<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blog by Jonathan Dai]]></title><description><![CDATA[Blog by Jonathan Dai]]></description><link>http://github.com/dylang/node-rss</link><generator>GatsbyJS</generator><lastBuildDate>Thu, 29 Sep 2022 08:43:16 GMT</lastBuildDate><item><title><![CDATA[轻量级健身综合入门指引]]></title><description><![CDATA[普通人轻量级健身指南：大肌霸是没戏的，强身健体可以有]]></description><link>https://xenojoshua.com/posts/2022/09/workout</link><guid isPermaLink="false">https://xenojoshua.com/posts/2022/09/workout</guid><pubDate>Mon, 26 Sep 2022 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E7%9B%AE%E6%A0%87&quot;&gt;2. 目标&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E7%9B%AE%E6%A0%87%E5%88%86%E7%B1%BB%E8%A1%A1%E9%87%8F&quot;&gt;2.1 目标分类/衡量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E7%9B%AE%E6%A0%87%E8%AE%BE%E5%AE%9A&quot;&gt;2.2 目标设定&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E7%9F%A5%E8%AF%86%E4%B8%8E%E5%8E%9F%E7%90%86&quot;&gt;3. 知识与原理&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-rm---repetition-maximum&quot;&gt;3.1 RM - repetition maximum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-rm%E4%B8%8E%E8%AE%AD%E7%BB%83%E6%95%88%E6%9E%9C&quot;&gt;3.2 RM与训练效果&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E5%8D%95%E9%83%A8%E4%BD%8D%E8%AE%AD%E7%BB%83%E7%9A%84%E5%A4%9A%E7%A7%8D%E5%8A%A8%E4%BD%9C&quot;&gt;3.3 单部位训练的多种动作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-%E9%87%8D%E5%A4%8D%E6%AC%A1%E6%95%B0%E4%B8%8E%E7%BB%84%E6%95%B0%E7%9A%84%E6%84%8F%E4%B9%89&quot;&gt;3.4 重复次数与组数的意义&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-doms---%E5%BB%B6%E8%BF%9F%E6%80%A7%E8%82%8C%E8%82%89%E9%85%B8%E7%97%9B&quot;&gt;3.5 DOMS - 延迟性肌肉酸痛&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#36-%E4%BC%91%E6%81%AF%E6%8B%89%E4%BC%B8&quot;&gt;3.6 休息拉伸&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#37-%E8%AE%AD%E7%BB%83%E5%91%A8%E6%9C%9F&quot;&gt;3.7 训练周期&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#38-%E7%A5%9E%E7%BB%8F%E7%9A%84%E5%8B%9F%E9%9B%86&quot;&gt;3.8 神经的募集&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#39-%E8%82%8C%E8%82%89%E7%94%9F%E9%95%BF%E7%9A%84%E7%90%86%E8%AE%BA&quot;&gt;3.9 肌肉生长的理论&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#310-%E8%AF%86%E5%88%AB%E8%82%8C%E8%82%89&quot;&gt;3.10 识别肌肉&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#311-%E4%B8%AD%E7%AB%8B%E4%BD%8D%E5%85%B3%E8%8A%82%E9%94%81%E6%AD%BB&quot;&gt;3.11 中立位、关节锁死&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#312-%E5%90%91%E5%BF%83%E6%94%B6%E7%BC%A9%E7%A6%BB%E5%BF%83%E6%94%B6%E7%BC%A9%E7%AD%89%E9%95%BF%E6%94%B6%E7%BC%A9&quot;&gt;3.12 向心收缩、离心收缩、等长收缩&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#313-%E5%8A%A8%E4%BD%9C%E8%A1%8C%E7%A8%8B&quot;&gt;3.13 动作行程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#314-%E5%8A%A8%E4%BD%9C%E7%A8%B3%E5%AE%9A%E6%80%A7&quot;&gt;3.14 动作稳定性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#315-%E5%A4%9A%E5%85%B3%E8%8A%82%E4%B8%8E%E5%8D%95%E5%85%B3%E8%8A%82&quot;&gt;3.15 多关节与单关节&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#316-%E6%B7%B1%E5%B1%82%E8%82%8C%E8%82%89%E4%B8%8E%E5%A7%BF%E5%8A%BF%E7%A8%B3%E5%AE%9A%E6%80%A7&quot;&gt;3.16 深层肌肉与姿势稳定性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#317-%E5%9D%9A%E6%8C%81&quot;&gt;3.17 坚持&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#318-%E6%9C%89%E6%B0%A7%E8%AE%AD%E7%BB%83%E7%9A%84%E9%80%89%E6%8B%A9&quot;&gt;3.18 有氧训练的选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#319-%E5%B8%B8%E8%A7%81%E8%AF%AF%E5%8C%BA&quot;&gt;3.19 常见误区&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E5%A6%82%E4%BD%95%E5%BC%80%E5%A7%8B&quot;&gt;5. 如何开始&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot;&gt;准备工作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%A1%AE%E8%AE%A4%E5%90%88%E9%80%82%E8%87%AA%E5%B7%B1%E7%9A%84%E8%AE%AD%E7%BB%83%E9%87%8D%E9%87%8F&quot;&gt;确认合适自己的训练重量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%88%B6%E5%AE%9A%E8%AE%AD%E7%BB%83%E8%AE%A1%E5%88%92&quot;&gt;制定训练计划&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A6%82%E4%BD%95%E8%BF%9B%E6%AD%A5&quot;&gt;如何进步&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-%E5%A6%82%E4%BD%95%E5%B1%85%E5%AE%B6%E8%AE%AD%E7%BB%83&quot;&gt;6. 如何居家训练&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-%E6%98%8E%E7%A1%AE%E7%9B%AE%E6%A0%87&quot;&gt;6.1 明确目标&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-%E8%AE%BE%E5%A4%87%E9%9C%80%E6%B1%82&quot;&gt;6.2 设备需求&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#63-%E5%AE%9E%E9%99%85%E5%AE%89%E8%A3%85%E7%BB%84%E5%90%88%E6%95%88%E6%9E%9C%E5%8F%8A%E5%8A%A8%E4%BD%9C%E9%80%89%E6%8B%A9&quot;&gt;6.3 实际安装组合效果及动作选择&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#631-%E8%83%B8%E9%83%A8%E8%82%8C%E7%BE%A4&quot;&gt;6.3.1 胸部肌群&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#632-%E8%83%8C%E9%83%A8%E8%82%8C%E7%BE%A4&quot;&gt;6.3.2 背部肌群&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#633-%E8%82%B1%E4%BA%8C%E5%A4%B4%E8%82%8C&quot;&gt;6.3.3 肱二头肌&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#634-%E8%82%B1%E4%B8%89%E5%A4%B4%E8%82%8C&quot;&gt;6.3.4 肱三头肌&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#635-%E8%82%A9%E9%83%A8&quot;&gt;6.3.5 肩部&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#636-%E8%85%B9%E9%83%A8--%E4%B8%8B%E8%83%8C&quot;&gt;6.3.6 腹部 + 下背&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#637-%E8%87%80%E8%85%BF&quot;&gt;6.3.7 臀腿&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;开始健身也有点年头了，从一开始的纯有氧，到后来基本上纯力量，知识经验积累都不少，这里做点总结，也分享给一众友人。&lt;/p&gt;
&lt;h1 id=&quot;2-目标&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E7%9B%AE%E6%A0%87&quot; aria-label=&quot;2 目标 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 目标&lt;/h1&gt;
&lt;p&gt;健身之前，首先需要明确自己健身的目标是什么。所谓&lt;code class=&quot;language-text&quot;&gt;give and take&lt;/code&gt;，健身无论从物质还是精神上，都是一项相当高付出的活动，所以还是有必要给自己设定目标并有针对性地进行训练。每个人的需求各不相同，达成目标的手法也不同，所以了解训练和目标的类型是有必要的。&lt;/p&gt;
&lt;h2 id=&quot;21-目标分类衡量&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E7%9B%AE%E6%A0%87%E5%88%86%E7%B1%BB%E8%A1%A1%E9%87%8F&quot; aria-label=&quot;21 目标分类衡量 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 目标分类/衡量&lt;/h2&gt;
&lt;p&gt;一般常见的健身目标有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增肌&lt;/li&gt;
&lt;li&gt;减脂&lt;/li&gt;
&lt;li&gt;心肺强化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;几点概念：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增肌
&lt;ul&gt;
&lt;li&gt;增肌不仅仅只是为了增肌，骨骼肌是人体热量消耗最大的部位之一，增肌能显著增加热量消耗也就是减脂&lt;/li&gt;
&lt;li&gt;要做&lt;code class=&quot;language-text&quot;&gt;可持续的减脂&lt;/code&gt;都必需先增肌（总是有人喜欢靠少吃减少摄入，或做大训练量的有氧运动来减脂，但这种做法很难保持，经常会反弹）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;减脂
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;极限减脂&lt;/code&gt;和增肌是相冲突的，极限减脂的时候会严格控制摄入量以造成热量缺口，对肌肉的生长是有影响的&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;心肺功能
&lt;ul&gt;
&lt;li&gt;极限增肌和有氧训练是冲突的，过多的有氧训练会导致人体的代谢水平激增能量物质消耗增大，自噬等消耗蛋白质的反应会激增，且肌肉容易过度疲劳而无法更好成长，所以一般增肌为主的话，有氧的量会减少&lt;/li&gt;
&lt;li&gt;一般单次训练的时长需要控制在1小时以内，这样生长激素以及神经刺激等都是最好的&lt;/li&gt;
&lt;li&gt;比较专业的训练一般很轻松就能达到40分钟以上，如果再加上有氧就太长了&lt;/li&gt;
&lt;li&gt;当增肌走到一个更高的极限的时候，有氧或者说心肺功能会是一个阻力点，所以即便是增肌，平时有氧训练也是不能少的，一般一周1-2次，或者一周多次但和阻抗训练分开&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;平衡
&lt;ul&gt;
&lt;li&gt;从上面的几点可以看出，各个目标之间有的时候是相互冲突的，关键在于掌握好平衡&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;自噬在各種細胞功能中都發揮作用。營養不足會導致高水平的自噬，降解不需要的蛋白質，並且回收氨基酸，以合成對細胞生存至關重要的蛋白質&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;对普通人来说，综合训练是最合适的，一定量的增肌训练，一定量的HIIT促进减脂，再加一点持续时间有点长的有氧。不要求非常显著的训练效果，以保持身体健康为第一目标。&lt;/p&gt;
&lt;p&gt;一般来说虽然不需要以极限增肌为目标，但无论如何日常的训练目标里应该加入一定量的阻抗训练以维持人体的肌肉量。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zhihu.com/question/398517719/answer/1955319169&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;为什么减脂容易掉肌肉? - 肉崽的回答 - 知乎&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/79038571&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;增肌期，到底要不要做有氧运动？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;目标的度量：增肌&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最大力量：比如说卧推或硬拉能上&lt;code class=&quot;language-text&quot;&gt;xxKG&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;肌肉维度：自己测量臂围、胸围、臀围等&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;目标的度量：减脂&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;体重/BMI：最粗的衡量指标，而且不太能作为依据来参考，如果在没有体脂率测量工具的情况下可以作为最基本的衡量标的&lt;/li&gt;
&lt;li&gt;体脂率：减脂的唯一真正目标，一般家用的体脂秤能看个大概/趋势，数值细节就不用多看了，一般不准&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;目标的度量：心肺功能&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;心率：同样强度（比如说跑步配速）的情况下，观察心率的变化就能很好衡量有氧能力的进步&lt;/li&gt;
&lt;li&gt;最大摄氧量：最科学的目标，但是一般没设备，所以了解下就好&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;22-目标设定&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E7%9B%AE%E6%A0%87%E8%AE%BE%E5%AE%9A&quot; aria-label=&quot;22 目标设定 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 目标设定&lt;/h2&gt;
&lt;p&gt;了解了目标的分类和衡量标准之后，接下来就是根据自己的情况和需求来选择对应的目标。先决定目标类型，然后再制作短期的目标。在制作目标的时候务必设定可以达到的目标。&lt;/p&gt;
&lt;p&gt;错误的例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增肌：「我要练出XXX那样的肌肉」；不可能&lt;/li&gt;
&lt;li&gt;减脂：「1个月里我要减掉xx%的脂肪」；做不到&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;正确的例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下个月我卧推的最大重量要增加4KG&lt;/li&gt;
&lt;li&gt;下个月我体重需要减掉1KG&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;设定做不到的目标将会非常严重挫伤积极性，一开始尽量要保证正向的激励（可完成），并保证坚持。只要能坚持，其他什么都好说。&lt;/p&gt;
&lt;p&gt;有一句话相当有道理：&lt;code class=&quot;language-text&quot;&gt;健身是一种生活状态，而不是一个目标&lt;/code&gt;。短期来说，健身设定目标是有必要的，但从长远来说，健身是一种必须长期持续的状态，目标感就很淡了，更多的是坚持下去的大目标。就像你买车开车，定期要做检查更换零件，你不会觉得买车第一年做个检查就够了后续就再也不需要了吧？一样的道理。&lt;/p&gt;
&lt;p&gt;本文剩下的篇幅会集中在阻抗训练上。刚才也说到了，减脂就是阻抗训练+少吃，有氧一般不需要很专业的指导。实际上，健身最重要就的在于阻抗训练/力量训练。&lt;/p&gt;
&lt;h1 id=&quot;3-知识与原理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E7%9F%A5%E8%AF%86%E4%B8%8E%E5%8E%9F%E7%90%86&quot; aria-label=&quot;3 知识与原理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 知识与原理&lt;/h1&gt;
&lt;p&gt;从这节开始我会讲相当多的健身知识和原理，会非常枯燥，但对于真正理解健身的人来说，这节才是真正的宝库。就像你去解一道数学问题的时候首先你需要学会公式，否则怎么解都不知道。一样的道理，阻抗训练里有相当多的知识点，不知道的话那就只能说是在胡乱训练罢了，非但不容易得到效果，还容易受伤。&lt;/p&gt;
&lt;h2 id=&quot;31-rm---repetition-maximum&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-rm---repetition-maximum&quot; aria-label=&quot;31 rm   repetition maximum permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 RM - repetition maximum&lt;/h2&gt;
&lt;p&gt;在我们开始任何之后的解说之前，我们先要解决2个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如何度量个人的力量（以便为后面的训练应该使用多少重量进行指引）
&lt;ul&gt;
&lt;li&gt;没有确定的方法来度量个人的力量就没办法了解应该使用什么重量进行训练，过重会受伤，过轻就没效果&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如何确定训练的重量
&lt;ul&gt;
&lt;li&gt;和第一点提到的是一个点，不过这里还要提一下就是关于沟通的统一标准&lt;/li&gt;
&lt;li&gt;多人之间的沟通（或者我们不说沟通，就说个人在单独学习健身知识的时候）应该以统一的标准进行，就比如说KG&lt;/li&gt;
&lt;li&gt;但即便重量一致，每个人在同样重量下的表现和训练效果是不一致的，这里RM就起作用了&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RM是：&lt;code class=&quot;language-text&quot;&gt;在某个重量&lt;/code&gt;下，一个人能将动作重复进行的&lt;code class=&quot;language-text&quot;&gt;最高次数&lt;/code&gt;。所以RM是一个相对的数值，是用来度量训练负荷的数值。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为什么说相对，因为每个人RM10的训练重量是完全不同的。大神的RM10（10次力竭）可能是100公斤，新手的RM10可能是10公斤。重点在于个人在&lt;code class=&quot;language-text&quot;&gt;某个重量&lt;/code&gt;下的最高可重复次数。&lt;/li&gt;
&lt;li&gt;为什么说这是用来度量训练负荷的数值，是因为虽然重量每个人不同，但结果都是一样的，都是&lt;code class=&quot;language-text&quot;&gt;重复X次&lt;/code&gt;之后&lt;code class=&quot;language-text&quot;&gt;力竭&lt;/code&gt;，再也做不了下一个了。也就是说训练效果是一致的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;32-rm与训练效果&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-rm%E4%B8%8E%E8%AE%AD%E7%BB%83%E6%95%88%E6%9E%9C&quot; aria-label=&quot;32 rm与训练效果 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 RM与训练效果&lt;/h2&gt;
&lt;p&gt;肌肉训练的三个维度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最大力量&lt;/li&gt;
&lt;li&gt;肌肉维度&lt;/li&gt;
&lt;li&gt;肌肉耐力&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;训练的时候不可三者兼得，所以需要取舍。RM不同的动作对于这三个维度的刺激是不同的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;RM值越低的训练越代表倾向于纯粹的力量（最大力量的提升），一般新手要训练力量的话，3-5的重量是比较合适的，尽量避免1左右的训练，风险太高容易受伤&lt;/li&gt;
&lt;li&gt;RM值8-12都是我们平时说的增肌比较合适的范围，比较均衡，更适合进行肌肥大训练（外观、肌肉维度）&lt;/li&gt;
&lt;li&gt;RM值高于15一般就没有训练意义了，更偏向于肌耐力，一般可以作为单次训练结束的收尾加量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;新手更推荐使用RM12的量来进行训练，但要保证姿势正确且真的是&lt;code class=&quot;language-text&quot;&gt;力竭&lt;/code&gt;了，也就是说12个之后，无论如何也做不了第13个了。&lt;/p&gt;
&lt;p&gt;高手一般会在单次训练中兼顾第一和第二种情况，也就是说即有低RM的力量训练，也有高RM（一般不高于10，除非是小肌群）的维度训练。&lt;/p&gt;
&lt;h2 id=&quot;33-单部位训练的多种动作&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E5%8D%95%E9%83%A8%E4%BD%8D%E8%AE%AD%E7%BB%83%E7%9A%84%E5%A4%9A%E7%A7%8D%E5%8A%A8%E4%BD%9C&quot; aria-label=&quot;33 单部位训练的多种动作 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 单部位训练的多种动作&lt;/h2&gt;
&lt;p&gt;新手肯定会有一个问题，那就是为什么我练一块肌肉（一个部位），需要换那么多动作。&lt;/p&gt;
&lt;p&gt;这是因为我们的肌肉是通过肌腱连接在骨骼上的，通过不同的姿势和不同的动作，肌肉的运动范围是不同的（也就是经常说的激活）。即便是针对同一块肌肉，不同的动作可以产生不同的运动范围，也就能得到不同的刺激。&lt;/p&gt;
&lt;p&gt;举个例子：&lt;/p&gt;
&lt;p&gt;手臂的三头肌有3个头，长头、外侧头以及内侧头，不同的动作因为起始的位置不同，肌腱和肌肉的伸展是不同的，那么其在运动的过程中，针对不同的头的刺激也是稍有不同的。我们在训练的时候就会多走几个动作，以期能顺利刺激到三头肌的不同部位。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-triceps-brachii-14.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-triceps-brachii-17.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;颈后位的三头肌动作，三头肌的长头在初始的位置就已经是充分拉伸了，所以刺激效果会非常好。&lt;/p&gt;
&lt;h2 id=&quot;34-重复次数与组数的意义&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-%E9%87%8D%E5%A4%8D%E6%AC%A1%E6%95%B0%E4%B8%8E%E7%BB%84%E6%95%B0%E7%9A%84%E6%84%8F%E4%B9%89&quot; aria-label=&quot;34 重复次数与组数的意义 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 重复次数与组数的意义&lt;/h2&gt;
&lt;p&gt;我们常说训练的时候要做某个动作N次（之前也说过了，RM10就是10次力竭）算一组，然后重复地做好几组才算是一个动作训练完成。那么为什么我们需要针对同一个动作做好几组呢？&lt;/p&gt;
&lt;p&gt;这是因为肌肉是一个&lt;code class=&quot;language-text&quot;&gt;束&lt;/code&gt;，其内部是由大量的肌肉细胞组成的，每次我们训练的时候，只训练一个组就结束的话，是无法把所有的肌肉细胞都尽可能地刺激到的。所以我们会针对一个相同的动作做好几组，尽量把该肌肉束中的肌肉细胞全部都刺激到。这样才能尽可能地促进该肌肉成长。&lt;/p&gt;
&lt;p&gt;至于是不是越多越好，那当然也不是，万事都要讲究一个度。之前也提到过，总的训练时长要尽量控制在1个小时之内，而且不同的动作也要尽量兼顾到，不能在一个动作上重复过多的组数。&lt;/p&gt;
&lt;h2 id=&quot;35-doms---延迟性肌肉酸痛&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#35-doms---%E5%BB%B6%E8%BF%9F%E6%80%A7%E8%82%8C%E8%82%89%E9%85%B8%E7%97%9B&quot; aria-label=&quot;35 doms   延迟性肌肉酸痛 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.5 DOMS - 延迟性肌肉酸痛&lt;/h2&gt;
&lt;p&gt;DOMS即&lt;code class=&quot;language-text&quot;&gt;Delayed onset muscle soreness&lt;/code&gt;，平时我们不是在健身的场合也会遇到过，比如说搬家搬重物的时候，如果用力过猛或者时间过长的话，第二天肌肉总是会超级痛，这就是DOMS。&lt;/p&gt;
&lt;p&gt;在健身的时候这种情况会像吃饭喝水一样&lt;code class=&quot;language-text&quot;&gt;正常&lt;/code&gt;，这也是衡量训练效果的一个非常重要的信号。一般来说，如果训练到位了，针对目标肌肉的刺激足够的话，第二天开始DOMS是必然会出现的。反过来说，如果没有DOMS，那说明你的训练还不够。或者说你的训练有问题，没有刺激到目标肌群。&lt;/p&gt;
&lt;p&gt;不过也不需要太过害怕DOMS，一般来说除了腿之外，其他部位的DOMS是不会影响正常生活的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/leg-day.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;（真的不是开玩笑）&lt;/p&gt;
&lt;p&gt;不过要注意DOMS会显著降低肌肉的能力，包括神经的募集能力，所以在DOMS中的肌肉应该避免再次训练。否则可能效果不会太好，也更容易受伤。&lt;/p&gt;
&lt;p&gt;这里简单聊下DOMS和一般拉伤的不同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DOMS不影响生活，只有动到这块肌肉的时候（发生特定动作的时候）才会感觉到痛；而拉伤则是无时无刻都在痛&lt;/li&gt;
&lt;li&gt;DOMS疼痛感不会特别剧烈，就算是动到会痛的部位也不会限制动作幅度；拉伤则会明显限制动作幅度&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;36-休息拉伸&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#36-%E4%BC%91%E6%81%AF%E6%8B%89%E4%BC%B8&quot; aria-label=&quot;36 休息拉伸 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.6 休息拉伸&lt;/h2&gt;
&lt;p&gt;一般训练之前和训练之后都需要进行拉伸。训练前拉伸一般和热身一起进行，保证训练过程中安全不受伤。训练后的拉伸有助于后续的肌肉恢复，并提升训练效果。总之不要偷懒好好拉伸就对了，特别是训练后的那部分。&lt;/p&gt;
&lt;h2 id=&quot;37-训练周期&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#37-%E8%AE%AD%E7%BB%83%E5%91%A8%E6%9C%9F&quot; aria-label=&quot;37 训练周期 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.7 训练周期&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;大肌群的训练需要72小时才能恢复，包括神经的募集能力，所以一般大肌群一周一练就足够了&lt;/li&gt;
&lt;li&gt;小肌群可以穿插在大肌群之间进行，这样能更好延长大肌群的神经疲劳恢复时间&lt;/li&gt;
&lt;li&gt;短时间内针对某一肌群反复训练反而会有反效果，训练的目的是为了刺激肌肉生长，过多的训练反而不利肌肉恢复和生长&lt;/li&gt;
&lt;li&gt;普通人一周的训练可以按：胸、背、二头、三头、肩部+腹部、臀腿，再加一次长时间的有氧，正好7天&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;38-神经的募集&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#38-%E7%A5%9E%E7%BB%8F%E7%9A%84%E5%8B%9F%E9%9B%86&quot; aria-label=&quot;38 神经的募集 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.8 神经的募集&lt;/h2&gt;
&lt;p&gt;人体动作的进行是由大脑发出信号，经过神经系统之后传达到肌肉才得以执行的。因此肌肉的训练离不开神经的帮助。而我们在进行肌肉训练的过程中，不单单只是肌肉细胞感受到了疲劳，神经系统也是会疲劳的。特征就是即便轻量级负重的动作，做的多了后面也是会觉得力不从心或者效果不佳，这就是神经开始疲劳了。&lt;/p&gt;
&lt;p&gt;所以我们一般说训练之后的休息和恢复也包含了神经的恢复，有的时候在负重不那么高的训练后，其实神经比肌肉更需要时间来恢复。&lt;/p&gt;
&lt;p&gt;我们经常听到教练会说&lt;code class=&quot;language-text&quot;&gt;念动一致&lt;/code&gt;，这其实也是基于这一理论的。当你在训练的时候一直专注在自己正在训练的肌肉上的时候，神经的募集能力就更能发挥到极致。&lt;/p&gt;
&lt;p&gt;一般大肌群的恢复需要72个小时，小肌群则需要24-48小时。&lt;/p&gt;
&lt;h2 id=&quot;39-肌肉生长的理论&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#39-%E8%82%8C%E8%82%89%E7%94%9F%E9%95%BF%E7%9A%84%E7%90%86%E8%AE%BA&quot; aria-label=&quot;39 肌肉生长的理论 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.9 肌肉生长的理论&lt;/h2&gt;
&lt;p&gt;训练肌肉的目的是为了刺激肌肉生长，训练本身根本就不是我们的目的。所以如何让肌肉更好地生长是必须要认真思考的，否则就是管挖不管埋，开坑不埋坑。&lt;/p&gt;
&lt;p&gt;先说结论，对于普通人来说要促进肌肉生长要做好一下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;早睡早起&lt;/li&gt;
&lt;li&gt;健康饮食，30-40%碳水 + 50%蛋白质 + 10-20%脂肪&lt;/li&gt;
&lt;li&gt;禁吸烟饮酒&lt;/li&gt;
&lt;li&gt;每周规律的至少3-4次每次1小时左右的阻抗训练&lt;/li&gt;
&lt;li&gt;每周2-3次每次至少30分钟的有氧训练（可以用时间更短的HIIT代替）&lt;/li&gt;
&lt;li&gt;每次阻抗训练后及时（1小时内）补充碳水化合物提升胰岛素水平（棒棒糖之类的低量但高GI的最合适），然后及时补充蛋白质（蛋白粉补剂）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接下来简单说下原理，简单的那种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;肌肉合成需要各种激素，比如：睾酮、生长激素、胰岛素等&lt;/li&gt;
&lt;li&gt;肌肉合成需要营养物质，比如：蛋白质、支链氨基酸、谷氨酸等&lt;/li&gt;
&lt;li&gt;健康规律的生活习惯能很好促进激素的分泌，特别是长时间规律的分泌&lt;/li&gt;
&lt;li&gt;酒精对睾酮分泌和肌肉合成都有极大的伤害，能避则避&lt;/li&gt;
&lt;li&gt;胰岛素不仅仅只是用来对抗血糖的，它还是一种合成代谢用的激素，所以肌肉生长也离不开它&lt;/li&gt;
&lt;li&gt;阻抗训练之后体内的胰岛素水平会降低，正好适合用高GI的碳水唤醒，然后就补充蛋白质，让肌肉充分生长&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GI是什么？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;升糖指數（glycemic index，簡稱GI），又譯糖生成指數，用於衡量糖類對血糖值的影響，是一種食物升高血糖能力的度量。GI值高的食物其所含醣類會被迅速分解然後吸收，將葡萄糖迅速釋放到循環系統，導致血糖急劇上升再下降。反之，低GI值的食物其所含醣類會被緩慢分解或較慢吸收，使葡萄糖逐漸釋放到循環系統，讓血糖水平的上升和下降更加緩慢與平衡。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;几个链接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/54400514&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;酒精对肌肉增长的影响&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/65633609&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;胰岛素与增肌 ～绝对干货&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zhihu.com/question/44055485/answer/1992536661&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;“肌肉在休息的时候超量生长”，其中关于“休息”的定义是睡觉吗？ - 肉崽的回答 - 知乎&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;310-识别肌肉&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#310-%E8%AF%86%E5%88%AB%E8%82%8C%E8%82%89&quot; aria-label=&quot;310 识别肌肉 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.10 识别肌肉&lt;/h2&gt;
&lt;p&gt;健身在初步入门对几个基本动作和集群有过简单训练之后，还是建议简单找点解剖学的资料来看下，了解下基本的几组常练集群的位置、大小、附着点、运动范围。这对深入学习各种健身动作，摸清训练的正确运动轨迹，以及抓肌肉的感觉很有好处。&lt;/p&gt;
&lt;p&gt;有条件的话可以找一些解剖学的3D软件来看下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-3d-atlas.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;文章最后我会有一段来简单过下所有的常练肌群。&lt;/p&gt;
&lt;h2 id=&quot;311-中立位关节锁死&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#311-%E4%B8%AD%E7%AB%8B%E4%BD%8D%E5%85%B3%E8%8A%82%E9%94%81%E6%AD%BB&quot; aria-label=&quot;311 中立位关节锁死 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.11 中立位、关节锁死&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;中立位&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;指我们在训练的时候，脊柱要保证不过分前倾也不过分后倾，尽量保持在正确的中轴上，比如下图这种状态：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-overextension.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;一旦躯干过分超前或者朝后倾斜的话，我们就说脊柱过伸或者过收了。一旦躯干保持这种状态做负重训练的话，极容易造成腰椎或颈椎受伤。特别是在做下半身的训练的时候，比如说深蹲硬拉的时候。&lt;/p&gt;
&lt;p&gt;在训练的时候一定要有意识地保证脊柱自然中立，说人话就是这时候关节还有可运动范围，可前可后，还没完全锁死。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关节锁死&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;关节锁死的意思就关节在一个反方向上伸展到极致，再也不能伸展了，反关节的伸展到极致的状态，就是关节锁死状态。这种情况就是在手臂支撑的肘关节和脚部支撑的膝关节最容易出现的状况。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/locked.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;这种时候关节的单向运动性达到了极限，一旦动作不稳导致再过度受力的话，很容易受伤。一般训练的时候要有意识地不要把关节打到最大，使用肌肉的力量让关节保持仍旧有一定程度的开合性。&lt;/p&gt;
&lt;p&gt;和上面说的中立位是异曲同工的。&lt;/p&gt;
&lt;h2 id=&quot;312-向心收缩离心收缩等长收缩&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#312-%E5%90%91%E5%BF%83%E6%94%B6%E7%BC%A9%E7%A6%BB%E5%BF%83%E6%94%B6%E7%BC%A9%E7%AD%89%E9%95%BF%E6%94%B6%E7%BC%A9&quot; aria-label=&quot;312 向心收缩离心收缩等长收缩 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.12 向心收缩、离心收缩、等长收缩&lt;/h2&gt;
&lt;p&gt;看一张图&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/contraction.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一个动作是&lt;code class=&quot;language-text&quot;&gt;等长收缩&lt;/code&gt;，肌肉的体积并没有变化，长度保持不变，但这时候肌肉是在发力的，保持其位置&lt;/li&gt;
&lt;li&gt;第二个动作是&lt;code class=&quot;language-text&quot;&gt;向心收缩&lt;/code&gt;，肌肉长度缩小，收缩发力，也是我们在日常中最常见的&lt;code class=&quot;language-text&quot;&gt;举起、抬起&lt;/code&gt;的场景&lt;/li&gt;
&lt;li&gt;第三个动作是&lt;code class=&quot;language-text&quot;&gt;离心收缩&lt;/code&gt;，肌肉长度变长，也是我们在日常中把东西&lt;code class=&quot;language-text&quot;&gt;放下&lt;/code&gt;的场景&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在健身的时候，等长收缩一般是辅助肌群的工作，他们保证躯干及动作的稳定，保证躯干没有位移。向心收缩一般大家也最熟悉，就不多说了。&lt;/p&gt;
&lt;p&gt;主要说下离心收缩。这个名词一般人都不熟，训练的时候也常常被忽视。但对于肌肉的训练来说，其实离心收缩也是非常重要的一部分。&lt;/p&gt;
&lt;p&gt;正确的训练步骤是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;肌肉发力收缩，向心收缩，把配重举起、抬起、压下&lt;/li&gt;
&lt;li&gt;到达肌肉运动轨迹的顶点，保持顶峰收缩1s&lt;/li&gt;
&lt;li&gt;肌肉发力缓慢放下配重，做离心收缩，到配重被完全放下为止&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;离心收缩要保证&lt;code class=&quot;language-text&quot;&gt;不要太快&lt;/code&gt;。很多人在训练的时候上去肯定是发力了的，但是放下的时候就一口气松掉了，直接像扔掉一样放掉。这样就等于训练直接少了一半的训练量，后半程完全没练到。&lt;/p&gt;
&lt;p&gt;选择训练重量的时候也尽量要保证自己能够&lt;code class=&quot;language-text&quot;&gt;控制&lt;/code&gt;，起来的时候要稳定，放下的时候同样要稳定，不要摔杠，不要扔哑铃。如果你觉得你不能很好完成全程，那正确的选择是减少配重的重量。&lt;/p&gt;
&lt;h2 id=&quot;313-动作行程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#313-%E5%8A%A8%E4%BD%9C%E8%A1%8C%E7%A8%8B&quot; aria-label=&quot;313 动作行程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.13 动作行程&lt;/h2&gt;
&lt;p&gt;一个肌肉的可能行程是由其生理结构决定的，肌肉长度如何，附着点在哪几块骨骼上。但有的时候因为个人选择原因，我们很可能不会完整做完一个动作的全部行程。&lt;/p&gt;
&lt;p&gt;比如说某些动作在低位的时候对关节的负担很重，那我们可能就不会跳过较低的那段行程，在下去一点之后就直接起来。再举个例子就是在极限增加最大力量的时候，我们可能会选择使用RM为3或者5之类的配重，这种情况下，动作做全程的话可能在低点就直接起不来了，所以一般也会走半程。&lt;/p&gt;
&lt;p&gt;一般来说，行程越是完整对肌肉的刺激效果就越好。所以不是特殊情况的话，尽量选择行程完整的动作进行训练是没错的。&lt;/p&gt;
&lt;h2 id=&quot;314-动作稳定性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#314-%E5%8A%A8%E4%BD%9C%E7%A8%B3%E5%AE%9A%E6%80%A7&quot; aria-label=&quot;314 动作稳定性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.14 动作稳定性&lt;/h2&gt;
&lt;p&gt;有很多人在健身的时候会选择比较重的配重，什么姿势什么动作都要往顶格的重量上，而最后最有可能的结果就是动作变形不标准，经常化地进行借力（完成一个动作并非由本来应该训练到的肌肉部位发力，而是借用了其他部位的力量）。这样的训练是有百害而无一利的，特别是非常容易受伤。&lt;/p&gt;
&lt;p&gt;健身训练的首要一点就是动作的稳定性。训练的时候动作必须稳定发力，上的时候可以做到慢而稳，顶峰要做到1s的收缩，放下的时候同样也需要稳，不要摔杠摔哑铃。如果能做到&lt;code class=&quot;language-text&quot;&gt;控制&lt;/code&gt;，那训练就没问题。当然事物总有例外，有的时候我们在训练最大力量的时候会用低RM的配重，会有一些动作变形，这也无可厚非，但切记这是特例，组数和次数都不会很多。总的来说，还是必须要做好&lt;code class=&quot;language-text&quot;&gt;控制&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&quot;315-多关节与单关节&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#315-%E5%A4%9A%E5%85%B3%E8%8A%82%E4%B8%8E%E5%8D%95%E5%85%B3%E8%8A%82&quot; aria-label=&quot;315 多关节与单关节 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.15 多关节与单关节&lt;/h2&gt;
&lt;p&gt;健身训练一般有两种类型的动作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多关节动作：一次训练会动到多个关节，e.g 杠铃胸推，用到了肩关节和肘关节&lt;/li&gt;
&lt;li&gt;单关节动作：一次训练只会动到一个关节，e.g 二头肌弯举，只用到肘关节&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里的优劣利弊是：在可能的情况下尽量选择多关节动作，一般来说多关节动作有更高的上限，训练效果会相对较好，而且因为多关节动作牵涉的关节较多，训练到的肌群也较多，有更好的效率。而单关节动作则是训练后半部的补充，可以更好地对一些小肌群进行雕琢。&lt;/p&gt;
&lt;h2 id=&quot;316-深层肌肉与姿势稳定性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#316-%E6%B7%B1%E5%B1%82%E8%82%8C%E8%82%89%E4%B8%8E%E5%A7%BF%E5%8A%BF%E7%A8%B3%E5%AE%9A%E6%80%A7&quot; aria-label=&quot;316 深层肌肉与姿势稳定性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.16 深层肌肉与姿势稳定性&lt;/h2&gt;
&lt;p&gt;一般我们在健身的过程中提到的肌肉都是表层肌肉，其实人身体上的肌肉远远不止只有一层，而是好几层的肌肉堆叠起来的。&lt;/p&gt;
&lt;p&gt;下图就是背部的斜方肌，以及其下的菱形肌：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-deep-muscle-1.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-deep-muscle-2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;深层肌一般是用来控制人的身体姿势的，比如说你站在半圆球上是否能站得稳，是否能在站稳之后还能做深蹲。&lt;/p&gt;
&lt;p&gt;一般我们健身是不会专门去训练深层肌的，但是深层肌对人的身体健康也是很有帮助的。所以有的时候我们可以专门做一些低负重稳定性比较差的动作，来训练。一般会用到半圆球或者瑜伽球这种提供不稳定性的道具。&lt;/p&gt;
&lt;h2 id=&quot;317-坚持&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#317-%E5%9D%9A%E6%8C%81&quot; aria-label=&quot;317 坚持 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.17 坚持&lt;/h2&gt;
&lt;p&gt;开篇的时候就已经提过了，健身应该是一种&lt;code class=&quot;language-text&quot;&gt;生活状态&lt;/code&gt;，而不是一种突然想要参加的&lt;code class=&quot;language-text&quot;&gt;活动&lt;/code&gt;。也就是说，只要你还活着一天，你就应该保持运动和健身以期能维持身体的健康。既然战线那么长，减少阻力就是第一位重要的事情。&lt;/p&gt;
&lt;p&gt;如果你真的有心要健身，就应该抛弃定势思维：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;健身一定要去健身房&lt;/li&gt;
&lt;li&gt;健身一定要请教练&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我的建议是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;居家健身，保证自己没有任何藉口&lt;/li&gt;
&lt;li&gt;自己看点健身的文章和视频，随手练几次，很快就能上手了&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于如何居家健身，后面我会有专门的篇幅来介绍。基本没多少器具就可以解决问题了。&lt;/p&gt;
&lt;h2 id=&quot;318-有氧训练的选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#318-%E6%9C%89%E6%B0%A7%E8%AE%AD%E7%BB%83%E7%9A%84%E9%80%89%E6%8B%A9&quot; aria-label=&quot;318 有氧训练的选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.18 有氧训练的选择&lt;/h2&gt;
&lt;p&gt;一般有氧在身体能负荷的情况下，应该尽量选择&lt;a href=&quot;https://en.wikipedia.org/wiki/High-intensity_interval_training&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HIIT&lt;/a&gt;作为有氧的训练方式。&lt;/p&gt;
&lt;p&gt;HIIT带有一点力量训练的特点，对肌耐力也有一定的训练效果，比纯有氧更好。而且HIIT耗时短，作为日常训练的选择优势更明显。&lt;/p&gt;
&lt;p&gt;手机上很多APP都有专门的HIIT课程，随便选一些就行了，很容易找：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/HIIT1.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/HIIT2.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/HIIT3.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/HIIT4.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/HIIT5.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;不过HIIT有一点不太好。。。蹦蹦跳跳为主（否则哪来的心率），所以老破小没法搞，楼下要上来敲门的。&lt;/p&gt;
&lt;h2 id=&quot;319-常见误区&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#319-%E5%B8%B8%E8%A7%81%E8%AF%AF%E5%8C%BA&quot; aria-label=&quot;319 常见误区 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.19 常见误区&lt;/h2&gt;
&lt;p&gt;最后列几个常见误区：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;女生：我不想练出肌肉
&lt;ul&gt;
&lt;li&gt;相信我，练出肌肉真不是这么简单的事情&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;重量与受伤
&lt;ul&gt;
&lt;li&gt;之前也提了，不要迷信大重量，首先你得有能力&lt;code class=&quot;language-text&quot;&gt;控制&lt;/code&gt;大重量&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;我不想做有氧，怕关节损伤
&lt;ul&gt;
&lt;li&gt;只要不是职业运动员级别的训练量，普通的健身训练对关节只有好处&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;部分减脂
&lt;ul&gt;
&lt;li&gt;不存在的，减脂永远是全身性的，不存在练什么部位哪里就减脂这个说法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;5-如何开始&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E5%A6%82%E4%BD%95%E5%BC%80%E5%A7%8B&quot; aria-label=&quot;5 如何开始 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 如何开始&lt;/h1&gt;
&lt;h2 id=&quot;准备工作&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot; aria-label=&quot;准备工作 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;准备工作&lt;/h2&gt;
&lt;p&gt;居家训练的准备工作我会放单独的章节。&lt;/p&gt;
&lt;p&gt;一般训练的话，或者上健身房的话，只需要4个东西：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;宽松的运动服装&lt;/li&gt;
&lt;li&gt;一个用来摇蛋白粉的摇摇杯，记得不要买那种铁丝球是单独分离的品种，不容易弄干净，最好买一体式震荡网的那种&lt;/li&gt;
&lt;li&gt;去海淘几桶蛋白粉，中国人的正常饮食蛋白质是肯定不够的&lt;/li&gt;
&lt;li&gt;买1组轻量级的哑铃，在家也能补充训练一些小肌群&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就这点足够了，不需要多。如果是希望能在家把训练做完做好的话，可以看我后面的专门章节。&lt;/p&gt;
&lt;h2 id=&quot;确认合适自己的训练重量&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%A1%AE%E8%AE%A4%E5%90%88%E9%80%82%E8%87%AA%E5%B7%B1%E7%9A%84%E8%AE%AD%E7%BB%83%E9%87%8D%E9%87%8F&quot; aria-label=&quot;确认合适自己的训练重量 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;确认合适自己的训练重量&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;确定自己要训练的部位&lt;/li&gt;
&lt;li&gt;找目标部位的经典动作&lt;/li&gt;
&lt;li&gt;找比较轻量级的负重，尝试练几次，看下这个负重是否能达到RM10&lt;/li&gt;
&lt;li&gt;一般新手的话，一个动作能到RM10就差不多了，暂时不需要考虑低RM的力量训练&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;制定训练计划&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%88%B6%E5%AE%9A%E8%AE%AD%E7%BB%83%E8%AE%A1%E5%88%92&quot; aria-label=&quot;制定训练计划 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;制定训练计划&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;每次训练都记得热身&lt;/li&gt;
&lt;li&gt;每次练完记得拉伸&lt;/li&gt;
&lt;li&gt;每周胸、背、二头、三头、臀腿、肩部+腰部各练一次，就6天了，然后有氧再来一天，差不多了&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;如何进步&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%A6%82%E4%BD%95%E8%BF%9B%E6%AD%A5&quot; aria-label=&quot;如何进步 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;如何进步&lt;/h2&gt;
&lt;p&gt;当有过一阵训练经验之后，想要进一步进步的话，可以：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加最大重量
&lt;ul&gt;
&lt;li&gt;在原来的重量上循序渐进增加重量&lt;/li&gt;
&lt;li&gt;当新的重量也适应之后，继续增重，循环往复&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;增加代谢压力
&lt;ul&gt;
&lt;li&gt;我们按公式计算：重量10KG * 每组次数10 / 组件间隔1分钟，得到现在的训练压力是100&lt;/li&gt;
&lt;li&gt;我们可以通过：增重 / 增加次数（但是尽量不要超过10，如果超过就要考虑增重） / 减少组件间隔，其中的任意组合来增加肌肉的代谢压力&lt;/li&gt;
&lt;li&gt;20KG * 10 / 1 = 200&lt;/li&gt;
&lt;li&gt;10KG * 12 / 1 = 120&lt;/li&gt;
&lt;li&gt;10KG * 10 / 0.5 = 200&lt;/li&gt;
&lt;li&gt;（这里的公式/数值没有意义，我只是举个例子来说明而已）&lt;/li&gt;
&lt;li&gt;调整次数和间隔之后，即便训练重量没变对于训练压力来说也是有提升的，一样能增加训练效果&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一般来说，在增加代谢压力保持一阵之后，总能自然而然地增加训练重量。至少我就是这么干的。&lt;/p&gt;
&lt;h1 id=&quot;6-如何居家训练&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-%E5%A6%82%E4%BD%95%E5%B1%85%E5%AE%B6%E8%AE%AD%E7%BB%83&quot; aria-label=&quot;6 如何居家训练 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. 如何居家训练&lt;/h1&gt;
&lt;p&gt;还是建议任何有健身需求的小伙伴尽量一开始尝试自己在家健身，就算只是哑铃也可以，先体验下。以轻量级的训练量尽量做到坚持1个月以上。如果能做到，那再考虑下一步是健身房还是买设备。如果做不到的话，那也不用谈什么健身房买卡了，都是浪费钱。&lt;/p&gt;
&lt;h2 id=&quot;61-明确目标&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-%E6%98%8E%E7%A1%AE%E7%9B%AE%E6%A0%87&quot; aria-label=&quot;61 明确目标 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 明确目标&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;要能练到几个主要肌群：胸、背、二头、三头、肩、腹、臀腿&lt;/li&gt;
&lt;li&gt;这里的练到指的不是轻量级的有练就行，而是必须有一定的负荷&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;62-设备需求&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-%E8%AE%BE%E5%A4%87%E9%9C%80%E6%B1%82&quot; aria-label=&quot;62 设备需求 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 设备需求&lt;/h2&gt;
&lt;p&gt;这里我会列出我现在在用的设备，以及动作和训练到的部位。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;可调哑铃&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重量自行判断自己的需求，我这里的是一组75KG的&lt;/li&gt;
&lt;li&gt;每档可调范围尽量细，最好是一档2KG，我这里的是老式的一档4KG&lt;/li&gt;
&lt;li&gt;必须是可调的，这样你在调整重量的时候可以做到10秒里解决，不要选用那种必须手动抽添哑铃片的，否则调整重量太麻烦&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/equipment2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;卧推凳&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;要求凳子的背部可以上下活动，主要用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哑铃卧推 - 胸大肌&lt;/li&gt;
&lt;li&gt;哑铃飞鸟 - 胸大肌&lt;/li&gt;
&lt;li&gt;站姿哑铃斜托臂弯举（40度打开椅背用来支撑肘部） - 二头&lt;/li&gt;
&lt;li&gt;仰卧哑铃臂屈伸 - 三头&lt;/li&gt;
&lt;li&gt;坐姿哑铃推举（90度打直座椅用来稳定支撑背部） - 三角肌&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/equipment1.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;单杠&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;可以买那种两边有缓冲垫的单杠，安装在过道上，不需要钉子，很方便。&lt;/p&gt;
&lt;p&gt;主要用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;引体向上 - 背部&lt;/li&gt;
&lt;li&gt;用来挂滑轮和钢索，可以用来完成所有向下拉的动作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/equipment3.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;弹力带&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这里要注意，要买那种厚度很厚的弹力带，因为是买来用来支撑体重的，所以不是那种薄的用来拉伸的弹力带。&lt;/p&gt;
&lt;p&gt;主要用途：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;减重组引体向上 - 背部&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/equipment11.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一组滑轮钢索以及一些拉杆工具&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1个滑轮 + 1根钢索，挂在单杠上&lt;/li&gt;
&lt;li&gt;2个环扣，1个用来挂滑轮，另一个用来挂拉杆或配重&lt;/li&gt;
&lt;li&gt;2根承重编织带，1个用来挂滑轮，另一个用来挂配重&lt;/li&gt;
&lt;li&gt;1根双头绳，用来练三头肌&lt;/li&gt;
&lt;li&gt;1个马鞍把手，用来练单手下拉或划船&lt;/li&gt;
&lt;li&gt;1个V型拉力杆，用来练下压&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/equipment4.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment7.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment5.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment6.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment8.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment9.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment10.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;63-实际安装组合效果及动作选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#63-%E5%AE%9E%E9%99%85%E5%AE%89%E8%A3%85%E7%BB%84%E5%90%88%E6%95%88%E6%9E%9C%E5%8F%8A%E5%8A%A8%E4%BD%9C%E9%80%89%E6%8B%A9&quot; aria-label=&quot;63 实际安装组合效果及动作选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3 实际安装组合效果及动作选择&lt;/h2&gt;
&lt;p&gt;这里我就综合放了，主要思路是按肌肉部位编排，每个肌肉部位：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;几张解剖图&lt;/li&gt;
&lt;li&gt;几张实际安装的居家设备图&lt;/li&gt;
&lt;li&gt;几张动作图&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;631-胸部肌群&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#631-%E8%83%B8%E9%83%A8%E8%82%8C%E7%BE%A4&quot; aria-label=&quot;631 胸部肌群 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3.1 胸部肌群&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;解剖图&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;胸大肌&lt;/li&gt;
&lt;li&gt;三角肌前束：练胸基本上都会练到三角肌前束&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-chest.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设备&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;椅背上下调节就可以练到上斜和下斜动作。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/equipment-installed1.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-chest-7.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-chest-8.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-chest-9.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;632-背部肌群&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#632-%E8%83%8C%E9%83%A8%E8%82%8C%E7%BE%A4&quot; aria-label=&quot;632 背部肌群 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3.2 背部肌群&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;解剖图&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这里会分几张来介绍&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;肩袖4块肌肉
&lt;ul&gt;
&lt;li&gt;冈上肌&lt;/li&gt;
&lt;li&gt;冈下肌&lt;/li&gt;
&lt;li&gt;小圆肌&lt;/li&gt;
&lt;li&gt;大圆肌&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;三角肌后束&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-back-shoulder.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;背部肌肉
&lt;ul&gt;
&lt;li&gt;斜方肌&lt;/li&gt;
&lt;li&gt;斜方肌下面的菱形肌&lt;/li&gt;
&lt;li&gt;背阔肌：男人的翅膀&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-back.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设备&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;单杠 + 滑轨 + 钢索 + 弹力带&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/equipment-installed4.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;后面有两张设备图我放在动作里一起介绍&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;V型拉力杆&lt;/li&gt;
&lt;li&gt;马鞍把手&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正握引体向上&lt;/li&gt;
&lt;li&gt;反握引体向上&lt;/li&gt;
&lt;li&gt;减重组参考上面的图的弹力带&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-back-1.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-back-2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直臂下拉/压&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-back-3.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment-installed2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;单手高位下拉&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个我在那本经典的健身书里没找到，就随便找了个gif，可以参考下。这个动作可以带一点轻微的脊柱侧弯，以达到背阔肌的最大行程和收缩。新手切记从低负荷开始尝试，保证安全并抓懂肌肉的本源感觉。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-back-4.gif&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment-installed5.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;633-肱二头肌&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#633-%E8%82%B1%E4%BA%8C%E5%A4%B4%E8%82%8C&quot; aria-label=&quot;633 肱二头肌 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3.3 肱二头肌&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;解剖图&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;肱二头肌和肱肌基本上是重叠的，所以训练基本上没差，都是一起练的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-biceps-brachii.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设备&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;就是哑铃和卧推凳，其中卧推凳的用法我会在下面的动作里一并带上&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-biceps-brachii-2.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-biceps-brachii-3.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-biceps-brachii-8.jpg&quot; alt=&quot;&quot;&gt;
椅背打到40-45度，单臂手肘放上面，就可以做哑铃+卧推凳的居家版本了
&lt;img src=&quot;/media/posts/2022/09/workout/equipment-installed6.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;634-肱三头肌&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#634-%E8%82%B1%E4%B8%89%E5%A4%B4%E8%82%8C&quot; aria-label=&quot;634 肱三头肌 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3.4 肱三头肌&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;解剖图&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-triceps-brachii1.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-triceps-brachii2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设备&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一样放动作一起&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-triceps-brachii-12.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/equipment-installed3.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-triceps-brachii-16.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-triceps-brachii-18.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-triceps-brachii-20.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;635-肩部&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#635-%E8%82%A9%E9%83%A8&quot; aria-label=&quot;635 肩部 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3.5 肩部&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;解剖图&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;解剖图里没分前中后三束，我就拍了张照，分离不太好，见笑了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-shoulder1.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/anatomy-shoulder2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;设备&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一样放动作一起&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;动作&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-shoulder-3.jpg&quot; alt=&quot;&quot;&gt;
卧推凳椅背打直，就可以用来做肩推的时候支撑背部，保证稳定性
&lt;img src=&quot;/media/posts/2022/09/workout/equipment-installed7.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-shoulder-5.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-shoulder-6.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;636-腹部--下背&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#636-%E8%85%B9%E9%83%A8--%E4%B8%8B%E8%83%8C&quot; aria-label=&quot;636 腹部  下背 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3.6 腹部 + 下背&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;腹部一般就仰卧起坐或者悬垂抬腿就行了，不用搞太复杂，记得组间短点就行了&lt;/li&gt;
&lt;li&gt;下背健身房可以做山羊挺身，居家就只能做做小飞燕了&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;637-臀腿&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#637-%E8%87%80%E8%85%BF&quot; aria-label=&quot;637 臀腿 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3.7 臀腿&lt;/h3&gt;
&lt;p&gt;居家没什么很好的办法做臀腿训练，有条件还是建议上健身房。&lt;/p&gt;
&lt;p&gt;居家基本上就只能酒杯深蹲和单腿蹲了，给两个图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/workout/workout-leg-1.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/workout/workout-leg-2.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;大致上就这点了&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[神奇的Node.js map中+=async问题]]></title><description><![CDATA[非常奇妙的一个在map中+=async的问题]]></description><link>https://xenojoshua.com/posts/2022/09/node-async-issue</link><guid isPermaLink="false">https://xenojoshua.com/posts/2022/09/node-async-issue</guid><pubDate>Mon, 05 Sep 2022 15:09:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E7%9C%8B%E4%BB%A3%E7%A0%81&quot;&gt;1. 看代码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%8E%9F%E7%90%86&quot;&gt;2. 原理&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-看代码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E7%9C%8B%E4%BB%A3%E7%A0%81&quot; aria-label=&quot;1 看代码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 看代码&lt;/h1&gt;
&lt;p&gt;东西都不复杂，看代码就完事了，一共是4个代码片段&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;map 中进行 += await&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; total &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exec&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      total &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果如图:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/node-async-issue/01.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;map 中进行 =赋值 然后+=&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; total &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exec&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      total &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果如图:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/node-async-issue/02.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;map 中进行 = await +&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; total &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exec&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      total &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这个结果和图2相同，也就是和上面一组相同&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;map 中进行同步 +=&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; total &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; Promise&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;exec&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;b&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      total &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;done&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; total&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果如图:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/node-async-issue/03.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;2-原理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%8E%9F%E7%90%86&quot; aria-label=&quot;2 原理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 原理&lt;/h1&gt;
&lt;p&gt;原理一点都不复杂，稍微想一下就知道了。这里主要是要注意这种case的发生，需要有意识地规避。因为结果比较反直觉，就算是有经验的程序员也会犯错。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Git Revert Trap]]></title><description><![CDATA[Commit lost when branch merged with revert command used]]></description><link>https://xenojoshua.com/posts/2022/09/git-revert-trap</link><guid isPermaLink="false">https://xenojoshua.com/posts/2022/09/git-revert-trap</guid><pubDate>Mon, 05 Sep 2022 14:09:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-see-an-example&quot;&gt;1. See an example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-see-an-example&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-see-an-example&quot; aria-label=&quot;1 see an example permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. See an example&lt;/h1&gt;
&lt;p&gt;Let’s see an example&lt;/p&gt;
&lt;p&gt;Step 1. Init dir &lt;code class=&quot;language-text&quot;&gt;git_test&lt;/code&gt; and git repo&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/Downloads &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; git_test &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; git_test &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; init &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;console.log(&quot;This is init&quot;);&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; index.js &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;init commit&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Step 2. Create branches: &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;feat-x&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;release&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch develop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout develop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;console.log(&quot;This is commit in develop&quot;);&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; index.js &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;develop commit&quot;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch feat-x &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch release&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/01.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Step 3. In branch &lt;code class=&quot;language-text&quot;&gt;feat-x&lt;/code&gt;, add one file &lt;code class=&quot;language-text&quot;&gt;x.js&lt;/code&gt; and append some codes in previous &lt;code class=&quot;language-text&quot;&gt;index.js&lt;/code&gt;, then merge it to &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout feat-x &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;console.log(&quot;code x file&quot;);&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; x.js &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;console.log(&quot;feat x changes&quot;);&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; - index.js &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /tmp/out &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; /tmp/out index.js &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;feat: x commit&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout develop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feat-x --no-ff&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/02.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Step 4. Now revert this merged commit on &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout develop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; revert 6aa7c6550c182605a24c95a41b7d32939f9e346f&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/03.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Step 5. Go to &lt;code class=&quot;language-text&quot;&gt;release&lt;/code&gt;, make some commits&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout release &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;console.log(&quot;release changes1&quot;);&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; index.js &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;release: change1&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;console.log(&quot;release changes2&quot;);&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt; index.js &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; commit &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;release: change2&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/04.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Step 6. Merge &lt;code class=&quot;language-text&quot;&gt;feat-x&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;release&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout release &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge feat-x --no-ff&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/05.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Step 7. Merge &lt;code class=&quot;language-text&quot;&gt;release&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout develop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge release --no-ff&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/06.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/07.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;See the branch &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;, you will find there is no changes belong to &lt;code class=&quot;language-text&quot;&gt;feat-x&lt;/code&gt;. We have this branch merged to develop previously, and we reverted that commit. Later we have commit merged from &lt;code class=&quot;language-text&quot;&gt;feat-x&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;release&lt;/code&gt; then &lt;code class=&quot;language-text&quot;&gt;release&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;. But as you can see, even this commit merged with &lt;code class=&quot;language-text&quot;&gt;release&lt;/code&gt; branch to &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt; later (means this commit merged to &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt; twice), it still not in the &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;How to fix this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;make a new branch &lt;code class=&quot;language-text&quot;&gt;fix&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;cherry-pick the commit belongs to &lt;code class=&quot;language-text&quot;&gt;feat-x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;merge &lt;code class=&quot;language-text&quot;&gt;fix&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout develop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; branch fix &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout fix &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; cherry-pick 6aa7c6550c182605a24c95a41b7d32939f9e346f&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/08.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout develop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; merge fix --no-ff&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;See the result:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/09.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/09/git-revert-trap/10.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Charles证书刷新]]></title><description><![CDATA[如何刷新到期的Charles根证书]]></description><link>https://xenojoshua.com/posts/2022/06/charles-cert-renew</link><guid isPermaLink="false">https://xenojoshua.com/posts/2022/06/charles-cert-renew</guid><pubDate>Wed, 15 Jun 2022 10:09:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%87%A0%E4%B8%AA%E6%96%B9%E6%B3%95&quot;&gt;2. 几个方法&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E9%87%8D%E7%BD%AE%E6%A0%B9%E8%AF%81%E4%B9%A6&quot;&gt;2.1 重置根证书&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E5%88%A0%E9%99%A4%E5%B9%B6%E9%87%8D%E6%96%B0%E7%94%9F%E6%88%90%E8%AF%81%E4%B9%A6&quot;&gt;2.2 删除并重新生成证书&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;新版本的Charles（具体是哪个版本我不记得了）生成出来的根证书只有1年的有效期，所以很容易就会过期，导致测试使用的失败。而我上次更新根证书的时候发生了很多问题，所以这里做个笔记来记录下。&lt;/p&gt;
&lt;p&gt;主要是参考这篇博文：&lt;a href=&quot;https://charlesdocsy.com/2021/12/29/expired-charles-proxy-root-certificate/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Expired Charles Proxy Root Certificate&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;2-几个方法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%87%A0%E4%B8%AA%E6%96%B9%E6%B3%95&quot; aria-label=&quot;2 几个方法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 几个方法&lt;/h1&gt;
&lt;h2 id=&quot;21-重置根证书&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E9%87%8D%E7%BD%AE%E6%A0%B9%E8%AF%81%E4%B9%A6&quot; aria-label=&quot;21 重置根证书 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 重置根证书&lt;/h2&gt;
&lt;p&gt;操作步骤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open Charles -&gt; Help -&gt; SSL Proxying -&gt; Reset Charles Root Certificate …&lt;/li&gt;
&lt;li&gt;Now follow the on-screen instructions&lt;/li&gt;
&lt;li&gt;Once complete, please restart Charles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然后手机上的根证书需要删除之后重新下载安装，和之前的初始安装操作一致。&lt;/p&gt;
&lt;h2 id=&quot;22-删除并重新生成证书&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E5%88%A0%E9%99%A4%E5%B9%B6%E9%87%8D%E6%96%B0%E7%94%9F%E6%88%90%E8%AF%81%E4%B9%A6&quot; aria-label=&quot;22 删除并重新生成证书 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 删除并重新生成证书&lt;/h2&gt;
&lt;p&gt;删除证书：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;From the Keychain application, right-click the Charles Root certificate&lt;/li&gt;
&lt;li&gt;Select delete and follow the on-screen instructions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;重新生成证书：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open Charles -&gt; Help -&gt; SSL Proxying -&gt; Install Charles Root Certificate&lt;/li&gt;
&lt;li&gt;This should now open “Keychain Access” on your Mac. Follow the on-screen instruction&lt;/li&gt;
&lt;li&gt;Once complete, please restart Charles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;老样子，手机上的根证书需要删除之后重新下载安装，和之前的初始安装操作一致。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[ngrok tutorial]]></title><description><![CDATA[如何使用ngrok将本地进程暴露到公网]]></description><link>https://xenojoshua.com/posts/2022/04/ngrok-tutorial</link><guid isPermaLink="false">https://xenojoshua.com/posts/2022/04/ngrok-tutorial</guid><pubDate>Fri, 15 Apr 2022 09:09:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85%E5%87%86%E5%A4%87&quot;&gt;2. 安装准备&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E4%BD%BF%E7%94%A8%E8%8C%83%E4%BE%8B&quot;&gt;3. 使用范例&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E5%87%86%E5%A4%87%E6%9C%AC%E5%9C%B0http%E6%9C%8D%E5%8A%A1&quot;&gt;3.1 准备本地http服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E5%90%AF%E5%8A%A8ngrok&quot;&gt;3.2 启动ngrok&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E6%B5%8B%E8%AF%95&quot;&gt;3.3 测试&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;因为手头在做支付相关的内容，如何测试支付服务商的回调功能就比较头痛。&lt;/p&gt;
&lt;p&gt;当年比较多的是使用自己的VPS来进行测试，代码直接ssh到VPS上就行了。但是我手头上的境外VPS都关掉了，比较贵嘛，现在blog都可以用静态服务商的免费服务，所以就没继续持有了。境内的VPS我倒是有，价格便宜，但问题在于境内VPS如果你要搭网站绑定域名的话，都要求域名经过备案，那就没辙了。&lt;/p&gt;
&lt;p&gt;于是就需要一个能将自己的本地进程暴露到公网的方法，现在倒是有这种工具的，就比如：&lt;a href=&quot;https://ngrok.com&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://ngrok.com&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;2-安装准备&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85%E5%87%86%E5%A4%87&quot; aria-label=&quot;2 安装准备 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 安装准备&lt;/h1&gt;
&lt;p&gt;到官网上注册账号，进入console。然后到&lt;a href=&quot;https://dashboard.ngrok.com/get-started/your-authtoken&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Your Authtoken&lt;/a&gt;页面找到你自己的token，将字符串复制下来。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/ngrok-tutorial/ngrok-token.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;接下来安装ngrok的二进制可执行文件，推荐使用brew安装&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; ngrok &lt;span class=&quot;token parameter variable&quot;&gt;--cask&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;接下来配置刚才的token，这步自己看下ngrok的版本，我用brew安装的是2.x的版本，比官网的3.x要老，所以语法有点不同&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ngrok authtoken &lt;span class=&quot;token variable&quot;&gt;$your_token_string&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-使用范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E4%BD%BF%E7%94%A8%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;3 使用范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 使用范例&lt;/h1&gt;
&lt;h2 id=&quot;31-准备本地http服务&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E5%87%86%E5%A4%87%E6%9C%AC%E5%9C%B0http%E6%9C%8D%E5%8A%A1&quot; aria-label=&quot;31 准备本地http服务 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 准备本地http服务&lt;/h2&gt;
&lt;p&gt;本地生成一个静态html index文件，并使用npm的http-server启动一个本地服务器&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; ~/Downloads/test &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ~/Downloads/test
$ &lt;span class=&quot;token function&quot;&gt;touch&lt;/span&gt; index.html
$ &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; index.html&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;test page jd&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;pwd&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# /Users/jonathan/Downloads/test&lt;/span&gt;
$ npx http-server ./&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/ngrok-tutorial/ngrok-http-server.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;32-启动ngrok&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E5%90%AF%E5%8A%A8ngrok&quot; aria-label=&quot;32 启动ngrok permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 启动ngrok&lt;/h2&gt;
&lt;p&gt;因为我们本地服务启动在&lt;code class=&quot;language-text&quot;&gt;8080&lt;/code&gt;端口上，所以ngrok的命令要以这个端口为目标&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ ngrok http &lt;span class=&quot;token number&quot;&gt;8080&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/ngrok-tutorial/ngrok-tunnel.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;33-测试&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E6%B5%8B%E8%AF%95&quot; aria-label=&quot;33 测试 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 测试&lt;/h2&gt;
&lt;p&gt;需要注意，每次使用ngrok命令打通tunnel都会随机分配一个域名，每次都是不一样的，所以在测试的时候记得切换代码/配置里的域名。这次测试分配到的是：&lt;code class=&quot;language-text&quot;&gt;211e-101-80-9-92&lt;/code&gt;。测试使用的时候务必记得使用https protocol，即便如此chrome还是会提醒这个网站不安全。反正只是测试用的，就无所谓了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/ngrok-tutorial/ngrok-test.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后可以打开&lt;a href=&quot;http://127.0.0.1:4040&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://127.0.0.1:4040&lt;/a&gt;，这是ngrok的console页面，会显示访问请求列表&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/ngrok-tutorial/ngrok-console.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Swift iOS App唤起支付宝支付的简单教程]]></title><description><![CDATA[如何制作一个简单的Swift iOS App来唤醒支付宝进行支付]]></description><link>https://xenojoshua.com/posts/2022/04/alipay-swift-and-tutorial</link><guid isPermaLink="false">https://xenojoshua.com/posts/2022/04/alipay-swift-and-tutorial</guid><pubDate>Fri, 15 Apr 2022 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%88%9B%E5%BB%BAios%E9%A1%B9%E7%9B%AE&quot;&gt;2. 创建iOS项目&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%AE%89%E8%A3%85cocospods&quot;&gt;3. 安装cocospods&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E5%AE%89%E8%A3%85alipay-sdk&quot;&gt;4. 安装Alipay SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E6%A1%A5%E6%8E%A5alipay-sdk%E7%9A%84header%E6%96%87%E4%BB%B6&quot;&gt;5. 桥接Alipay SDK的Header文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-%E5%AE%9E%E7%8E%B0%E5%94%A4%E8%B5%B7alipay&quot;&gt;6. 实现唤起Alipay&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;作为一名后端程序员，整个API链的调用联调是否能摒除所有的外部依赖是非常重要的，测试的流程贯通关系到整个开发的顺畅程度。支付系统的联调麻烦就麻烦在有外部系统的依赖。虽然在做开发的时候可以在单元测试代码中进行Mock来绕过外部的依赖，但真实的e2e测试还是必须的，这个时候就需要引入外部支付系统的接口了。&lt;/p&gt;
&lt;p&gt;目前国内的支付系统主要就是支付宝和维信支付。微信支付有点忘记了，但支付宝的app支付和网页支付是分开的2个独立的功能，也就是说公司的app可能只签了app支付而没有签网页支付。这种情况下在测试的时候，后端下单之后就无法使用自己生成的二维码然后用手机扫码支付测试了，必须是直接在手机的app内进行测试。这就很麻烦。所以本文会做一个教程，简单教下如何创建一个简单的app，可以使用后端下单生成的返回字串来唤醒支付宝进行支付，以打通整个支付流程。&lt;/p&gt;
&lt;h1 id=&quot;2-创建ios项目&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%88%9B%E5%BB%BAios%E9%A1%B9%E7%9B%AE&quot; aria-label=&quot;2 创建ios项目 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 创建iOS项目&lt;/h1&gt;
&lt;p&gt;首先需要注册一个Apple开发者账号，因为没有任何账号的话，是无法对App进行打包和部署到手机上进行测试的。注册去：&lt;a href=&quot;https://developer.apple.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://developer.apple.com/&lt;/a&gt;，点右上角的&lt;code class=&quot;language-text&quot;&gt;Account&lt;/code&gt;，按引导注册即可。然后打开xocde，点开&lt;code class=&quot;language-text&quot;&gt;Perferences -&gt; Accounts&lt;/code&gt;，点左下角的&lt;code class=&quot;language-text&quot;&gt;+&lt;/code&gt;添加自己的账号。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-account.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后打开xcode，创建新项目。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-create-1.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-create-2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;题外：如果想认真学习下Swift的话，官方Tutorials教程在：&lt;a href=&quot;https://developer.apple.com/tutorials/swiftui/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;SwiftUI Tutorials&lt;/a&gt;。此外，还有&lt;a href=&quot;https://docs.swift.org/swift-book/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The swift programming language&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;3-安装cocospods&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%AE%89%E8%A3%85cocospods&quot; aria-label=&quot;3 安装cocospods permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 安装cocospods&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;cocospods&lt;/code&gt;是iOS项目的依赖管理工具，类似nodejs的npm，基本上做项目都需要。最方便的的一点是这东西在安装的时候，会把一些对应的配置文件都更新好，对于我这样的新手来说就少了很多事情。&lt;/p&gt;
&lt;p&gt;几篇参考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/f43b5964f582&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CocoaPods安装方法-2022.03.25&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cloud.tencent.com/developer/article/1143325&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;cocoapods从安装到使用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 安装cocospods本体&lt;/span&gt;
$ brew update &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;
$ brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; cocospods &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# 安装数据库，这个repo超级大，一共有将近1个GB的数据，建议用代理加速&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone https://github.com/CocoaPods/Specs.git ~/.cocoapods/repos/trunk
&lt;span class=&quot;token comment&quot;&gt;# 完成后测试下效果，是否可以搜到dep，有结果返回就OK了&lt;/span&gt;
$ pod search Alamofire&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-安装alipay-sdk&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E5%AE%89%E8%A3%85alipay-sdk&quot; aria-label=&quot;4 安装alipay sdk permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 安装Alipay SDK&lt;/h1&gt;
&lt;p&gt;到刚才创建的新项目的根目录下，首先需要创建pod的配置文件，类似package.json&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ pod init&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;会生成一个&lt;code class=&quot;language-text&quot;&gt;Podfile&lt;/code&gt;，然后编辑该文件，添加Alipay SDK，添加在&lt;code class=&quot;language-text&quot;&gt;# Pods for AlipayTest&lt;/code&gt;这行下：&lt;code class=&quot;language-text&quot;&gt;pod &apos;AlipaySDK-iOS&apos;&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Uncomment the next line to define a global platform for your project&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# platform :ios, &apos;9.0&apos;&lt;/span&gt;

target &lt;span class=&quot;token string&quot;&gt;&apos;AlipayTest&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# Comment the next line if you don&apos;t want to use dynamic frameworks&lt;/span&gt;
  use_frameworks&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# Pods for AlipayTest&lt;/span&gt;
  pod &lt;span class=&quot;token string&quot;&gt;&apos;AlipaySDK-iOS&apos;&lt;/span&gt;

  target &lt;span class=&quot;token string&quot;&gt;&apos;AlipayTestTests&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    inherit&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; :search_paths
    &lt;span class=&quot;token comment&quot;&gt;# Pods for testing&lt;/span&gt;
  end

  target &lt;span class=&quot;token string&quot;&gt;&apos;AlipayTestUITests&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Pods for testing&lt;/span&gt;
  end

end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最后在repo的根目录下执行安装命令&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ pod &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;安装完成的dep都放在：&lt;code class=&quot;language-text&quot;&gt;Pods/&lt;/code&gt;下，Alipay SDK在：&lt;code class=&quot;language-text&quot;&gt;/Pods/AlipaySDK-iOS&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;后续需要关闭xcode，使用新生成的&lt;code class=&quot;language-text&quot;&gt;AlipayTest.xcworkspace&lt;/code&gt;文件来打开项目。&lt;/p&gt;
&lt;p&gt;更多细节可以看支付宝官方的：&lt;a href=&quot;https://opendocs.alipay.com/open/204/105295&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;客户端 iOS 集成流程&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;5-桥接alipay-sdk的header文件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E6%A1%A5%E6%8E%A5alipay-sdk%E7%9A%84header%E6%96%87%E4%BB%B6&quot; aria-label=&quot;5 桥接alipay sdk的header文件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 桥接Alipay SDK的Header文件&lt;/h1&gt;
&lt;p&gt;因为Alipay SDK是使用ObjC写的，所以在Swift项目中使用需要做一步工作：引入桥接的Header文件。&lt;/p&gt;
&lt;p&gt;执行创建文件操作，选择ObjC文件，名字随意，实际上这个ObjC文件我们后续可以直接删除，没用。IDE会问是否需要创建桥接Header，点击蓝色按钮选是，这才是我们创建ObjC文件的真正目的。&lt;/p&gt;
&lt;p&gt;操作完成后，删除ObjC文件，打开桥接Header文件，并添加：&lt;code class=&quot;language-text&quot;&gt;# import &amp;lt;AlipaySDK/AlipaySDK.h&gt;&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-header-1.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-header-2.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-header-3.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-header-4.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-header-5.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;6-实现唤起alipay&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-%E5%AE%9E%E7%8E%B0%E5%94%A4%E8%B5%B7alipay&quot; aria-label=&quot;6 实现唤起alipay permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. 实现唤起Alipay&lt;/h1&gt;
&lt;p&gt;打开创建新项目时默认生成的：&lt;code class=&quot;language-text&quot;&gt;ContentView&lt;/code&gt;。页面上添加一个 TextEditor 用来输入后端下单之后生成的&lt;code class=&quot;language-text&quot;&gt;sign字符串&lt;/code&gt;，然后一个 Button 来执行确认唤起。&lt;/p&gt;
&lt;p&gt;要正确唤起支付宝，并能够正确支付，需要注意几个点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进行测试的手机上需要安装好真正的业务app（我们做的支付测试app是为了测通支付流程用的，不是真正的应用app，这里说需要安装好的是我们实际接入支付的真正的业务app）&lt;/li&gt;
&lt;li&gt;用来输入sign字符串的 TextEditor，在输入的时候需要删除之前的Placeholder&lt;code class=&quot;language-text&quot;&gt;Input the sign here&lt;/code&gt;，我是没找到这个控件应该怎么加Placeholder…&lt;/li&gt;
&lt;li&gt;代码中&lt;code class=&quot;language-text&quot;&gt;AlipaySDK.defaultService().payOrder&lt;/code&gt;的&lt;code class=&quot;language-text&quot;&gt;fromScheme&lt;/code&gt;需要替换成第二点中提到的真正业务app的项目名字，也就是支付宝支付完成后的回调app
&lt;ul&gt;
&lt;li&gt;这里不知道为什么，填写我们的测试app的名字支付宝支付会报错，具体应该和iOS应用配置打包细节有关，这个我不是专业的就不琢磨了，直接用真正的业务app的名字即可&lt;/li&gt;
&lt;li&gt;所以这个支付的回调是不会走回我们的这个支付测试app的，而是会回到业务app，切记，不过无所谓，毕竟我们只是要完成支付打通支付流程而已&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//  ContentView.swift&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//  honors&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//  Created by Jonathan Dai on 2022/4/14.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; editor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Input the sign here&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attribute atrule&quot;&gt;@State&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Console:\n&quot;&lt;/span&gt;&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;VStack&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;SwiftUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Pay with order sign&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token nil constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;TextEditor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $editor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;Button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;action&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Button &apos;Go to Alipay&apos; clicked&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token function&quot;&gt;gotoAlipay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token class-name&quot;&gt;Text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Go to Alipay&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;all&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;token class-name&quot;&gt;TextEditor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; $console&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;border&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;black&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;gotoAlipay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;console &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gotoAlipay\n&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gotoAlipay: sign: &quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;editor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;AlipaySDK&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;payOrder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;editor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fromScheme&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;YourBusinessAppNameHere&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; callback&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resultDic&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Alipay reslut = &lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;describing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resultDic&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; resultDic &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; resultDic&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Dictionary&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; resultStatus &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; resultDic&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;resultStatus&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; resultStatus &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;9000&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;console &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;支付成功\n&quot;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;console &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token string-literal&quot;&gt;&lt;span class=&quot;token string&quot;&gt;&quot;支付失败\n&quot;&lt;/span&gt;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ContentView_Previews&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PreviewProvider&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; previews&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;some&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token class-name&quot;&gt;Group&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;ContentView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;UI长这样&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2022/04/alipay-swift-and-tutorial/xcode-preview.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后端下单，生成app唤起用的sign字符串&lt;/li&gt;
&lt;li&gt;拷贝到该测试应用的第一个 TextEditor 里&lt;/li&gt;
&lt;li&gt;点击按钮&lt;code class=&quot;language-text&quot;&gt;Go to Alipay&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;即可&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Obsidian插件经验]]></title><description><![CDATA[制作Obsidian插件相关经验]]></description><link>https://xenojoshua.com/posts/2021/10/obsidian-plugin</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/10/obsidian-plugin</guid><pubDate>Fri, 08 Oct 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%9F%BA%E7%A1%80&quot;&gt;2. 基础&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E4%BB%A3%E7%A0%81&quot;&gt;3. 代码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E9%97%AE%E9%A2%98&quot;&gt;4. 问题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#reference&quot;&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;之前花了点时间制作Obsidian的插件：&lt;a href=&quot;https://github.com/agreatfool/obsidian-post-gallery&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;agreatfool/obsidian-post-gallery&lt;/a&gt;，稍微积累了点经验，这里留点笔记。不会过于深入，因为我做的插件还是很简单的，也没有用到太多的Obsidian的功能。&lt;/p&gt;
&lt;p&gt;丑话说在前面，Obsidian的Plugin相关文档是极其匮乏的，有很多功能你基本上找不到文档对于其的描述，更扯的是一部分概念在文档里也没解释，比如说：&lt;code class=&quot;language-text&quot;&gt;leaf&lt;/code&gt;等，导致如果你需要制作功能比较复杂的插件的话，会很困难。最好的方法就是找现在官方网站上列出来的那些community plugin的源码，然后慢慢读。我也搞不懂这些作者是怎么搞清楚那么多细节的，哎。反正我是没做很高级的功能，所以基本上没怎么接触。&lt;/p&gt;
&lt;h1 id=&quot;2-基础&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%9F%BA%E7%A1%80&quot; aria-label=&quot;2 基础 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 基础&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/obsidianmd/obsidian-api&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;obsidianmd/obsidian-api&lt;/a&gt;，算是官方的插件文档地址。这个repo里面就只有一个&lt;code class=&quot;language-text&quot;&gt;d.ts&lt;/code&gt;文件，描述了Obsidian API的内容。制作插件的时候可以使用这些官方提供的API，实际上Obsidian是基于&lt;a href=&quot;https://www.electronjs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Electron&lt;/a&gt;的一个封装，但官方的API并不会暴露Electron的API给你使用，是基于安全方面的考量：&lt;a href=&quot;https://forum.obsidian.md/t/security-of-the-plugins/7544&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Security of the plugins&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/obsidianmd/obsidian-sample-plugin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;obsidianmd/obsidian-sample-plugin&lt;/a&gt;是官方的范例repo，可以clone下来尝试下，里面有最简单的使用范例。&lt;/p&gt;
&lt;p&gt;在编码方面，你会需要安装&lt;a href=&quot;https://www.npmjs.com/package/obsidian&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Obsidian API&lt;/a&gt;，虽然本质上它也就只是一个typing。&lt;/p&gt;
&lt;h1 id=&quot;3-代码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E4%BB%A3%E7%A0%81&quot; aria-label=&quot;3 代码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 代码&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;main.ts&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; LibOs &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;os&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; MarkdownPostProcessorContext&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Plugin &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;obsidian&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; MarkdownBlockProcessor &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./lib/md_block&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InPostGalleryPlugin&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Plugin&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LibOs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;darwin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;InPostGalleryPlugin.onload unsupported platform: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;LibOs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;InPostGalleryPlugin.onload&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerMarkdownCodeBlockProcessor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;post-gallery&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; el&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; HTMLElement&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; MarkdownPostProcessorContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MarkdownBlockProcessor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;source&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; el&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ctx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;定义一个 default export 的 class，继承 obsidian 包里的 &lt;code class=&quot;language-text&quot;&gt;Plugin&lt;/code&gt;。上面的代码就只响应了&lt;code class=&quot;language-text&quot;&gt;onload&lt;/code&gt;事件，在事件中保证插件安装在OSX系统中，并注册一个markdown代码块处理器，在&lt;code class=&quot;language-text&quot;&gt;post-gallery&lt;/code&gt;代码块出现的时候进行触发。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;md_block.ts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;剩下的其他功能代码也非常简单，一共没几行：&lt;a href=&quot;https://github.com/agreatfool/obsidian-post-gallery/blob/master/src/lib/md_block.ts&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;md_block.ts&lt;/a&gt;，可以简单看下。&lt;/p&gt;
&lt;h1 id=&quot;4-问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E9%97%AE%E9%A2%98&quot; aria-label=&quot;4 问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 问题&lt;/h1&gt;
&lt;p&gt;当时在制作这个插件的时候，虽然功能很简单，但还是遇到了不少问题。最主要的一个问题是代码打包。&lt;/p&gt;
&lt;p&gt;因为所有的dep安装（源码）都是通过npm安装的，而代码的&lt;code class=&quot;language-text&quot;&gt;import / require&lt;/code&gt;又是在&lt;code class=&quot;language-text&quot;&gt;Obsidian (Electron)&lt;/code&gt;环境中运行的，所以很多用来初始化的&lt;code class=&quot;language-text&quot;&gt;self execute function: (function(){})()&lt;/code&gt;会侦测错环境，导致最终的lib加载注入错了global：&lt;code class=&quot;language-text&quot;&gt;global vs window&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这里需要使用第三方的打包工具来进行代码打包，比如说webpack，但因为我这个项目实在是太小了，杀鸡牛刀，也不想浪费时间搞一大堆的配置。最后就直接把一些第三方的dep的加载函数给改了下，放到src里，作为自己的源码来进行import，就行了。算是比较&lt;code class=&quot;language-text&quot;&gt;tricky&lt;/code&gt;的绕过方法。&lt;/p&gt;
&lt;p&gt;举个例子：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;原版 jquery&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;global&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;use strict&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; module &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;object&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;object&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// For CommonJS and CommonJS-like environments where a proper `window`&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// is present, execute the factory and get jQuery.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// For environments that do not have a `window` with a `document`&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// (such as Node.js), expose a factory as module.exports.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// This accentuates the need for the creation of a real `window`.&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// e.g. var jQuery = require(&quot;jquery&quot;)(window);&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// See ticket #14549 for more info.&lt;/span&gt;
    module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; global&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;document
      &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;global&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;jQuery requires a window with a document&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;global&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Pass this if window is not defined yet&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; window &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;undefined&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; window &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; noGlobal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;修改后&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;global&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&apos;use strict&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Pass this if window is not defined yet&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; window &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;undefined&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; window &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;window&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; noGlobal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;reference&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#reference&quot; aria-label=&quot;reference permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Reference&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/obsidianmd/obsidian-api&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;obsidianmd/obsidian-api&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forum.obsidian.md/t/plugins-mini-faq/7737&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Plugins mini FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://forum.obsidian.md/t/security-of-the-plugins/7544&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Security of the plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.electronjs.org/docs/latest/api/shell&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Electron &gt; API &gt; shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.electronjs.org/docs/latest/api/browser-window#winpreviewfilepath-displayname-macos&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Electron &gt; API &gt; win.previewFile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Darakah/obsidian-gallery&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Darakah/obsidian-gallery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/5073603/is-there-a-way-to-trigger-finders-quick-look-window-with-applescript&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Is there a way to trigger Finder’s “quick look” window with Applescript?&lt;/a&gt;，这个方向错了，应该搜 “electron” mac image quick look&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/obsidian-tools/obsidian-tools&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;obsidian-tools/obsidian-tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lightgalleryjs.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;lightGallery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/justifiedGallery&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;justifiedGallery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Evernote: The Knowledge Database]]></title><description><![CDATA[使用Evernote来管理你的知识数据库]]></description><link>https://xenojoshua.com/posts/2021/10/knowledge-database</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/10/knowledge-database</guid><pubDate>Thu, 07 Oct 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E7%9F%A5%E8%AF%86%E7%AE%A1%E7%90%86&quot;&gt;2. 知识管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-evernote%E4%BD%BF%E7%94%A8&quot;&gt;3. Evernote使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E7%BD%91%E9%A1%B5%E5%89%AA%E8%97%8F&quot;&gt;3.1 网页剪藏&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E5%BE%AE%E4%BF%A1%E5%89%AA%E8%97%8F&quot;&gt;3.2 微信剪藏&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-tag%E7%AE%A1%E7%90%86&quot;&gt;3.3 Tag管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-%E6%90%9C%E7%B4%A2&quot;&gt;3.4 搜索&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-evernote%E7%BC%BA%E9%99%B7&quot;&gt;4. Evernote缺陷&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-editor&quot;&gt;4.1 Editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-export&quot;&gt;4.2 Export&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-sync&quot;&gt;4.3 Sync&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;之前在&lt;a href=&quot;/posts/2021/08/notes-management&quot;&gt;如何管理个人笔记&lt;/a&gt;里也提到了知识管理我选的是Evernote这款软件。这里就聊下，知识管理主要指什么，要做什么，以及Evernote这款软件的功能等。&lt;/p&gt;
&lt;h1 id=&quot;2-知识管理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E7%9F%A5%E8%AF%86%E7%AE%A1%E7%90%86&quot; aria-label=&quot;2 知识管理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 知识管理&lt;/h1&gt;
&lt;p&gt;所谓知识管理，核心功能需要以下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;方便简洁的知识收集能力，操作要简单，渠道覆盖要全面&lt;/li&gt;
&lt;li&gt;基本的知识分类管理能力，按category和tag对一条知识进行组织和管理（核心是tag，category可选非必要）&lt;/li&gt;
&lt;li&gt;强大和&lt;code class=&quot;language-text&quot;&gt;高效&lt;/code&gt;的搜索能力，1-2秒内快速搜索指定的tag对应的知识条目，需要支持复合搜索&lt;/li&gt;
&lt;li&gt;数据导出和工具迁移能力，知识条目可以导出，并可以迁移到其他软件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;即：收集、管理（标签）、搜索，三个步骤。这里编辑功能是非必要的，至少不是核心功能，编辑功能可以做得很糟糕（就比如Evernote，极其糟糕的编辑功能）。&lt;/p&gt;
&lt;p&gt;一般的流程为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;看到合适的知识内容（微信公众号、网页等），使用Evernote的剪藏工具剪藏收集到Evernote中&lt;/li&gt;
&lt;li&gt;更新Evernote里的剪藏post，移动到合适的category并附上合适的tags&lt;/li&gt;
&lt;li&gt;后续如果有任何搜索需求，使用Evernote的搜索功能进行查询&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-evernote使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-evernote%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;3 evernote使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Evernote使用&lt;/h1&gt;
&lt;h2 id=&quot;31-网页剪藏&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E7%BD%91%E9%A1%B5%E5%89%AA%E8%97%8F&quot; aria-label=&quot;31 网页剪藏 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 网页剪藏&lt;/h2&gt;
&lt;p&gt;剪藏的官方插件列表在这里：&lt;a href=&quot;https://www.yinxiang.com/product/webclipper/install/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;印象笔记剪藏·下载&lt;/a&gt;。Chrome插件在&lt;a href=&quot;https://chrome.google.com/webstore/detail/evernote-web-clipper/pioclpoplcdbaefihamjohnefbikjilc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;这里&lt;/a&gt;，如果是墙内的话可以自己打开前面的链接找里面的下载包。&lt;/p&gt;
&lt;p&gt;关于如何切换国际版和国内版，参见：&lt;a href=&quot;https://help.evernote.com/hc/sr-me/articles/213419317-%E5%A6%82%E4%BD%95%E5%88%87%E6%8D%A2%E5%8D%B0%E8%B1%A1%E7%AC%94%E8%AE%B0%E5%9B%BD%E5%86%85%E5%B8%90%E6%88%B7%E5%92%8C-Evernote-%E5%9B%BD%E9%99%85%E7%89%88%E5%B8%90%E6%88%B7%E7%99%BB%E5%BD%95%E5%85%A5%E5%8F%A3-&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;如何切换印象笔记国内帐户和 Evernote 国际版帐户登录入口？&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;使用：点击插件列表里的Evernote图标或键盘”`“呼出剪藏面板，然后简单操作即可：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/10/knowledge-database/evernote-webclipper.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;32-微信剪藏&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E5%BE%AE%E4%BF%A1%E5%89%AA%E8%97%8F&quot; aria-label=&quot;32 微信剪藏 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 微信剪藏&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://yinxiang.com/product/wechatmyyxbj/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;我的印象笔记@微信&lt;/a&gt;。按步骤操作即可。&lt;/p&gt;
&lt;p&gt;因为很久之前的一次微信改版，现在都需要手动拷贝链接贴到微信公众号的聊天框内才能收藏，实在是很麻烦。&lt;/p&gt;
&lt;h2 id=&quot;33-tag管理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-tag%E7%AE%A1%E7%90%86&quot; aria-label=&quot;33 tag管理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 Tag管理&lt;/h2&gt;
&lt;p&gt;Tag的管理建议：&lt;code class=&quot;language-text&quot;&gt;宁滥毋缺&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;因为你在使用/搜索的时候，不一定能精确记起每个你命名的tag，有的时候可以多留几个近义词来保证后续搜索的稳定性。&lt;/p&gt;
&lt;p&gt;两个个人习惯：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为那些高质量，在搜索某个tag/概念的时候肯定想要搜到的条目附加&lt;code class=&quot;language-text&quot;&gt;BestPractice&lt;/code&gt;标签，作为后续过滤高质量条目的tag&lt;/li&gt;
&lt;li&gt;为某些概念的条目添加CN/EN双重tag，防止某些时候想不起来：e.g &lt;code class=&quot;language-text&quot;&gt;DistributedSystem / 分布式系统&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;34-搜索&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-%E6%90%9C%E7%B4%A2&quot; aria-label=&quot;34 搜索 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 搜索&lt;/h2&gt;
&lt;p&gt;搜索语法参见官方文档（EN）：&lt;a href=&quot;https://dev.evernote.com/doc/articles/search_grammar.php&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Search Grammar&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;常用搜索：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;notebook:&quot;golang&quot;&lt;/code&gt;，根据category/笔记本来搜索&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;tag:&quot;TagNameXX*&quot;&lt;/code&gt;，根据tag来搜索条目，搜索可以带通配符&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-tag:&quot;TagNameYY&quot;&lt;/code&gt;，不包含某个tag&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;created:&quot;20210704&quot;&lt;/code&gt;，搜索在2021-07-04或之后创建的条目&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sourceurl:&quot;https://www.google.com/*&quot;&lt;/code&gt;，根据条目url进行搜索&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt;，根据字符串来搜索条目内容&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-content&lt;/code&gt;，根据条目内容搜索不带&lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt;字符串的条目&lt;/li&gt;
&lt;li&gt;关于复合条件搜索
&lt;ul&gt;
&lt;li&gt;任何多条件的搜索默认都是&lt;code class=&quot;language-text&quot;&gt;and&lt;/code&gt;关系，e.g &lt;code class=&quot;language-text&quot;&gt;criteria1 criteria2&lt;/code&gt; 也就是 &lt;code class=&quot;language-text&quot;&gt;both criteria1 and criteria2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果需要按&lt;code class=&quot;language-text&quot;&gt;or&lt;/code&gt;关系进行搜索，需要在所有的criteria之前带上&lt;code class=&quot;language-text&quot;&gt;any&lt;/code&gt;，e.g &lt;code class=&quot;language-text&quot;&gt;any: criteria1 criteria2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;AND&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/10/knowledge-database/evernote-search-and.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;OR&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/10/knowledge-database/evernote-search-or.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;4-evernote缺陷&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-evernote%E7%BC%BA%E9%99%B7&quot; aria-label=&quot;4 evernote缺陷 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Evernote缺陷&lt;/h1&gt;
&lt;h2 id=&quot;41-editor&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-editor&quot; aria-label=&quot;41 editor permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 Editor&lt;/h2&gt;
&lt;p&gt;Evernote说实在的，在使用上还是有相当多的问题。最主要的是它的编辑能力实在是非常孱弱，基本上除了随手写点笔记之外，结构性的和系统性的文章编辑就别指望它了，任何一款主流的基于Markdown的编辑软件都比它好用。&lt;/p&gt;
&lt;p&gt;虽然Evernote的新版本也支持markdown，但还是明显和传统笔记分割了开来，在Evernote里创建笔记只会创建出TXT笔记，而Markdown语法支持的笔记需要特定选择才可以：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/10/knowledge-database/evernote-markdown-create.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;42-export&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-export&quot; aria-label=&quot;42 export permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 Export&lt;/h2&gt;
&lt;p&gt;Evernote的导出也不是特别友好，因为刚才说的，其支持Markdown比较晚，所以大量的历史存量笔记肯定都是TXT格式（从使用者角度来说）的，所以导出的时候的选项一般只有&lt;code class=&quot;language-text&quot;&gt;HTML&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;ENEX&lt;/code&gt;这个Evernote专用格式（后续测试了下，即便新版本里可以创建Markdown笔记，导出的时候也只有HTML和ENEX这两个选项）。&lt;/p&gt;
&lt;p&gt;也就是说，如果后续用户希望转到其他的平台或其他的工具，那只有祈祷转入方能够支持&lt;code class=&quot;language-text&quot;&gt;ENEX&lt;/code&gt;格式的文件了。我之前有做过一些简单research，从结果来看不太乐观，一般来说即便宣称支持的那些软件做得也不太好，会有各种各样的导入问题或展示格式问题。而且有很多软件虽然支持导入ENEX文件，但不支持批量导入，所以当你需要整个转过去的时候就基本上没办法了。&lt;/p&gt;
&lt;p&gt;因此，使用Evernote是有壁垒的，用户要有心理准备，后续将会很难将自己的数据导出或转移到其他服务。当然这也并非Evernote一家的问题，我相信MS的OneNote应该也差不多，或者其他的软件也是如此。&lt;/p&gt;
&lt;h2 id=&quot;43-sync&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-sync&quot; aria-label=&quot;43 sync permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 Sync&lt;/h2&gt;
&lt;p&gt;Evernote还有一个问题就是同步，最早的版本会完整同步所有你账户里的数据落地到本地磁盘，但后续的更新废除了这个同步。在新版本中，每次在新的机器上进行账号登录，只会同步&lt;code class=&quot;language-text&quot;&gt;最近一年&lt;/code&gt;的数据，更早的数据不会丢失，但并不会自动下载到你本地磁盘上，而是当你点击该条目的时候，再按需从Evernote的服务器上实时下载。&lt;/p&gt;
&lt;p&gt;这对数据完整性和数据安全敏感的用户来说极不友好，因为一旦Evernote的服务暂时不可用或永久停止服务的时候，你将没有任何手段将你的数据库完整下载下来，难道几万条条目一个个点过来吗，不现实的。&lt;/p&gt;
&lt;p&gt;所以如果数据量不大的话，记得尽量将你目前所拥有的本地数据做好备份，比如说用好TimeMachine，保证至少有一份完整的数据存在于你本地。然后比如说当你更换新机器的时候，记得将整个本地文件夹都拷贝到新的机器上去，然后再进行账户登录和同步，这样你的本地数据就一直都是完整的了。&lt;/p&gt;
&lt;p&gt;目前版本的Evernote在MAC上的数据存储在：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/Users/XXX/Library/Application Support/com.yinxiang.Mac/accounts/app.yinxiang.com/XXXX&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
$ &lt;span class=&quot;token function&quot;&gt;du&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-sh&lt;/span&gt; *
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.0K	ContactExtractorFetchDate.plist
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.0K	CoreNote-CheckPoint
 16K	SyncState
112K	announcements
 40K	atlas
760M	backupPreMigration
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.0K	checkpoint
  0B	chunks
 48G	content
  0B	eb-up-sell
  0B	external-edits
428K	localMessageStore
142M	localNoteStore
 11M	localNoteStore.metadata
335M	note-personal.index
203M	note.index
157M	note.index.old
&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;.0K	plugins
 80K	puppetmaster
 46M	purgatory
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.0K	quick-search.store
 32K	quick-search.store-shm
 12K	quick-search.store-wal
  0B	temp_relatedContent
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.0K	tierSelectionEligibility.state
265M	typeAhead-personal.index
182M	typeAhead.index
158M	typeAhead.index.old
&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.0K	version&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;条目数据全部都存放在&lt;code class=&quot;language-text&quot;&gt;content&lt;/code&gt;文件夹下，务必保证该文件夹得到妥善的备份。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[NAS备份计划 及 PC备份软件推荐]]></title><description><![CDATA[简单介绍下NAS的备份策略，并推荐一款非常好用的PC端的备份软件]]></description><link>https://xenojoshua.com/posts/2021/10/nas-backup</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/10/nas-backup</guid><pubDate>Wed, 06 Oct 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-syncbackpro-%E4%BB%8B%E7%BB%8D&quot;&gt;2. SyncBackPro 介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A4%87%E4%BB%BD%E5%91%A8%E6%9C%9F%E5%92%8C%E7%AD%96%E7%95%A5&quot;&gt;备份周期和策略&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;今年上半年对家里的NAS进行了下换代。之前只有一台&lt;code class=&quot;language-text&quot;&gt;4 * 6T NAS&lt;/code&gt;，备份基本上都是使用USB零碎手工做的，效率和安全性都非常差。上半年新购了一台NAS&lt;code class=&quot;language-text&quot;&gt;4 * 8T&lt;/code&gt;。然后组装了一台Intel的集显PC（基本都是最低性能，只有主板因为需要大量SATA口，所以还算比较好）把从2004年开始&lt;code class=&quot;language-text&quot;&gt;装机 -&gt; 报废&lt;/code&gt;循环后留下来的的大量闲置3.5寸硬盘都装了进去。&lt;/p&gt;
&lt;p&gt;这样就：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;32T新NAS作为主力机器，负责读写&lt;/li&gt;
&lt;li&gt;24T老NAS作为备份机，备份主力NAS里的一个子集&lt;/li&gt;
&lt;li&gt;PC差不多有33T的容量，也负责进行备份，同样备份主力NAS的一个子集&lt;/li&gt;
&lt;li&gt;部分内容为单备，会落在老NAS或备份PC两者其一&lt;/li&gt;
&lt;li&gt;部分比较重要的内容（e.g 十几年间的所有照片）双备，会在老NAS和备份PC中同时存在一份备份&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;两台NAS之间的备份比较好处理，因为都是&lt;code class=&quot;language-text&quot;&gt;QNAP&lt;/code&gt;的OS，所以直接使用系统自带的同步即可。&lt;/p&gt;
&lt;p&gt;但是NAS到PC之间的备份就不是那么好弄了，因为Windows的SMB的关系（此处存疑，不一定就是这个原因），导致NAS到PC的备份无论是速度还是稳定性都有问题，经常容易出现半路报错退出的情况。因此找了很久替代的方案，最后锁定了今天要提的备份软件&lt;code class=&quot;language-text&quot;&gt;SyncBackPro&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;2-syncbackpro-介绍&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-syncbackpro-%E4%BB%8B%E7%BB%8D&quot; aria-label=&quot;2 syncbackpro 介绍 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. SyncBackPro 介绍&lt;/h1&gt;
&lt;p&gt;主页在这里：&lt;a href=&quot;https://www.2brightsparks.com/syncback/sbpro.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://www.2brightsparks.com/syncback/sbpro.html&lt;/a&gt; 。付费软件，将近400，因为确实做的不错，就直接下单购买了。如果不放心的话可以下载之后试用一下，不用急着下单购买。&lt;/p&gt;
&lt;p&gt;支持的功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据源备份到云盘&lt;/li&gt;
&lt;li&gt;不同类型平台间（MAC、PC等）的数据备份&lt;/li&gt;
&lt;li&gt;支持推送数据从本地（源）到远程（目标）&lt;/li&gt;
&lt;li&gt;支持从远程（源）拉取数据到本地（目标）&lt;/li&gt;
&lt;li&gt;WIN计划任务设置，自动启动计划备份&lt;/li&gt;
&lt;li&gt;每次的备份运行都会有详细的日志，包括源与目标的文件差异，传输列表等，保证一清二楚&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其他未列出的还有很多，可以说完全满足了我对于备份的要求，确实相当好用。&lt;/p&gt;
&lt;h1 id=&quot;备份周期和策略&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%A4%87%E4%BB%BD%E5%91%A8%E6%9C%9F%E5%92%8C%E7%AD%96%E7%95%A5&quot; aria-label=&quot;备份周期和策略 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;备份周期和策略&lt;/h1&gt;
&lt;p&gt;目前我这里每周做一次备份：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;周五晚上老NAS做了电源计划任务，周五晚8点30自动启动&lt;/li&gt;
&lt;li&gt;听到启动音，手动启动备份PC&lt;/li&gt;
&lt;li&gt;周六凌晨，新NAS内会有同步任务，将文件从新NAS同步到老NAS&lt;/li&gt;
&lt;li&gt;周六早晨，备份PC内会有备份任务，将文件从新NAS拉到备份PC&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[MAC UTM 虚拟机使用]]></title><description><![CDATA[在MAC上安装使用UTM虚拟机]]></description><link>https://xenojoshua.com/posts/2021/10/mac-utm</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/10/mac-utm</guid><pubDate>Tue, 05 Oct 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E4%BB%8B%E7%BB%8D&quot;&gt;2. 介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%AE%89%E8%A3%85&quot;&gt;3. 安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E6%96%87%E4%BB%B6%E5%85%B1%E4%BA%AB&quot;&gt;4. 文件共享&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91&quot;&gt;5. 端口转发&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;一般来说使用MAC操作系统都会安装一个WIN虚拟机，来协助一些需要WIN的操作。因为之前的MAC也是使用的Intel的芯片，所以可以直接在虚拟机里安装x86的WIN，这样基本上就覆盖了最经典的使用场景。&lt;/p&gt;
&lt;p&gt;而最新的M1 MAC是ARM架构，且因为Rosetta不支持虚拟化，就导致了很多主流的虚拟机软件，类似Parallels都不支持在M1的MAC上安装x86架构的WIN10。&lt;/p&gt;
&lt;p&gt;所以一旦有需求要使用x86的Windows，那就不能使用那些主流的虚拟机软件了，只能找一些偏门的软件。&lt;/p&gt;
&lt;h1 id=&quot;2-介绍&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E4%BB%8B%E7%BB%8D&quot; aria-label=&quot;2 介绍 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 介绍&lt;/h1&gt;
&lt;p&gt;实际上可选的并不多，或者说最后我就只找到了&lt;code class=&quot;language-text&quot;&gt;QEMU&lt;/code&gt;，而在其基础上进行封装的&lt;code class=&quot;language-text&quot;&gt;UTM&lt;/code&gt;应该说是最佳选择了。&lt;/p&gt;
&lt;p&gt;相关链接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.qemu.org/contribute/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;QEMU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mac.getutm.app/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;UTM MAC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/utmapp/UTM&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;UTM Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/utmapp/UTM/wiki/Useful-tips&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;UTM Useful tips&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%AE%89%E8%A3%85&quot; aria-label=&quot;3 安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 安装&lt;/h1&gt;
&lt;p&gt;关于在MAC上安装UTM并安装虚拟操作系统的方法，参考这篇就够了：&lt;a href=&quot;https://github.com/utmapp/UTM/wiki/Install-Ubuntu-ARM64-on-Apple-M1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Install Ubuntu ARM64 on Apple M1&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;因为这篇讲的是如何安装&lt;code class=&quot;language-text&quot;&gt;ARM64&lt;/code&gt;架构的虚拟操作系统，因此对于需要安装&lt;code class=&quot;language-text&quot;&gt;x86&lt;/code&gt;虚拟系统的用户需要自行调整：&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol start=&quot;3&quot;&gt;
&lt;li&gt;In System, select the “ARM64 (aarch64)” architecture, and specify the amount of memory. At least half of your computer’s total memory is recommended for performance.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;在这里选择&lt;code class=&quot;language-text&quot;&gt;x86_64&lt;/code&gt;，而不是ARM64。其他都一致即可。最后不要忘记在虚拟机内安装：&lt;code class=&quot;language-text&quot;&gt;sudo apt install spice-vdagent spice-webdavd&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;4-文件共享&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E6%96%87%E4%BB%B6%E5%85%B1%E4%BA%AB&quot; aria-label=&quot;4 文件共享 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 文件共享&lt;/h1&gt;
&lt;p&gt;因为装过一次之后就没怎么使用过UTM了，而且也没打算装第二次。这里就留点之前的笔记：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;关闭虚拟机
在面板里选择共享目录
重开虚拟机
curl http://127.0.0.1:9843/ 查看是否有可访问内容
sudo apt install davfs2
mkdir -p /home/jonathan/mnt
sudo mount -t davfs -o uid=jonathan -o gid=jonathan http://127.0.0.1:9843/ /home/jonathan/mnt
sudo mount -t davfs http://127.0.0.1:9843/ /home/jonathan/mnt
skip username &amp;amp; password, no such setting

使用umount来卸载挂载盘
sudo umount /home/jonathan/mnt
会显示 target is busy
需要安装工具来查看使用者
sudo apt install psmisc
查看使用情况
fuser -mv /home/jonathan/mnt
杀掉使用者进程
fuser -kv /home/jonathan/mnt

自启动装载：
https://github.com/utmapp/UTM/wiki/Useful-tips#permanently-via-fstab

cat &amp;lt;&amp;lt; EOF | sudo tee -a /etc/fstab

# UMT webdav server
http://localhost:9843 /home/jonathan/mnt davfs _netdev,user,uid=jonathan,gid=jonathan 0 0
EOF

cat &amp;lt;&amp;lt; EOF | sudo tee -a /etc/davfs2/secrets

# fake credentials for UMT webdav server
/home/jonathan/mnt hello world
EOF

sudo mount /home/jonathan/mnt&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;5-端口转发&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E7%AB%AF%E5%8F%A3%E8%BD%AC%E5%8F%91&quot; aria-label=&quot;5 端口转发 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 端口转发&lt;/h1&gt;
&lt;p&gt;主要还是为了虚拟机和宿主机之间能像两台主机一样进行ssh连接：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;网络面板有个高级设置，勾选
下面会有个新建，使用TCP，然后guest（虚拟机）设置0.0.0.0端口22，主机（宿主机）设置127.0.0.1端口52222
重新启动虚拟机，然后自宿主机上进行ssh登录
ssh jonathan@localhost -p 52222&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[WIN10安装WSL]]></title><description><![CDATA[WIN10安装WSL相关笔记]]></description><link>https://xenojoshua.com/posts/2021/10/win10-wsl</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/10/win10-wsl</guid><pubDate>Mon, 04 Oct 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E8%B5%84%E6%BA%90&quot;&gt;2. 资源&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;之前在WIN10上有一些linux相关需求，因此安装过一次WSL2，这里稍微留点笔记。但因为这货实在是使用频率极低，大概率不会安装第二次，因此细节就不过多补充了，就留点link。&lt;/p&gt;
&lt;h1 id=&quot;2-资源&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E8%B5%84%E6%BA%90&quot; aria-label=&quot;2 资源 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 资源&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;安装步骤可以参考：&lt;a href=&quot;https://blog.csdn.net/yushuzhen2008/article/details/104944579&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;在Windows 10中启动WSL2 并安装Linux（ Ubuntu 为例）并运行docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WSL也有版本，从1升级到2可以参考：&lt;a href=&quot;https://ld246.com/article/1568615613388&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;win10 wsl1 转换为 wsl2 的方法及实际使用案例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WSL内核更新，&lt;a href=&quot;https://docs.microsoft.com/en-us/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;下载链接&lt;/a&gt;，参考：&lt;a href=&quot;https://blog.csdn.net/littlehaes/article/details/104879476&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;WSL 2 需要更新其内核组件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;网络问题：
&lt;ul&gt;
&lt;li&gt;很多时候我们会需要把WSL实例作为一个单独的主机来对待，那么就需要这个实例在局域网中有对应的入口，能够和WIN10相互通讯，这里有几篇可以看下：&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ohyee.cc/post/note_windows_redirect_wsl2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Windows重定向端口转发请求到WSL2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hexh250786313/Blog/issues/12&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;一口气搞定 WSL2 的网络问题 #12&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cn.desmoineshvaccompany.com/how-open-firewall-ports-windows-10&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;如何在WINDOWS 10中打开防火墙端口&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[MAC ARM 兼容性问题]]></title><description><![CDATA[MAC ARM CPU的兼容性问题]]></description><link>https://xenojoshua.com/posts/2021/10/mac-arm-issues</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/10/mac-arm-issues</guid><pubDate>Sun, 03 Oct 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%85%BC%E5%AE%B9%E6%80%A7%E9%97%AE%E9%A2%98&quot;&gt;2. 兼容性问题&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#brew&quot;&gt;brew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#docker&quot;&gt;docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#nodejs&quot;&gt;node.js&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#nvm&quot;&gt;nvm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dep&quot;&gt;dep&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;年头上更换的M1 MAC ARM架构，当时确实还是遇到了点兼容性问题的。当然全部都是编程方面的问题，不得不夸奖下&lt;code class=&quot;language-text&quot;&gt;Rosetta 2&lt;/code&gt;，确实强大。因为解决兼容性的时候遇到的一些问题的细节笔记已经丢失，所以这篇文章不会带太多细节，主要是一些指导性、方向性的解释。&lt;/p&gt;
&lt;h1 id=&quot;2-兼容性问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%85%BC%E5%AE%B9%E6%80%A7%E9%97%AE%E9%A2%98&quot; aria-label=&quot;2 兼容性问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 兼容性问题&lt;/h1&gt;
&lt;h2 id=&quot;brew&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#brew&quot; aria-label=&quot;brew permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;brew&lt;/h2&gt;
&lt;p&gt;brew也是分arm和x86的，按我目前的经验来说只要装一份arm的就够了，不需要保持两个brew命令同时存在。arm版本的安装操作可以参考：&lt;a href=&quot;https://segmentfault.com/a/1190000038879366&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;M1芯片Mac上Homebrew安装教程&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;docker&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#docker&quot; aria-label=&quot;docker permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;docker&lt;/h2&gt;
&lt;p&gt;在使用&lt;code class=&quot;language-text&quot;&gt;docker build&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;docker run&lt;/code&gt;的时候都要记得指定&lt;code class=&quot;language-text&quot;&gt;--platform&lt;/code&gt;来确定镜像是&lt;code class=&quot;language-text&quot;&gt;intel&lt;/code&gt;还是&lt;code class=&quot;language-text&quot;&gt;arm&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;linux/x86_64&lt;/li&gt;
&lt;li&gt;linux/arm64&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特别是run的时候，有的时候会默认去抓取intel的镜像，就导致启动的时候各种问题。&lt;/p&gt;
&lt;p&gt;此外还有一个问题，有一些动作比较慢的厂商，比如说&lt;code class=&quot;language-text&quot;&gt;couchbase&lt;/code&gt;迄今为止都没有arm的image。这就很头痛了，不过没什么好办法，只能慢慢等。&lt;/p&gt;
&lt;h2 id=&quot;nodejs&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#nodejs&quot; aria-label=&quot;nodejs permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;node.js&lt;/h2&gt;
&lt;p&gt;node的兼容性分两方面，一是node自身的平台及版本管理，另一个就是项目代码里的依赖包的兼容性问题。&lt;/p&gt;
&lt;h3 id=&quot;nvm&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#nvm&quot; aria-label=&quot;nvm permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;nvm&lt;/h3&gt;
&lt;p&gt;建议使用&lt;code class=&quot;language-text&quot;&gt;nvm&lt;/code&gt;来进行node的版本管理，官方文档里有关于MAC的相关问题指引：&lt;a href=&quot;https://github.com/nvm-sh/nvm#macos-troubleshooting&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;macOS Troubleshooting&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;node在&lt;code class=&quot;language-text&quot;&gt;v15&lt;/code&gt;之前的版本是没有arm二进制包的，所以arm的环境nvm安装会从源码开始安装，并得到arm版本的node：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; process.arch
arm64&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;January 2021: there are no pre-compiled NodeJS binaries for versions prior to 15.x for Apple’s new M1 chip (arm64 architecture).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;官方发布包地址：&lt;a href=&quot;https://nodejs.org/dist/latest-v16.x/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nodejs.org/dist/latest-v16.x&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;dep&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dep&quot; aria-label=&quot;dep permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;dep&lt;/h3&gt;
&lt;p&gt;因为node安装的时候是arm的，然后大量的dep包实际上也是没有arm的二进制包的，所以在编译的时候会遇到各式各样的问题（如果你安装的dep包的版本特别老的话，就更容易遇到，如果版本比较新的话，很多都已经制作了arm对应的binary）。&lt;/p&gt;
&lt;p&gt;这里可以按刚才的nvm官方文档里提到的，把整个command line bash环境改成intel的，来进行安装x86的node。这样dep包在安装的时候会和node保持一致，都是x86的，就会更少遇到问题。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Check what version you&apos;re running:&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
v14.15.4
&lt;span class=&quot;token comment&quot;&gt;# Check architecture of the `node` binary:&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; process.arch
arm64
&lt;span class=&quot;token comment&quot;&gt;# This confirms that the arch is for the M1 chip, which is causing the problems.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# So we need to uninstall it.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# We can&apos;t uninstall the version we are currently using, so switch to another version:&lt;/span&gt;
$ nvm &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; v12.20.1
&lt;span class=&quot;token comment&quot;&gt;# Now uninstall the version we want to replace:&lt;/span&gt;
$ nvm uninstall v14.15.4
&lt;span class=&quot;token comment&quot;&gt;# Launch a new zsh process under the 64-bit X86 architecture:&lt;/span&gt;
$ arch &lt;span class=&quot;token parameter variable&quot;&gt;-x86_64&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;zsh&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Install node using nvm. This should download the precompiled x64 binary:&lt;/span&gt;
$ nvm &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; v14.15.4
&lt;span class=&quot;token comment&quot;&gt;# Now check that the architecture is correct:&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; process.arch
x64
&lt;span class=&quot;token comment&quot;&gt;# It is now safe to return to the arm64 zsh process:&lt;/span&gt;
$ &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# We&apos;re back to a native shell:&lt;/span&gt;
$ arch
arm64
&lt;span class=&quot;token comment&quot;&gt;# And the new version is now available to use:&lt;/span&gt;
$ nvm use v14.15.4
Now using &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; v14.15.4 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;npm v6.14.10&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;dep包的安装问题就一个指导思想：&lt;code class=&quot;language-text&quot;&gt;更新dep包的版本，更新到有arm的binary的版本，就不会有问题了&lt;/code&gt;，切忌闷头在那边找源码编译的问题的解决办法。无他，主要是太浪费时间了。。。&lt;/p&gt;
&lt;p&gt;没什么感觉的可以看看这些，你就知道有多痛苦了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nodejs/build/issues/2474&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Apple silicon builds #2474&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nvm-sh/nvm/issues/2350#issuecomment-734132550&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nvm install node fails to install on macOS Big Sur M1 Chip #2350&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/lovell/sharp/issues/2460#issuecomment-811046375&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Can’t compile under Apple Silicon M1 arm64 #2460&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nodejs/node-gyp/issues/2296&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;fsevents issues on macOS with Apple Silicon ARM CPUs #2296&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nodejs/node-gyp/issues/2144&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;node-gyp rebuild is failing #2144&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[OSX LocateMe]]></title><description><![CDATA[如何在OSX上用命令行工具获得Location信息]]></description><link>https://xenojoshua.com/posts/2021/10/locateme</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/10/locateme</guid><pubDate>Sat, 02 Oct 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85&quot;&gt;2. 安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E4%BD%BF%E7%94%A8&quot;&gt;3. 使用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;locateme&lt;/code&gt;是一个命令行工具，能够调用osx系统自带的apple定位服务来给出经纬数据。&lt;/p&gt;
&lt;p&gt;Github：&lt;a href=&quot;https://github.com/netj/LocateMe&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;netj/LocateMe&lt;/a&gt;。下载站：&lt;a href=&quot;http://iharder.sourceforge.net/current/macosx/locateme/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;iHarder.net LocateMe&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Returns your computer’s location using Apple’s built-in geolocation services.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;2-安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85&quot; aria-label=&quot;2 安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 安装&lt;/h1&gt;
&lt;p&gt;可以从下载站下载软件包之后解压并放到bin下面，当然更推荐使用brew安装：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ brew update &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; locateme &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; locateme
/usr/local/bin/locateme&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这还没完，接下来要先使用一次locateme，会报错：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ locateme

&lt;span class=&quot;token number&quot;&gt;2021&lt;/span&gt;-08-31 &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;:47:01.299 locateme&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32912&lt;/span&gt;:640457&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;error code&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; kCLErrorLocationUnknown: Error &lt;span class=&quot;token assign-left variable&quot;&gt;Domain&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;kCLErrorDomain &lt;span class=&quot;token assign-left variable&quot;&gt;Code&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;(null)&quot;&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;2021&lt;/span&gt;-08-31 &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;:47:01.299 locateme&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32912&lt;/span&gt;:640457&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; Error: Error &lt;span class=&quot;token assign-left variable&quot;&gt;Domain&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;kCLErrorDomain &lt;span class=&quot;token assign-left variable&quot;&gt;Code&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;(null)&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后打开&lt;code class=&quot;language-text&quot;&gt;系统偏好设置 &gt; 安全性与隐私 &gt; 定位服务&lt;/code&gt;，勾选&lt;code class=&quot;language-text&quot;&gt;LocateMe&lt;/code&gt;。然后再尝试使用，应该就OK了：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ locateme

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;+XX.23453090,+XXX.4829305&lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;7&lt;/span&gt;&gt;&lt;/span&gt; +/- &lt;span class=&quot;token number&quot;&gt;65&lt;/span&gt;.00m &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;speed &lt;span class=&quot;token parameter variable&quot;&gt;-1.00&lt;/span&gt; mps / course -1.00&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; @ &lt;span class=&quot;token number&quot;&gt;2021&lt;/span&gt;/8/28 中国标准时间 XX:XX:XX&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;3 使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 使用&lt;/h1&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ locateme &lt;span class=&quot;token parameter variable&quot;&gt;-h&lt;/span&gt;
USAGE: locateme &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
Version: &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;.1
Outputs your current location using Apple&apos;s geolocation services.
  &lt;span class=&quot;token parameter variable&quot;&gt;-h&lt;/span&gt;          This &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt; message
  &lt;span class=&quot;token parameter variable&quot;&gt;-g&lt;/span&gt;          Generate a Google Map URL
  &lt;span class=&quot;token parameter variable&quot;&gt;-l&lt;/span&gt;          Generate long, multiline &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;   Generate a custom output with the following placeholders
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;LAT&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    Latitude as a floating point number
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;LON&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    Longitude as a floating point number
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ALT&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    Altitude &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; meters as a floating point number
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;SPD&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    Speed &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; meters per second as a floating point number
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;DIR&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    Direction &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; degrees from &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; north as a floating point number
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;HAC&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    Horizontal accuracy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; meters as a floating point number
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;VAC&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;    Vertical accuracy &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; meters as a floating point number
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;TIME&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;   Timestamp &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;with &lt;span class=&quot;token function&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; of the location fix
     &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;HOST&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;   Computer &lt;span class=&quot;token function&quot;&gt;hostname&lt;/span&gt;

Examples:

 Command: locateme &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lat={LAT},lon={LON}&quot;&lt;/span&gt;
 Output &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;lat&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12.34567&lt;/span&gt;,lon&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;98.76543&lt;/span&gt;

 Command: locateme &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;lat&gt;{LAT}&amp;lt;/lat&gt;&amp;lt;lon&gt;{LON}&amp;lt;/lon&gt;&amp;lt;alt&gt;{ALT}&amp;lt;/alt&gt;&quot;&lt;/span&gt;
 Output &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;lat&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12.3456&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;7&lt;/span&gt;&amp;lt;&lt;/span&gt;/lat&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;lon&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;98.7654&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;3&lt;/span&gt;&amp;lt;&lt;/span&gt;/lon&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;alt&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;3&lt;/span&gt;&amp;lt;&lt;/span&gt;/alt&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;一般这样用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ locateme &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;lat&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;:&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;{LAT}&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;,&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;lon&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;:&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;{LON}&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;}&quot;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;lat&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;XX.234463&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;lon&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;XXX.482957&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[高德地图 API]]></title><description><![CDATA[高德 API的使用]]></description><link>https://xenojoshua.com/posts/2021/09/amap-api</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/09/amap-api</guid><pubDate>Sat, 25 Sep 2021 03:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E8%B4%A6%E5%8F%B7%E7%94%B3%E8%AF%B7%E4%B8%8E%E5%87%86%E5%A4%87&quot;&gt;2. 账号申请与准备&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%B8%B8%E7%94%A8api&quot;&gt;3. 常用API&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E9%80%86%E5%9C%B0%E7%90%86%E7%BC%96%E7%A0%81&quot;&gt;3.1 逆地理编码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E5%9C%B0%E7%90%86%E7%BC%96%E7%A0%81&quot;&gt;3.2 地理编码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E9%80%89%E5%9D%80%E7%BB%84%E4%BB%B6&quot;&gt;3.3 选址组件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-%E5%A5%97%E8%B7%AF&quot;&gt;3.4 套路&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;地图服务主要就百度和高德两家，百度的API之前有接过，这次简单尝试下高德的API。基本上可以说大同小异，没什么本质差别。大概从一些客制化的方面会有些差别吧，主要是一些比较细节的功能方面。&lt;/p&gt;
&lt;p&gt;API主页：&lt;a href=&quot;https://lbs.amap.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;高德开放平台&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;2-账号申请与准备&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E8%B4%A6%E5%8F%B7%E7%94%B3%E8%AF%B7%E4%B8%8E%E5%87%86%E5%A4%87&quot; aria-label=&quot;2 账号申请与准备 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 账号申请与准备&lt;/h1&gt;
&lt;p&gt;首先进行账号注册，然后到&lt;a href=&quot;https://console.amap.com/dev/index&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;console&lt;/a&gt;创建API Key：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;创建应用：&lt;code class=&quot;language-text&quot;&gt;左边栏 应用管理 &gt; 我的应用&lt;/code&gt; =&gt; &lt;code class=&quot;language-text&quot;&gt;右上部按钮 创建新应用&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;添加Key：在创建出来的应用，&lt;code class=&quot;language-text&quot;&gt;右上部按钮 添加&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;这里注意，有两类KEY是比较常用的：
&lt;ul&gt;
&lt;li&gt;Web端(JS API)：这个KEY是用在浏览器内，或内嵌Web端的，e.g 地图选点组件&lt;/li&gt;
&lt;li&gt;Web服务：这个KEY是用在restful api调用的，e.g curl …&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;这两者的名字有一定的误导性，注意使用时的区分，一般可以把前者称为&lt;code class=&quot;language-text&quot;&gt;WebKey&lt;/code&gt;，后者称为&lt;code class=&quot;language-text&quot;&gt;ApiKey&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API Key是后续调用接口的关键，所以首先需要创建这两者。&lt;/p&gt;
&lt;h1 id=&quot;3-常用api&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%B8%B8%E7%94%A8api&quot; aria-label=&quot;3 常用api permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 常用API&lt;/h1&gt;
&lt;p&gt;全体Web API的列表可以到这里查阅文档：&lt;a href=&quot;https://lbs.amap.com/api/webservice/gettingstarted&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开发 &gt; Web服务 API &gt; 入门指南&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;31-逆地理编码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E9%80%86%E5%9C%B0%E7%90%86%E7%BC%96%E7%A0%81&quot; aria-label=&quot;31 逆地理编码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 逆地理编码&lt;/h2&gt;
&lt;p&gt;实际上就是根据经纬查找地点信息：&lt;a href=&quot;https://lbs.amap.com/api/webservice/guide/api/georegeo#regeo&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;文档&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://restapi.amap.com/v3/geocode/regeo?output=json&amp;amp;location=116.310003,39.991957&amp;amp;key=2e06f02c891a78a0b3860e75ebc8702b&amp;amp;radius=100&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;regeocode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;addressComponent&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;province&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京市&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;adcode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;110108&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;district&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;海淀区&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;towncode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;110108015000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;streetNumber&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5号&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;location&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;116.310454,39.992734&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;direction&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;东北&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;distance&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;94.5489&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;street&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;颐和园路&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;country&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;中国&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;township&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;燕园街道&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;businessAreas&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;building&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京大学&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;科教文化服务;学校;高等院校&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;neighborhood&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京大学&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;科教文化服务;学校;高等院校&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;citycode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;010&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;formatted_address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京市海淀区燕园街道北京大学&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;infocode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;这个API返回的city是空数组，不太清楚是不是因为直辖市的原因&lt;/li&gt;
&lt;li&gt;注意这里的&lt;code class=&quot;language-text&quot;&gt;formatted_address&lt;/code&gt;，后面可以结合另一个API使用&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;32-地理编码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E5%9C%B0%E7%90%86%E7%BC%96%E7%A0%81&quot; aria-label=&quot;32 地理编码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 地理编码&lt;/h2&gt;
&lt;p&gt;可以根据3.1里提到的&lt;code class=&quot;language-text&quot;&gt;formatted_address&lt;/code&gt;来查找具体的地点信息：&lt;a href=&quot;https://lbs.amap.com/api/webservice/guide/api/georegeo#geo&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;文档&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://restapi.amap.com/v3/geocode/geo?key=2e06f02c891a78a0b3860e75ebc8702b&amp;amp;address=北京市海淀区燕园街道北京大学&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;info&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;infocode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;count&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;geocodes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;formatted_address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京市海淀区北京大学&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;country&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;中国&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;province&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京市&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;citycode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;010&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;city&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京市&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;district&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;海淀区&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;township&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;neighborhood&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;building&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;adcode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;110108&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;street&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;location&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;116.305469,39.989481&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;level&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;兴趣点&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;33-选址组件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E9%80%89%E5%9D%80%E7%BB%84%E4%BB%B6&quot; aria-label=&quot;33 选址组件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 选址组件&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;开发 &gt; 地图组件 &gt; 开发指南 &gt; 选址组件&lt;/code&gt;：&lt;a href=&quot;https://lbs.amap.com/api/lightmap/guide/picker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;文档&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;需要注意，这个组件和刚才的2个API不同，刚才的2个API使用的是&lt;code class=&quot;language-text&quot;&gt;Web服务&lt;/code&gt;API Key，而这个组件则需要使用&lt;code class=&quot;language-text&quot;&gt;Web端(JS API)&lt;/code&gt;API Key。千万不要搞错了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/09/amap-api/amap-location-picker.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;内嵌一个iframe到web页面上之后，就可以通过文档中的代码进行初始化。当用户点击下面的地址列表中的某一个地址时，就会触发事件，返回给开发者以下信息：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;颐和园路5号&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;location&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;116.310003,39.991957&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京大学&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;34-套路&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-%E5%A5%97%E8%B7%AF&quot; aria-label=&quot;34 套路 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 套路&lt;/h2&gt;
&lt;p&gt;一般来说可以这样做：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在app或web中嵌入&lt;code class=&quot;language-text&quot;&gt;3.3 选址组件&lt;/code&gt;，然后获得用户所选地点的经纬度&lt;/li&gt;
&lt;li&gt;然后将经纬度传入&lt;code class=&quot;language-text&quot;&gt;3.1 逆地理编码&lt;/code&gt;获得到&lt;code class=&quot;language-text&quot;&gt;formatted_address&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;最后通过&lt;code class=&quot;language-text&quot;&gt;3.2 地理编码&lt;/code&gt;来获得地点的省市等信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根据3.1和3.2两者的返回，可以拼装出完整的地点信息。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Weather API]]></title><description><![CDATA[一些关于天气的API]]></description><link>https://xenojoshua.com/posts/2021/09/weather-api</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/09/weather-api</guid><pubDate>Sat, 25 Sep 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-openweather&quot;&gt;2. OpenWeather&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-nowapi&quot;&gt;3. Nowapi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;平时做一些和生活、日常应用相关的功能时，偶尔会有些需要获取天气信息的功能。所以简单了解了点天气相关的API。之前在知乎上搜了下，找到一个topic：&lt;a href=&quot;https://www.zhihu.com/question/20575288&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;网上的天气 API 哪一个更加可靠？&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;不过总感觉国内的API一般都不咋的，所以兴趣不大，也没怎么尝试。下面简单介绍下尝试过的两个。&lt;/p&gt;
&lt;h1 id=&quot;2-openweather&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-openweather&quot; aria-label=&quot;2 openweather permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. OpenWeather&lt;/h1&gt;
&lt;p&gt;国外推荐使用这个：&lt;a href=&quot;https://openweathermap.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OpenWeather&lt;/a&gt;。注册之后就会获得token / API Key，基本上调用API也只需要这个token。&lt;/p&gt;
&lt;p&gt;价格：&lt;a href=&quot;https://openweathermap.org/price&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Pricing&lt;/a&gt;。免费版的账号限制：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;60 calls/minute
1,000,000 calls/month&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;而且免费版的账号有一些API是无法调用的，比如说查询历史天气信息。&lt;/p&gt;
&lt;p&gt;可供使用的API清单：&lt;a href=&quot;https://openweathermap.org/api&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Weather API&lt;/a&gt;。基本上和天气相关你想得到的，都能得到满足。下面会举几个常用的API例子，注意所有的API返回的温度都是开氏温度，需要提供如下参数才可以转为摄氏温度：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;name&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;mandatory&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;units&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;optional&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Units of measurement. standard, metric and imperial units are available. If you do not use the units parameter, standard units will be applied by default.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;Temperature is available in Fahrenheit, Celsius and Kelvin units.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;For temperature in Fahrenheit use units=imperial&lt;/li&gt;
&lt;li&gt;For temperature in &lt;code class=&quot;language-text&quot;&gt;Celsius&lt;/code&gt; use units=&lt;code class=&quot;language-text&quot;&gt;metric&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Temperature in Kelvin is used by default, no need to use units parameter in API call&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Current Weather Data&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.openweathermap.org/data/2.5/weather?q={city name}&amp;amp;appid={API key}&quot;&lt;/span&gt;

$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.openweathermap.org/data/2.5/weather?q={city name},{state code}&amp;amp;appid={API key}&quot;&lt;/span&gt;

$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.openweathermap.org/data/2.5/weather?q={city name},{state code},{country code}&amp;amp;appid={API key}&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;coord&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;lon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;-122.08&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;lat&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;37.39&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Clear&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;clear sky&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;01d&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;base&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;stations&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;282.55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;feels_like&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;281.86&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;temp_min&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;280.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;temp_max&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;284.26&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;pressure&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1023&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;humidity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;visibility&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16093&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;wind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;speed&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;deg&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;350&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;clouds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;all&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;dt&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1560350645&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;sys&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5122&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0139&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;country&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;US&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sunrise&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1560343627&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sunset&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1560396563&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;timezone&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;-25200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;420006353&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Mountain View&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;cod&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Historical weather API&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://history.openweathermap.org/data/2.5/history/city?q={city ID},{country code}&amp;amp;type=hour&amp;amp;start={start}&amp;amp;end={end}&amp;amp;appid={API key}&quot;&lt;/span&gt;

$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://history.openweathermap.org/data/2.5/history/city?q={city ID},{country code}&amp;amp;type=hour&amp;amp;start={start}&amp;amp;cnt={cnt}&amp;amp;appid={API key}&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;cod&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;200&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;city_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2885679&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;calctime&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0823&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;cnt&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;list&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;266.052&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp_min&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;266.052&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp_max&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;266.052&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;pressure&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;957.86&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;sea_level&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1039.34&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;grnd_level&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;957.86&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;humidity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;speed&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;deg&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;139.502&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;clouds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;all&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Clear&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Sky is Clear&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;01n&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;dt&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1485722804&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;263.847&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp_min&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;263.847&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp_max&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;263.847&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;pressure&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;955.78&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;sea_level&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1037.43&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;grnd_level&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;955.78&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;humidity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;91&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;speed&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.49&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;deg&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;159&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;clouds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;all&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Clear&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Sky is Clear&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;01n&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;dt&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1485749608&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;274.9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;pressure&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1019&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp_min&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;274.15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;temp_max&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;275.15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;humidity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;88&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;speed&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;deg&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;clouds&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;all&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;76&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Rain&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;light rain&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10d&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;dt&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1485773778&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-nowapi&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-nowapi&quot; aria-label=&quot;3 nowapi permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Nowapi&lt;/h1&gt;
&lt;p&gt;偶然搜到的这个API，国内公司。准确度暂时没有认真校对过，这个存疑，有需要用的需要认真看下。&lt;/p&gt;
&lt;p&gt;这家公司做的API还相当多，全部列表在这里：&lt;a href=&quot;https://www.nowapi.com/api&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Nowapi&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;天气API主要有下面这几个接口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;天气预报(整合版)&lt;/li&gt;
&lt;li&gt;天气预报(5-7天)&lt;/li&gt;
&lt;li&gt;实时天气&lt;/li&gt;
&lt;li&gt;实时天气(批量)&lt;/li&gt;
&lt;li&gt;历史天气&lt;/li&gt;
&lt;li&gt;PM2.5&lt;/li&gt;
&lt;li&gt;AQI生活指数(5-7天)&lt;/li&gt;
&lt;li&gt;城市列表天气类型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注册账号之后在后台就可以看到自己的&lt;code class=&quot;language-text&quot;&gt;AppKey&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;Sign&lt;/code&gt;，这两个是用来调API的。&lt;/p&gt;
&lt;p&gt;付费方面主要有两种形式：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;按API调用频次分价格段的包月&lt;/li&gt;
&lt;li&gt;按API实际使用次数购买次数&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;价格可以说相当亲民，轻度使用￥10买个15000次可以用很久了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;包月&lt;/strong&gt;
&lt;img src=&quot;/media/posts/2021/09/weather-api/nowapi-time.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;买次数&lt;/strong&gt;
&lt;img src=&quot;/media/posts/2021/09/weather-api/nowapi-count.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;选两个API看下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实时天气&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; https://sapi.k780.com/?app&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;weather.today&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;weaId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;appkey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10003&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;b59bc3ef6191eb9f747dd4e83c99f2a4&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;json &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;示例中sign会不定期调整&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;success&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;weaid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;days&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2014-07-30&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;week&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;星期三&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;cityno&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;beijing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;citynm&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;cityid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;101010100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;temperature&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;31℃/24℃&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*当日温度区间 (注: 夜间只有一个温度如24℃/24℃)*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;temperature_curr&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;21℃&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*当前温度*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;humidity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;50%&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*湿度*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;aqi&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*pm2.5 说明详见weather.pm25*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;多云转晴&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*天气*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;weather_icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://api.k780.com/upload/weather/d/1.gif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*气象图标 全部气象图标下载*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;weather_icon1&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*无意义不必理会*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;wind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;微风&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*风向*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;winp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;小于3级&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*风力*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;temp_high&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;31&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*最高温度*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;temp_low&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;24&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*最低温度*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;humi_high&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;87.8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*最大湿度 [历史遗留栏位不再更新]*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;humi_low&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;75.2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*最小湿度 [历史遗留栏位不再更新]*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;weatid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*天气ID，可对照weather.wtype接口中weaid*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;weatid1&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*无意义不必理会*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;windid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*风向ID(暂无对照表)*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;winpid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*风力ID(暂无对照表)*/&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;weather_iconid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/*气象图标编号,对应weather_icon 1.gif*/&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;历史天气&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; https://sapi.k780.com/?app&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;weather.history&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;weaId&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2015&lt;/span&gt;-07-20&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;appkey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10003&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;sign&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;b59bc3ef6191eb9f747dd4e83c99f2a4&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;json&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;success&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;result&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weaid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;week&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;星期一&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;cityno&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;beijing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;citynm&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;cityid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;101010100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*气象编号*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;uptime&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2015-07-20 00:50:00&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*更新时间*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;temperature&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22℃&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*该时段温度*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;humidity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;97%&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*该时段湿度*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;aqi&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;101&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*PM2.5 AQI*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;晴&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*该时段天气*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather_icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://api.k780.com/upload/weather/d/0.gif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*时段气象图标 全部气象图标下载*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;东北风&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*该时段风向*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;winp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1级&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*该时段风力*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*温度*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weatid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*天气编号*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;windid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;13&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*风向编号*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;winpid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;201&quot;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*风力编号*/&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather_iconid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/*气象图标编号,对应weather_icon 0.gif*/&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weaid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;week&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;星期一&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;cityno&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;beijing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;citynm&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;北京&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;cityid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;101010100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;uptime&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2015-07-20 01:50:00&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;temperature&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22℃&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;humidity&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;99%&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;aqi&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;101&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;晴&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weather_icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http://api.k780.com/upload/weather/d/0.gif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;东北风&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;winp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1级&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;22&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;weatid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;windid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;13&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;winpid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;201&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Vegeta Notes]]></title><description><![CDATA[Vegeta的使用方法]]></description><link>https://xenojoshua.com/posts/2021/09/vegeta-notes</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/09/vegeta-notes</guid><pubDate>Sat, 11 Sep 2021 03:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%B7%A5%E5%85%B7%E9%80%89%E6%8B%A9&quot;&gt;1. 工具选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%90%8E%E7%AB%AF%E7%A4%BA%E4%BE%8B&quot;&gt;2. 后端示例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-vegeta-command&quot;&gt;3. vegeta command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-vegeta-attack&quot;&gt;4. vegeta attack&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-vegeta-attack-target-from-stdin&quot;&gt;4.1 vegeta attack: target from stdin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-vegeta-attack-target-from-file&quot;&gt;4.2 vegeta attack: target from file&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-vegeta-plot&quot;&gt;5. vegeta plot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-vegeta-report&quot;&gt;6. vegeta report&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-vegeta-encode&quot;&gt;7. vegeta encode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-others&quot;&gt;8. Others&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#81-%E5%8A%A8%E6%80%81targets&quot;&gt;8.1 动态targets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#82-%E5%88%86%E5%B8%83%E5%BC%8F%E5%8E%8B%E6%B5%8B&quot;&gt;8.2 分布式压测&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#83-%E5%8E%8B%E6%B5%8B%E5%AE%9E%E6%97%B6%E5%88%86%E6%9E%90&quot;&gt;8.3 压测实时分析&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-工具选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%B7%A5%E5%85%B7%E9%80%89%E6%8B%A9&quot; aria-label=&quot;1 工具选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 工具选择&lt;/h1&gt;
&lt;p&gt;压力测试也是后端工作中比较多见的需求。一般来说，针对简单的HTTP请求，用得比较多的是：&lt;a href=&quot;https://httpd.apache.org/docs/2.4/programs/ab.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ab - Apache HTTP server benchmarking tool&lt;/a&gt; &amp;#x26; &lt;a href=&quot;https://github.com/wg/wrk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;wg/wrk&lt;/a&gt;。这两款都是使用C语言进行编写的工具，性能有十分保障。&lt;/p&gt;
&lt;p&gt;但日常工作中，我们的压测还有一些灵活的需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;压测的目标不一定是单个的API&lt;/li&gt;
&lt;li&gt;压测的时长和速率需要能调节&lt;/li&gt;
&lt;li&gt;压测的结果要能快速展示，包括文字和graph两种形式&lt;/li&gt;
&lt;li&gt;压测的结果要能进行存储，以使用其他软件进行拓展研究&lt;/li&gt;
&lt;li&gt;压测要能以client端分布式的方式进行，以保证在制造巨量的请求时，可以使用多台client进行联合测试，且测试结果可以融合归一进行分析&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;以上的几点需求，在ab和wrk中都不能完全满足，特别是分布式测试这点，基本上没见过市面上有哪个软件能够很好做到。&lt;/p&gt;
&lt;p&gt;这里就要介绍下今天的主角了：&lt;a href=&quot;https://github.com/tsenart/vegeta&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;tsenart/vegeta&lt;/a&gt;。这款工具是使用golang编写的压测工具，由于golang非常优秀的goroutine，这款工具的表现几乎不逊色于c语言编写的几位前辈。&lt;/p&gt;
&lt;p&gt;安装：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ brew update &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; vegeta&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2-后端示例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%90%8E%E7%AB%AF%E7%A4%BA%E4%BE%8B&quot; aria-label=&quot;2 后端示例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 后端示例&lt;/h1&gt;
&lt;p&gt;本文会进行一些范例演示，所有的vegeta命令所针对的后端服务器都使用如下代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; express &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;express&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; app &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;express&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;express&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;express&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;urlencoded&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; extended&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/get&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/get&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    query&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/post&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    method&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;POST&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    path&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/post&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    data&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; req&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;listen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Server listening at http://localhost:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;port&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该服务器仅只有两个API：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;http://localhost:5000/get&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;http://localhost:5000/post&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两个API会在收到请求后，在console中打印出该请求的所有信息。&lt;/p&gt;
&lt;h1 id=&quot;3-vegeta-command&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-vegeta-command&quot; aria-label=&quot;3 vegeta command permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. vegeta command&lt;/h1&gt;
&lt;p&gt;vegeta命令包含多个功能，在运行的时候，需要额外提供一个子命令，来明确目前运行的时候具体要做什么：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;attack：压测命令&lt;/li&gt;
&lt;li&gt;encode：转码命令，将压测输出的结果集从默认格式转成其他的格式（json等）&lt;/li&gt;
&lt;li&gt;plot：graph命令，将压测输出的结果生成graph html，以供查看&lt;/li&gt;
&lt;li&gt;report：报告命令，将压测输出的结果生成文字形式的report&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;vegeta使用*nix pipeline非常重，很多参数的输入和结果的输出都默认使用&lt;code class=&quot;language-text&quot;&gt;stdin&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;stdout&lt;/code&gt;，所以非常适合多个命令进行前后管道顺序执行。&lt;/p&gt;
&lt;p&gt;另外需要提一点，vegeta命令中提供的所有文件的路径，都必须以当前的工作路径（cwd）为基准。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET ...&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta attack &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;. &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta report&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-vegeta-attack&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-vegeta-attack&quot; aria-label=&quot;4 vegeta attack permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. vegeta attack&lt;/h1&gt;
&lt;p&gt;该命令用以发起压测，官方文档：&lt;a href=&quot;https://github.com/tsenart/vegeta#attack-command&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;。有几个option需要简单说明下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-targets&lt;/code&gt;：该option指定attack的目标是什么，默认读取stdin的输入，也可以提供一个文件路径，让vegeta读取其文本内容来获取目标&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-format&lt;/code&gt;：该option一般使用&lt;code class=&quot;language-text&quot;&gt;http&lt;/code&gt;，表示target给的内容必须按&lt;a href=&quot;https://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;RFC 2616&lt;/a&gt;的格式提供：&lt;code class=&quot;language-text&quot;&gt;&apos;GET http://localhost:5000/...&apos;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-header&lt;/code&gt;：该option可以提供多个，每个option表示额外提供一个header&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-body&lt;/code&gt;：该option用来指定post body的数据文件，注意，如果在targets里也提供了&lt;code class=&quot;language-text&quot;&gt;@/body/file/path&lt;/code&gt;则以target里的为准，当前option提供的body会被忽略&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-timeout&lt;/code&gt;：该option表示每个http请求的超时时长，默认为0表示无超时&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-workers&lt;/code&gt;：该option用来指定vegeta刚启动时需要启动的workers数量，后续实际workers数值会根据需求自行上升以满足rate的要求&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-max-workers&lt;/code&gt;：该option用来限制attack时的最高并发数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-duration&lt;/code&gt;：该option用来控制测试时长，使用字符串形式来提供数值：&lt;code class=&quot;language-text&quot;&gt;5s&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-rate&lt;/code&gt;：该option用来控制请求并发速率
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;5/s&lt;/code&gt;表示每秒vegeta会一共发出5个请求（vegeta会启动补充worker，如果速度设置很高的话）&lt;/li&gt;
&lt;li&gt;设置为0表示无限制，vegeta会尽可能快地发出请求&lt;/li&gt;
&lt;li&gt;设置为0的时候需要和&lt;code class=&quot;language-text&quot;&gt;max-workers&lt;/code&gt;配合使用，来行成一个固定的并发速率，否则可能会快速耗尽系统资源&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;41-vegeta-attack-target-from-stdin&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-vegeta-attack-target-from-stdin&quot; aria-label=&quot;41 vegeta attack target from stdin permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 vegeta attack: target from stdin&lt;/h2&gt;
&lt;p&gt;如下命令启动5秒的测试，并每秒发送5个请求，最后以文字形式输出报告。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;vegeta attack&lt;/code&gt;从自己的stdin读取&lt;code class=&quot;language-text&quot;&gt;echo&lt;/code&gt;的字符串作为target进行压测&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;vegeta report&lt;/code&gt;从自己的stdin读取上一个命令&lt;code class=&quot;language-text&quot;&gt;vegeta attack&lt;/code&gt;的stdout，来获取数据进行处理&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;GET http://localhost:5000/get?get_key=get_val&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    vegeta attack &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;token parameter variable&quot;&gt;-duration&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;5s &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;token parameter variable&quot;&gt;-rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;/s &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;token parameter variable&quot;&gt;-format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
        &lt;span class=&quot;token parameter variable&quot;&gt;-header&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Cache-Control: no-cache&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
            vegeta report &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;text&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;服务端输出：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Server listening at http://localhost:5000
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;0&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;1&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;2&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;3&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;4&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;5&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;6&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;7&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;8&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;9&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;10&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;11&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;12&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;13&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;14&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;15&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;16&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;17&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;18&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;19&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;20&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;21&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;22&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;23&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-vegeta-seq&quot;:&quot;24&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;report：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Requests      [total, rate, throughput]         25, 5.21, 5.21
Duration      [total, attack, wait]             4.799s, 4.798s, 1.073ms
Latencies     [min, mean, 50, 90, 95, 99, max]  1.023ms, 1.57ms, 1.386ms, 1.97ms, 2.819ms, 4.442ms, 4.442ms
Bytes In      [total, mean]                     6762, 270.48
Bytes Out     [total, mean]                     736, 29.44
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:25  
Error Set:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;42-vegeta-attack-target-from-file&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-vegeta-attack-target-from-file&quot; aria-label=&quot;42 vegeta attack target from file permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 vegeta attack: target from file&lt;/h2&gt;
&lt;p&gt;如下命令会启动持续5秒的测试，并每秒发送5个请求，请求内容来自&lt;code class=&quot;language-text&quot;&gt;targets.txt&lt;/code&gt;文件的内容，最后以文字形式输出报：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;vegeta attack &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-targets&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;./vegeta/targets.txt &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-duration&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;5s &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;/s &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-format&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-header&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Cache-Control: no-cache&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
        vegeta report &lt;span class=&quot;token parameter variable&quot;&gt;-type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;text&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;targets.txt&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;GET http://localhost:5000/get?get_key=get_val
X-Add-Get-ID1: 78
X-Add-Get-ID2: 88

POST http://localhost:5000/post?post_key1=post_val
X-Add-Post-ID: 199
Content-Type: application/json
@./vegeta/postdata.json

POST http://localhost:5000/post?post_key2=post_val
X-Add-Post-ID: 299
Content-Type: application/json
@./vegeta/postdata.json&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;postdata.json&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;postdata&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;a&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;b&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;vegeta发送的请求会以targets.txt内列的target一个个请求发送下去&lt;/li&gt;
&lt;li&gt;每个target下面可以附带额外的header，不限数量，每行一个header&lt;/li&gt;
&lt;li&gt;POST的target可以在下面带上一行&lt;code class=&quot;language-text&quot;&gt;@/body/file/path&lt;/code&gt;格式的文本，表示读取该位置的文件，作为post的body使用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;服务端输出：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Server listening at http://localhost:5000
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;0&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;1&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;2&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;3&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;4&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;5&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;6&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;7&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;8&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;9&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;10&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;11&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;12&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;13&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;14&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;15&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;16&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;17&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;18&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;19&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;20&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;21&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;199&quot;,&quot;x-vegeta-seq&quot;:&quot;22&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;POST&quot;,&quot;path&quot;:&quot;/post&quot;,&quot;data&quot;:{&quot;postdata&quot;:{&quot;a&quot;:1,&quot;b&quot;:2}},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;content-length&quot;:&quot;46&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;content-type&quot;:&quot;application/json&quot;,&quot;x-add-post-id&quot;:&quot;299&quot;,&quot;x-vegeta-seq&quot;:&quot;23&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}
{&quot;method&quot;:&quot;GET&quot;,&quot;path&quot;:&quot;/get&quot;,&quot;query&quot;:{&quot;get_key&quot;:&quot;get_val&quot;},&quot;headers&quot;:{&quot;host&quot;:&quot;localhost:5000&quot;,&quot;user-agent&quot;:&quot;Go-http-client/1.1&quot;,&quot;cache-control&quot;:&quot;no-cache&quot;,&quot;x-add-get-id1&quot;:&quot;78&quot;,&quot;x-add-get-id2&quot;:&quot;88&quot;,&quot;x-vegeta-seq&quot;:&quot;24&quot;,&quot;accept-encoding&quot;:&quot;gzip&quot;}}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到，根据我们的option设置，一共是25个请求&lt;code class=&quot;language-text&quot;&gt;5s * 5/s&lt;/code&gt;。然后请求和targets.txt里指定的一样，每次都是按1个GET2个POST这样的顺序发送。&lt;code class=&quot;language-text&quot;&gt;3*8=24&lt;/code&gt;之后，正好还有一个待发的，因此最后就是一个GET。&lt;/p&gt;
&lt;p&gt;report：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Requests      [total, rate, throughput]         25, 5.21, 5.21
Duration      [total, attack, wait]             4.802s, 4.801s, 1.344ms
Latencies     [min, mean, 50, 90, 95, 99, max]  1.093ms, 1.687ms, 1.379ms, 1.769ms, 3.979ms, 5.077ms, 5.077ms
Bytes In      [total, mean]                     6762, 270.48
Bytes Out     [total, mean]                     736, 29.44
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:25  
Error Set:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;5-vegeta-plot&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-vegeta-plot&quot; aria-label=&quot;5 vegeta plot permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. vegeta plot&lt;/h1&gt;
&lt;p&gt;该命令用来将测试结果输出成graph的html，官方文档：&lt;a href=&quot;https://github.com/tsenart/vegeta#plot-command&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;。option基本不需要调整。这里需要注意，输出的graph只含&lt;code class=&quot;language-text&quot;&gt;latency&lt;/code&gt;，不含其它信息。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/09/vegeta-notes/vegeta-plot.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GET http://:80&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta attack &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;50qps &lt;span class=&quot;token parameter variable&quot;&gt;-rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-duration&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;5s &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; results.50qps.bin
$ &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; results.50qps.bin &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta plot &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; plot.50qps.html
$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GET http://:80&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta attack &lt;span class=&quot;token parameter variable&quot;&gt;-name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;100qps &lt;span class=&quot;token parameter variable&quot;&gt;-rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-duration&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;5s &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; results.100qps.bin
$ vegeta plot results.50qps.bin results.100qps.bin &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; plot.html&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;6-vegeta-report&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-vegeta-report&quot; aria-label=&quot;6 vegeta report permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. vegeta report&lt;/h1&gt;
&lt;p&gt;该明星用来将测试结果转换为报告，官方文档：&lt;a href=&quot;https://github.com/tsenart/vegeta#report-command&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;options：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--type&lt;/code&gt;：报告类型：&lt;code class=&quot;language-text&quot;&gt;text | json | hist[buckets] | hdrplot&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--every&lt;/code&gt;：报告间隔，设置该值会在测试中也渐次输出report，e.g &lt;code class=&quot;language-text&quot;&gt;--every=1s&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GET http://:80&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta attack &lt;span class=&quot;token parameter variable&quot;&gt;-rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;/s &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; results.gob
$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GET http://:80&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta attack &lt;span class=&quot;token parameter variable&quot;&gt;-rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;/s &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta encode &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; results.json
$ vegeta report results.*&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;7-vegeta-encode&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-vegeta-encode&quot; aria-label=&quot;7 vegeta encode permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. vegeta encode&lt;/h1&gt;
&lt;p&gt;该命令用来将测试结果转换成其他格式，默认输出自vegeta attack的格式是&lt;code class=&quot;language-text&quot;&gt;gob&lt;/code&gt;，官方文档：&lt;a href=&quot;https://github.com/tsenart/vegeta#encode-command&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;可以转换为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gob&lt;/li&gt;
&lt;li&gt;json&lt;/li&gt;
&lt;li&gt;csv&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用option&lt;code class=&quot;language-text&quot;&gt;--to&lt;/code&gt;来进行指定。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;GET http://:80&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta attack &lt;span class=&quot;token parameter variable&quot;&gt;-rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;/s &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; results.gob
$ &lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; results.gob &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta encode &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;del(.body)&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; vegeta encode &lt;span class=&quot;token parameter variable&quot;&gt;-to&lt;/span&gt; gob&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;8-others&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-others&quot; aria-label=&quot;8 others permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. Others&lt;/h1&gt;
&lt;h2 id=&quot;81-动态targets&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#81-%E5%8A%A8%E6%80%81targets&quot; aria-label=&quot;81 动态targets permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1 动态targets&lt;/h2&gt;
&lt;p&gt;根据官方instruction &lt;a href=&quot;https://github.com/tsenart/vegeta#usage-generated-targets&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Usage: Generated targets&lt;/a&gt;，可以动态生成压测的target。另外也可以通过&lt;code class=&quot;language-text&quot;&gt;vegeta attack -targets=...&lt;/code&gt;的方式提供测试目标文件，然后在该文件中列出期望的用户行为来进行拟真测试。&lt;/p&gt;
&lt;h2 id=&quot;82-分布式压测&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#82-%E5%88%86%E5%B8%83%E5%BC%8F%E5%8E%8B%E6%B5%8B&quot; aria-label=&quot;82 分布式压测 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2 分布式压测&lt;/h2&gt;
&lt;p&gt;这也是在开篇的时候提到的比较重要的一点需求：&lt;a href=&quot;https://github.com/tsenart/vegeta#usage-distributed-attacks&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Usage: Distributed attacks&lt;/a&gt;。可以按该官方指引在多台client上进行分布式压测，vegeta有一点很好的是可以组合各个client生成出来的&lt;code class=&quot;language-text&quot;&gt;gob&lt;/code&gt;文件，来生成一份最终的结果report。&lt;/p&gt;
&lt;h2 id=&quot;83-压测实时分析&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#83-%E5%8E%8B%E6%B5%8B%E5%AE%9E%E6%97%B6%E5%88%86%E6%9E%90&quot; aria-label=&quot;83 压测实时分析 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.3 压测实时分析&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/tsenart/vegeta#usage-real-time-analysis&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Usage: Real-time Analysis&lt;/a&gt;，可以查看压测实时的运行状态。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Gatsby Notes]]></title><description><![CDATA[Gatsby系统简述，及技术剖析]]></description><link>https://xenojoshua.com/posts/2021/09/gatsby-notes</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/09/gatsby-notes</guid><pubDate>Sun, 05 Sep 2021 03:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-wordpress---jekyll---gatsby&quot;&gt;1. Wordpress -&gt; Jekyll -&gt; Gatsby&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E9%80%89%E6%8B%A9starter&quot;&gt;2. 选择Starter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%A6%82%E4%BD%95%E7%AE%A1%E7%90%86%E4%BD%A0%E7%9A%84repo&quot;&gt;3. 如何管理你的repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-gatsby%E6%8A%80%E6%9C%AF%E5%BC%80%E5%8F%91&quot;&gt;4. Gatsby技术开发&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-config&quot;&gt;4.1 Config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-structure&quot;&gt;4.2 Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-graphql&quot;&gt;4.3 Graphql&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#431-page-query&quot;&gt;4.3.1 Page query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#432-static-query&quot;&gt;4.3.2 Static query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-wordpress---jekyll---gatsby&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-wordpress---jekyll---gatsby&quot; aria-label=&quot;1 wordpress   jekyll   gatsby permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. Wordpress -&gt; Jekyll -&gt; Gatsby&lt;/h1&gt;
&lt;p&gt;开博也不算特别早，11年开始的，正好10年，当时基本上没什么选择：&lt;code class=&quot;language-text&quot;&gt;Godaddy + VPS + Wordpress&lt;/code&gt;。后来github搞出了免费的page，加上jekyll提供了不错的静态化工具，也就顺理成章换成了&lt;code class=&quot;language-text&quot;&gt;Jekyll + Github Page&lt;/code&gt;。第一次更换还算比较简单，Wordpress的旧post全部转换成静态html，所有资源都是内嵌的，然后放到jekyll的一个文件夹里就完事了，然后后续使用jekyll来编译md文件成静态html，后续的post也能便捷接续上。&lt;/p&gt;
&lt;p&gt;断断续续也写了点关于jekyll blog的维护文章：&lt;a href=&quot;https://xenojoshua.com/posts/2017/09/jekyll-installation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Jekyll的安装&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;不过后续使用jekyll也遇到了一些问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ruby技术栈，不熟悉，导致要做一些customization很不方便&lt;/li&gt;
&lt;li&gt;gem有的时候总是会遇到安装问题&lt;/li&gt;
&lt;li&gt;jekyll的theme定了一个之后基本上就没办法换成其他的了（这个问题在gatsby上也有，后面会提供解决方法），然后我之前选的一款theme比较老，就导致了很多问题，比如说手机浏览不友好等&lt;/li&gt;
&lt;li&gt;一些比较现代化的website应该有的功能都没有，比如说浏览器兼容性等，其实主要还是因为上一条&lt;/li&gt;
&lt;li&gt;功能相对来说比较简单，毕竟jekyll真的是一款很纯粹的静态化站点工具&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;说到底，关键的问题还是技术栈，如果是基于node的话，很多问题其实我都可以自己解决。 于是今年就想换到node技术栈，看了下，其实也就&lt;a href=&quot;https://www.gatsbyjs.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gatsby&lt;/a&gt;比较强大点。&lt;/p&gt;
&lt;p&gt;这里需要澄清一点：Gatsby是一个&lt;code class=&quot;language-text&quot;&gt;建站工具集&lt;/code&gt;，而不是Jekyll这样的&lt;code class=&quot;language-text&quot;&gt;静态站点工具&lt;/code&gt;。这两者是有本质区别的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jekyll只能用来做&lt;code class=&quot;language-text&quot;&gt;静态网站&lt;/code&gt;，也就是说将md内容构建成一系列的静态html内容，放到host上&lt;/li&gt;
&lt;li&gt;Gatsby主要是用来做&lt;code class=&quot;language-text&quot;&gt;网站建设&lt;/code&gt;的，你需要什么类型的网站，静态的还是带后台数据库的，gatsby都可以帮你搞定，而不仅仅只是静态的CMS型的网站&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以看下&lt;a href=&quot;https://www.gatsbyjs.com/why-gatsby/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;WHY GATSBY&lt;/a&gt;了解下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Gatsby enables developers to build fast, secure, and powerful websites using a React-based framework and innovative data layer that makes integrating different content, APIs, and services into one web experience incredibly simple.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Gatsby功能非常强大，对我来说有利有弊：&lt;/p&gt;
&lt;p&gt;pros：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gatsby工具集、插件系统非常强大，各种客制化需求都可以自行满足&lt;/li&gt;
&lt;li&gt;gatsby基于reactjs，要制作一些自己的组件非常容易上手&lt;/li&gt;
&lt;li&gt;gatsby有大量现成的starter或theme等，几乎任何简单的需求都可以直接使用，不需要额外的开发&lt;/li&gt;
&lt;li&gt;gatsby的工具集提供的功能都非常现代化，响应式页面、浏览器兼容性等都不在话下，建出来的站点功能完备&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;cons：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gatsby过于强大，很多东西存在但对我来说无用，反而可能会有维护负担（漏洞、版本升级等）&lt;/li&gt;
&lt;li&gt;gatsby的graphql系统对我来说太复杂了，我只是要一个静态站点而已&lt;/li&gt;
&lt;li&gt;gatsby需要上手时间来学习和了解里面的细节，它有自己的系统和API等，都是需要时间熟悉的，而不是像jekyll那样几个CLI命令就搞定一切了&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anyway，最后反正还是切到了Gatsby。不过因为wordpress之前转到jekyll的时候是通过生成一部分静态html直接存放在jekyll的repo里的方式进行的。到了gatsby这步就行不通了，gatsby是整站完全由CLI生成的，我简单研究了下，没找到像jekyll那时候的那种能兼容两种行为的模式。最后只能忍痛抛弃掉了转到jekyll之前的那部分博客内容，还好量不算特别大。&lt;/p&gt;
&lt;h1 id=&quot;2-选择starter&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E9%80%89%E6%8B%A9starter&quot; aria-label=&quot;2 选择starter permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 选择Starter&lt;/h1&gt;
&lt;p&gt;要使用Gatsby开始建站，必然首先会需要选择一款Starter，在其基础上进行二次制作/设置/内容输出（什么？你说你想直接用gatsby基础库裸做一个站点？那你为什么不直接用react得了，gatsby一堆API那么复杂，何必呢）。选择Starter可以去Gatsby的官方站点：&lt;a href=&quot;https://www.gatsbyjs.com/starters/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gatsby Starter Library&lt;/a&gt;，然后用命令行工具来进行操作：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ gatsby new &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;your-project-name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;link-to-starter&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;不过实际上这个命令也就是帮你clone了一个repo出来而已，没啥意义，建议看我后面的第三点来进行初始化和repo管理。&lt;/p&gt;
&lt;p&gt;我个人选的是：&lt;a href=&quot;https://www.gatsbyjs.com/starters-next/alxshelepenok/gatsby-starter-lumen&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gatsby-starter-lumen&lt;/a&gt;。虽然没什么出彩的地方，但至少功能比较齐全，而且我看了看还有稳定的维护记录，不过应该也不能算是active了，到现在（20210905）仍旧用的是Gatsby的2.X的版本，Gatsby官方Release都已经是&lt;code class=&quot;language-text&quot;&gt;3.14.X&lt;/code&gt;了。如果现在还有人入坑的话，那建议还是要选一款支持v3以后Gatsby版本的Starter。&lt;/p&gt;
&lt;h1 id=&quot;3-如何管理你的repo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%A6%82%E4%BD%95%E7%AE%A1%E7%90%86%E4%BD%A0%E7%9A%84repo&quot; aria-label=&quot;3 如何管理你的repo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 如何管理你的repo&lt;/h1&gt;
&lt;p&gt;静态站点的repo管理建议如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;制作一个repo专门放gatsby相关内容，建议使用bitbucket制作一个单人用的private repo：&lt;a href=&quot;https://bitbucket.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Bitbucket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;制作一个单独的github page repo，来收取gatsby build出来的静态内容，作为静态站点的host：&lt;a href=&quot;https://pages.github.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Github Pages&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至于为什么要这么做：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;鸡蛋不同篮，保证安全，原始数据和静态站点尽量分开&lt;/li&gt;
&lt;li&gt;如果你的站点里有任何会导致版权争议之类的内容，也只会有github page repo被take down，而不会影响到你的原始数据&lt;/li&gt;
&lt;li&gt;务必保证你的原始数据一定要保存在一个private repo里，否则极容易被和page repo一起take down&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为我的原始数据repo是放在bitbucket的，就不能直接使用github的fork了。这里可以打开&lt;a href=&quot;https://bitbucket.org/repo/import&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Bitbucket的import页面&lt;/a&gt;，使用import的方式，把你选择的Starter的github链接贴进去，这样就会在bitbucket里创建一个private repo，里面的内容是完全clone自github的。&lt;/p&gt;
&lt;p&gt;为了后续接收原始starter repo里的改动（新功能及版本升级之类的维护等），建议不要直接在这个repo里的master分支进行任何改动，该repo的master分支上的所有内容必须保证无变动。后续所有starter的master发生的改动就可以直接pull过来。&lt;/p&gt;
&lt;p&gt;在本地磁盘上clone刚才创建出来的bitbucket repo后，进入这个repo&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;创建一个以你的站点命名的branch：&lt;code class=&quot;language-text&quot;&gt;xenojoshua.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在repo根目录创建同名文件夹：&lt;code class=&quot;language-text&quot;&gt;xenojoshua.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;然后在里面创建一个&lt;code class=&quot;language-text&quot;&gt;Makefile&lt;/code&gt;来维护一些日常使用的命令&lt;/li&gt;
&lt;li&gt;此外，创建一个root文件夹，把所有你的客制化内容都放在这个文件夹内，文件夹的结构和外部starter的root文件保持一致，后续就可以使用脚本将这个文件夹下的内容全部复制到根目录，这样就能在保证starter不变的情况下，添加客制化的东西&lt;/li&gt;
&lt;li&gt;为了同步starter github原repo的内容，还需要添加一个remote，名字就叫sync，地址就是starter的github repo地址&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原始数据repo和github page repo位置：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;some_dir_on_disk /
                 | agreatfool.github.io / ...
                 | gatsby-starter-lumen / ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;原始数据repo文件结构：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gatsby-starter-lumen /
                     | content /
                               | pages    # starter自带的页面
                               | posts    # starter自带的范例posts
                     | src                # starter自带的组件等实现代码
                     | static /
                              | media     # starter自带的范例posts里用到的图片
                     | xenojoshua.com /
                                      | root /   # 所有内容都会在develop和build的时候覆盖到lumen根目录
                                             | content /
                                                       | pages
                                                       | posts /
                                                               | 2016 / ...
                                                               | 2017 / ...
                                                               | ...
                                                               | 2021 /
                                                                      | ...
                                                                      | 09 /
                                                                           | ...
                                                                           | gatsby-notes.md
                                             | src       # 客制化的组件代码，包括修改starter自带组件的一些行为
                                             | static /
                                                      | media /
                                                      | posts /
                                                              | 2016 / ...
                                                              | 2017 / ...
                                                              | ...
                                                              | 2021 /
                                                                     | ...
                                                                     | 09 /
                                                                          | ...
                                                                          | gatsby-notes / ... / *.jpeg
                                      | Makefile&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Makefile：&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;sync&lt;/code&gt;将starter原repo里的改动同步过来：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;makefile&quot;&gt;&lt;pre class=&quot;language-makefile&quot;&gt;&lt;code class=&quot;language-makefile&quot;&gt;&lt;span class=&quot;token target symbol&quot;&gt;sync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; \
		cd ..&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git checkout master -f&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git pull sync master --verbose&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git push origin master -f --verbose&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git checkout xenojoshua.com -f&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git rebase master&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git push origin xenojoshua.com -f&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		cd xenojoshua.com&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
	&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;develop&lt;/code&gt;在本地应用所有的变化，查看在xenojoshua.com文件夹下做的改动的效果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;makefile&quot;&gt;&lt;pre class=&quot;language-makefile&quot;&gt;&lt;code class=&quot;language-makefile&quot;&gt;&lt;span class=&quot;token target symbol&quot;&gt;develop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; \
		cd ..&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		pwd&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		rm -rf ./content/posts/*&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		rm -rf ./static/media/*&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		cp -Rf ./xenojoshua.com/root/* ./&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		yarn add gatsby-remark-table-of-contents gatsby-plugin-image&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		yarn develop&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
	&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;制作发布用的静态站点：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;makefile&quot;&gt;&lt;pre class=&quot;language-makefile&quot;&gt;&lt;code class=&quot;language-makefile&quot;&gt;&lt;span class=&quot;token target symbol&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; \
		cd ..&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		pwd&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		rm -rf ./public&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		rm -rf ./content/posts/*&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		rm -rf ./static/media/*&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		cp -Rf ./xenojoshua.com/root/* ./&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		yarn add gatsby-remark-table-of-contents gatsby-plugin-image&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		yarn build&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git checkout .&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git clean -fd&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
	&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;deploy&lt;/code&gt;将最新的发布内容提交到github page repo，发布上线：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;makefile&quot;&gt;&lt;pre class=&quot;language-makefile&quot;&gt;&lt;code class=&quot;language-makefile&quot;&gt;&lt;span class=&quot;token target symbol&quot;&gt;deploy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; \
		cd ../../agreatfool.github.io&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		pwd&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git fetch&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git checkout -f gatsby&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git pull origin gatsby&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		cd ../gatsby-starter-lumen&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		pwd&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		cp -Rf ./public/* ../agreatfool.github.io/&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		cd ../agreatfool.github.io/&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		pwd&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git add .&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git commit -m &lt;span class=&quot;token string&quot;&gt;&quot;Save.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
		git push origin gatsby&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; \
	&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-gatsby技术开发&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-gatsby%E6%8A%80%E6%9C%AF%E5%BC%80%E5%8F%91&quot; aria-label=&quot;4 gatsby技术开发 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Gatsby技术开发&lt;/h1&gt;
&lt;p&gt;刚才也说到了用gatsby的最主要的原因就是能开箱即用，基本上不需要做什么改动就可以建站，但实际上多多少少还是要做点调整的。我对lumen做的改动：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;blockquote太丑了，改了下样式&lt;/li&gt;
&lt;li&gt;Feed组件改了下时间的format，改为中国人的习惯格式&lt;/li&gt;
&lt;li&gt;Author组件改为github链接&lt;/li&gt;
&lt;li&gt;Meta组件改了下时间的format&lt;/li&gt;
&lt;li&gt;自制了Gallery组件：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://xenojoshua.com/posts/2021/09/gallery-example&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gatsby Gallery组件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;用到了额外的插件：&lt;a href=&quot;https://www.gatsbyjs.com/plugins/gatsby-plugin-image/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gatsby-plugin-image&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面就简单说下gatsby里的一些技术点，因为每个starter都会对基本的gatsby进行客制化，所以我说的不一定你用得上，但大致上的概念是不会变的。另，建议先通读下&lt;a href=&quot;https://www.gatsbyjs.com/docs/tutorial/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Official Tutorial&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;41-config&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-config&quot; aria-label=&quot;41 config permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 Config&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;root/config.js&lt;/code&gt;：站点的一些基本属性，url是什么，作者信息等，会被下面的gatsby配置文件加载，实际上就是gatsby-config.js的一部分&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;root/gatsby-config.js&lt;/code&gt;：其他基本可以忽略，主要是插件的配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里提一句如果要让&lt;code class=&quot;language-text&quot;&gt;_&lt;/code&gt;不再被转为斜体，需要修改&lt;code class=&quot;language-text&quot;&gt;gatsby-transformer-remark&lt;/code&gt;插件的配置，在options里添加：&lt;code class=&quot;language-text&quot;&gt;pedantic: false&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&quot;42-structure&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-structure&quot; aria-label=&quot;42 structure permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 Structure&lt;/h2&gt;
&lt;p&gt;准备知识：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/tutorial/part-6/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Part 6: Create Pages Programmatically&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/reference/config-files/gatsby-node/#createPages&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Node createPages API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/reference/config-files/gatsby-node/#onCreateNode&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Node onCreateNode API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/reference/config-files/gatsby-ssr/#onRenderBody&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;SSR onRenderBody API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;lumen的代码文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;root /
     | gatsby /
              | create-pages.js    # 实现 createPages API，创建tags、categories、分页posts等页面
              | on-create-node.js  # 实现 onCreateNode API
              | on-render-body.js  # 实现 onRenderBody API
     | src /
           | assets / scss / ...   # 样式代码文件
           | components / ...      # 所有页面组件代码文件
           | templates / ...       # 所有页面的模板代码文件
     | gatsby-browser.js           # gatsby web的入口，css等就在这里加载
     | gatsby-config.js            # gatsby 的配置
     | gatsby-node.js              # gatsby node的入口，后端进程入口
     | gatsby-ssr.js               # gatsby ssr的入口，离线渲染&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;43-graphql&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-graphql&quot; aria-label=&quot;43 graphql permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 Graphql&lt;/h2&gt;
&lt;p&gt;Gatsby用Graphql用得很重，所有的页面上的数据都是来自graphql的查询，即便是你写的md文件post内容，也是通过graphql查询获得的。&lt;/p&gt;
&lt;p&gt;准备知识：&lt;a href=&quot;https://www.gatsbyjs.com/docs/tutorial/part-4/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Part 4: Query for Data with GraphQL&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这里不准备讲太展开，这个话题有点大了，基本上读完tutorial的内容也就差不多了，更深入的就先不谈了。&lt;/p&gt;
&lt;p&gt;建议先用develop命令把后端启起来，然后按&lt;a href=&quot;https://www.gatsbyjs.com/docs/tutorial/part-4/#use-graphiql-to-explore-the-data-layer-and-write-graphql-queries&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Use GraphiQL to explore the data layer and write GraphQL queries&lt;/a&gt;里提到的，打开GraphiQL界面进行摸索，稍微看下就会了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/09/gatsby-notes/graphiql.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;图上左边会列出所有gatsby可用的查询内容，紫色的表示是查询条件，蓝色的表示是可以得到的返回数据，点击你需要的内容，UI会自动将点中的内容填充到中间的那段查询语句里，非常便捷。查询结果也可以直接在UI上看到，基本上免去了后面到代码里调试的麻烦，只要UI上你的语句是对的，结果是你想要的，照样贴到代码里就不会错了。&lt;/p&gt;
&lt;h3 id=&quot;431-page-query&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#431-page-query&quot; aria-label=&quot;431 page query permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3.1 Page query&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/how-to/querying-data/page-query/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Querying Data in Pages with GraphQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/tutorial/part-4/#task-use-a-page-query-to-pull-the-list-of-post-filenames-into-your-blog-page&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Task: Use a page query to pull the list of post filenames into your blog page&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graphql最主要有两种使用方法，一种叫&lt;code class=&quot;language-text&quot;&gt;page query&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主要应用在页面初始化的时候的查询，比如说你的blog，点击某一篇post的链接，打开的时候就会去查询对应的post数据&lt;/li&gt;
&lt;li&gt;这个查询是&lt;code class=&quot;language-text&quot;&gt;可以带参数&lt;/code&gt;的，这很重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整个查询路径如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;root/gatsby-node.js：启动服务器，会加载 gatsby/create-page.js&lt;/li&gt;
&lt;li&gt;root/gatsby/create-page.js：会决定某个page的template，以及对应的page query的context：e.g &lt;a href=&quot;https://github.com/alxshelepenok/gatsby-starter-lumen/blob/3.0.7/gatsby/create-pages.js#L62-L63&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;root/src/templates/post-template.js：在对应的template文件中，在graphql查询中使用context带过来的参数，并在page组件中使用查询得到的结果：e.g &lt;a href=&quot;https://github.com/alxshelepenok/gatsby-starter-lumen/blob/3.0.7/src/templates/post-template.js#L30&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;source1&lt;/a&gt; &lt;a href=&quot;https://github.com/alxshelepenok/gatsby-starter-lumen/blob/3.0.7/src/templates/post-template.js#L24&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;source2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;432-static-query&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#432-static-query&quot; aria-label=&quot;432 static query permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3.2 Static query&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/how-to/querying-data/use-static-query/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Querying Data in Components with the useStaticQuery Hook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gatsbyjs.com/docs/tutorial/part-4/#task-use-usestaticquery-to-pull-the-site-title-into-the-layout-component&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Task: Use useStaticQuery to pull the site title into the Layout component&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Graphql另一种使用方法是&lt;code class=&quot;language-text&quot;&gt;static query&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可以在任何你想要进行查询的地方进行查询，不一定要像&lt;code class=&quot;language-text&quot;&gt;page query&lt;/code&gt;那样必须写在固定的地方遵照规定的流程&lt;/li&gt;
&lt;li&gt;但这类查询必须是完全&lt;code class=&quot;language-text&quot;&gt;静态&lt;/code&gt;的，意味着你不能在query中添加任何变量&lt;/li&gt;
&lt;li&gt;虽然写法比较自由，但实际应用范围反而很小&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Gatsby Gallery组件]]></title><description><![CDATA[在gatsby站点中制作gallery展示组件]]></description><link>https://xenojoshua.com/posts/2021/09/gallery-example</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/09/gallery-example</guid><pubDate>Sun, 05 Sep 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E9%9C%80%E6%B1%82&quot;&gt;1. 需求&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84&quot;&gt;2. 文件结构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E4%BB%A3%E7%A0%81%E6%94%B9%E5%8A%A8&quot;&gt;3. 代码改动&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-create-pagejs&quot;&gt;3.1 create-page.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-post-templatejs&quot;&gt;3.2 post-template.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-galleryjs&quot;&gt;3.3 Gallery.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-postjs&quot;&gt;3.4 Post.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-需求&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E9%9C%80%E6%B1%82&quot; aria-label=&quot;1 需求 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 需求&lt;/h1&gt;
&lt;p&gt;Gallery算是一个blog中非常基础的需求，看了下gatsby的插件库，貌似是有一个&lt;code class=&quot;language-text&quot;&gt;gatsby-theme-gallery&lt;/code&gt;。但是这个插件引入了theme概念，对我来说无用，而且我需求的并不是要一个site级别的gallery，而是一个post级别的gallery，所以不合用。还是自己做一个得了。&lt;/p&gt;
&lt;p&gt;主要参考了：&lt;a href=&quot;https://engineering.belchior.me/creating-a-custom-photo-gallery-using-gatsbyjs-and-css-grid-ck8ghm0vn01vkz3s1ulux9v17&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Creating a Custom Photo Gallery using Gatsby.js and CSS Grid&lt;/a&gt;。此外，我的gatsby使用的是&lt;a href=&quot;https://github.com/alxshelepenok/gatsby-starter-lumen&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;alxshelepenok/gatsby-starter-lumen&lt;/a&gt;这个starter，技术上倒是无所谓用的是哪个starter，但文件夹结构是因应着这个starter的结构，所以姑且这里提下。&lt;/p&gt;
&lt;p&gt;另外还有一个插件：&lt;a href=&quot;https://github.com/browniebroke/gatsby-image-gallery&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;browniebroke/gatsby-image-gallery&lt;/a&gt;，不过看了下用起来也蛮麻烦的，再说了。&lt;/p&gt;
&lt;p&gt;关于gatsby的一些技术点，及如何制作自制插件之类的，会在另一篇博文里展开，这里就不提了。&lt;/p&gt;
&lt;h1 id=&quot;2-文件结构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84&quot; aria-label=&quot;2 文件结构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 文件结构&lt;/h1&gt;
&lt;p&gt;这里按当前这篇post进行举例，来说明下大致上的post相关文件及gallery相关图片文件的存放位置。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;root /
     | content /
               | posts /
                       | 2021 /
                              | 09 /
                                   | gallery-example.md  # 这是博文本身
     | static /
              | media /
                      | posts /
                              | 2021 /
                                     | 09 /
                                          | gallery-example /
                                                            | gallery / *.jpeg  # 将会展示在gallery内的图片
                                                            | *.jpeg            # 其他会在post内使用的图片&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;这篇blog的slug：&lt;code class=&quot;language-text&quot;&gt;gallery-example&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;post本身的md文件还是按slug存放在：&lt;code class=&quot;language-text&quot;&gt;/content/posts/YYYY/MM/${slug}.md&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;post对应的图片是按slug存放在：&lt;code class=&quot;language-text&quot;&gt;/static/media/posts/YYYY/MM/${slug}/*.jpeg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;这里新添加一层&lt;code class=&quot;language-text&quot;&gt;gallery&lt;/code&gt;文件夹，里面的图片会被gallery插件使用，展示在post的&lt;code class=&quot;language-text&quot;&gt;EOF&lt;/code&gt;之后：&lt;code class=&quot;language-text&quot;&gt;/static/media/posts/YYYY/MM/${slug}/gallery/*.jpeg&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大致上就这样，主要就是在media的post专属文件夹里新添加了一个gallery文件夹，里面的图片都会作为post的专属gallery展示在EOF之后。&lt;/p&gt;
&lt;p&gt;这里展示一张不会在gallery里展出的图片，因为它是存放在post的media文件夹内，但在gallery文件夹之外的图片：&lt;code class=&quot;language-text&quot;&gt;/static/media/posts/2021/09/gallery-example/non-gallery.jpeg&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/09/gallery-example/non-gallery.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;3-代码改动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E4%BB%A3%E7%A0%81%E6%94%B9%E5%8A%A8&quot; aria-label=&quot;3 代码改动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 代码改动&lt;/h1&gt;
&lt;p&gt;代码改动主要是下面几个：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gatsby-config.js                                 # 添加gatsby-plugin-image插件，该图片展示插件在lumen这个starter中不存在
gatsby/create-page.js                            # 在post-template.js使用的context中添加gallery参数，该值为static的media文件夹下post对应的gallery文件夹
src/types/gallery.js                             # 描述从graphql内查询出来的allFile数据结构，这会作为gallery参数传给Post
src/templates/post-template.js                   # 在该template的page query中根据create-page.js给的gallery参数，查询对应路径的图片文件信息allFile；PostTemplate的传入参数data里会有一个新的节点allFile，把它作为gallery参数传给Post
src/components/Post/Gallery/Gallery.js           # 组件实现js
src/components/Post/Gallery/Gallery.module.scss  # 组件style
src/components/Post/Gallery/index.js             # 组件index，直接引入Gallery.js
src/components/Post/Post.js                      # 判断Post新的传入参数gallery，如果里面有图片，则在Content后面追加Gallery组件&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;31-create-pagejs&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-create-pagejs&quot; aria-label=&quot;31 create pagejs permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 create-page.js&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;  &lt;span class=&quot;token function&quot;&gt;createPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; edge&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fields&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;./src/templates/post-template.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; edge&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fields&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;gallery&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;edge&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fields&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slug&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/gallery&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;32-post-templatejs&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-post-templatejs&quot; aria-label=&quot;32 post templatejs permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 post-template.js&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;graphql&quot;&gt;&lt;pre class=&quot;language-graphql&quot;&gt;&lt;code class=&quot;language-graphql&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;token definition-query function&quot;&gt;PostBySlug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$slug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token scalar&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$gallery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token scalar&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property-query&quot;&gt;markdownRemark&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$slug&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;### &lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;others&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;###&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token property-query&quot;&gt;allFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;relativeDirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$gallery&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;totalCount&lt;/span&gt;
      &lt;span class=&quot;token object&quot;&gt;nodes&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token object&quot;&gt;childrenImageSharp&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;gatsbyImageData&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Layout title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;postTitle&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; - &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;siteTitle&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; description&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;metaDescription&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; socialImage&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;socialImageUrl&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Post post&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;markdownRemark&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; gallery&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;allFile&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Layout&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;33-galleryjs&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-galleryjs&quot; aria-label=&quot;33 galleryjs permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 Gallery.js&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// @flow strict&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; GatsbyImage &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;gatsby-plugin-image&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styles &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./Gallery.module.scss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; type &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; GalleryData &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../../../types/gallery&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

type Props &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;gallery&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; GalleryData
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Gallery&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; gallery &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; images &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// eslint-disable-next-line no-restricted-syntax&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; gallery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nodes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;entries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; imgKey &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;gallery-img-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;index&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sharp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;childrenImageSharp&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sharp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; image &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sharp&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;gatsbyImageData&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        images&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;GatsbyImage key&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;imgKey&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; alt&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;imgKey&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; image&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;images&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;styles&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;gallery&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;images&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; Gallery&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;34-postjs&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-postjs&quot; aria-label=&quot;34 postjs permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 Post.js&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;styles&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;post__content&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Content body&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;html&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;galleryNode&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[如何管理个人笔记]]></title><description><![CDATA[如何做好个人的笔记管理，保证其安全性及编写体验 | Obsidian软件介绍]]></description><link>https://xenojoshua.com/posts/2021/08/notes-management</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/08/notes-management</guid><pubDate>Sat, 28 Aug 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E7%AC%94%E8%AE%B0%E5%88%86%E7%B1%BB&quot;&gt;1. 笔记分类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%B7%A5%E5%85%B7%E9%80%89%E6%8B%A9&quot;&gt;2. 工具选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%A4%87%E4%BB%BD%E5%92%8C%E5%AE%89%E5%85%A8&quot;&gt;3. 备份和安全&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-dayone%E7%9A%84%E9%97%AE%E9%A2%98&quot;&gt;4. DayOne的问题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E4%B8%AA%E4%BA%BA%E6%84%9F%E6%82%9F%E7%9A%84%E5%B7%A5%E5%85%B7%E9%80%89%E6%8B%A9&quot;&gt;5. 个人感悟的工具选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-obsidian&quot;&gt;6. Obsidian&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-obsidian%E7%AE%80%E4%BB%8B&quot;&gt;6.1 Obsidian简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#63-obsidian%E8%AE%BE%E7%BD%AE%E5%8F%8A%E4%BD%BF%E7%94%A8&quot;&gt;6.3 Obsidian设置及使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#64-vault%E8%A7%84%E5%88%92%E5%8F%8Afront-matter%E5%AE%9A%E4%B9%89&quot;&gt;6.4 Vault规划及front matter定义&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#65-%E4%B8%80%E4%BA%9B%E5%B7%A5%E5%85%B7&quot;&gt;6.5 一些工具&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-笔记分类&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E7%AC%94%E8%AE%B0%E5%88%86%E7%B1%BB&quot; aria-label=&quot;1 笔记分类 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 笔记分类&lt;/h1&gt;
&lt;p&gt;笔记管理是非常重要的，无论是小时候老生常谈的剪报修养，到读书学习时候的课堂笔记，再到后来的个人博客，无非就是将经验积累下来，转化为文字形态进行存储。无论其子概念范畴是什么，其实一律可以归类为「笔记」。&lt;/p&gt;
&lt;p&gt;这里简单分享下个人的笔记分类，主要以可见度为第一维度分类，以内容和类型为第二维度分类（不存在微博、twitter之类的短文字内容，这类内容不足以被称为笔记）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公众可见：
&lt;ul&gt;
&lt;li&gt;个人博客：进行一些经验分享和探讨（comment形式），以技术内容为主，辅以少量政经评论&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;个人私密：
&lt;ul&gt;
&lt;li&gt;剪藏笔记：主要是通过剪藏的方式进行存储的一些资料，包括技术内容的以及政经内容的各种方向资料&lt;/li&gt;
&lt;li&gt;日记&lt;/li&gt;
&lt;li&gt;个人感悟：日常的一些体悟和思想积累，也包括游记等娱乐内容&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其负责的领域各不相同：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个人博客主要进行技术分享，其实本来也有政经探讨的意向，但因为国情问题，还是不方便在公众场合进行这类分享&lt;/li&gt;
&lt;li&gt;剪藏笔记属于非常重要的一块，不过这块基本上都不是原创内容，是从网络各个频道上剪藏过来的内容，和老旧概念&lt;code class=&quot;language-text&quot;&gt;剪报&lt;/code&gt;属于一个意思。这部分内容最主要是构建个人知识数据库，需要高效的工具进行管理，方便后续的搜索和查询&lt;/li&gt;
&lt;li&gt;个人感悟这块纯原创，主要把人生中的各种想法和经历记录下来，以免一辈子白活&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-工具选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%B7%A5%E5%85%B7%E9%80%89%E6%8B%A9&quot; aria-label=&quot;2 工具选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 工具选择&lt;/h1&gt;
&lt;p&gt;根据上面的分类，工具主要分3部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个人博客：
&lt;ul&gt;
&lt;li&gt;静态博客系统，使用github来进行host&lt;/li&gt;
&lt;li&gt;至于静态博客系统选哪家，那实在可选的工具太多了，大家根据自己的技术栈来进行选择即可&lt;/li&gt;
&lt;li&gt;目前我个人刚从jekyll转到gatsby，后面应该也会撰文记录细节&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;剪藏笔记：
&lt;ul&gt;
&lt;li&gt;目前市面上的选择应该也比较多了，这块推荐&lt;a href=&quot;https://www.yinxiang.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;印象笔记&lt;/a&gt;以及&lt;a href=&quot;https://www.yinxiang.com/new/product/webclipper/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;剪藏插件&lt;/a&gt;，再加上印象笔记官方微信公众号的剪藏功能，可以保证全平台覆盖&lt;/li&gt;
&lt;li&gt;印象笔记的tagging和搜索功能都做的很强大，非常好用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;个人感悟：
&lt;ul&gt;
&lt;li&gt;之前使用的是dayone，目前转到了obsidian使用静态文件系统进行管理&lt;/li&gt;
&lt;li&gt;这块属于本文的重点内容后面细说&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;阮一峰的博文「&lt;a href=&quot;https://www.ruanyifeng.com/blog/2021/08/best-note-taking-software-for-programmers.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;最适合程序员的笔记软件&lt;/a&gt;」，可以仔细阅读下。&lt;/p&gt;
&lt;h1 id=&quot;3-备份和安全&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%A4%87%E4%BB%BD%E5%92%8C%E5%AE%89%E5%85%A8&quot; aria-label=&quot;3 备份和安全 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 备份和安全&lt;/h1&gt;
&lt;p&gt;无论上述的任何一个分类，数据安全都是非常重要的，当然需要有针对性的对策：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;个人博客：之前也提到了使用静态博客系统，既然如此这块自然会使用git进行代码/内容管理，git本身就是分布式的，remote一份，本地磁盘一份，OSX的TimeMachine一份&lt;/li&gt;
&lt;li&gt;剪藏笔记：这块主要靠印象笔记的云服务，云端一份，本地磁盘一份，OSX的TimeMachine一份&lt;/li&gt;
&lt;li&gt;个人感悟：目前使用obsidian，iCloud一份，本地磁盘一份，OSX的TimeMachine一份&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;4-dayone的问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-dayone%E7%9A%84%E9%97%AE%E9%A2%98&quot; aria-label=&quot;4 dayone的问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. DayOne的问题&lt;/h1&gt;
&lt;p&gt;使用DayOne的时间也很久了，这款软件的版本演进引入了相当激进的行为变化，导致了一系列的问题。&lt;/p&gt;
&lt;p&gt;早期程序行为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;markdown优先，编辑操作非常轻松愉快&lt;/li&gt;
&lt;li&gt;数据存储完全依赖文件系统，每个post一个单独的文件，附件则全部存储到一个统一的文件夹内&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就保证了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;程序员型的编辑者创造内容有非常愉悦的编写体验&lt;/li&gt;
&lt;li&gt;内容所见即所得，不需要手动操作菜单界面&lt;/li&gt;
&lt;li&gt;备份非常简单便捷，直接存放到备份文件系统即可&lt;/li&gt;
&lt;li&gt;后续切换到其他的编辑软件非常方便，只要是支持markdown语法的编辑软件都可以直接使用，如果不考虑过于复杂的内容维护和搜索等&lt;/li&gt;
&lt;li&gt;数据同步和备份的选择相当灵活，可以用iCloud也可以用dropbox等，反正数据就是文件而已&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而后续程序改版为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编辑以界面菜单操作为优先，虽然仍旧兼容部分markdown语法，但大幅阉割，完整的编写体验需要大量的UI操作&lt;/li&gt;
&lt;li&gt;数据存储使用数据库sqlite，不再使用文件系统&lt;/li&gt;
&lt;li&gt;dayone推出了自己的同步云服务，等于是变相把软件做成了订阅型软件，希望多端数据同步的必须买dayone自己的服务，不再可以使用第三方的iCloud之类的&lt;/li&gt;
&lt;li&gt;限制单个post最多30张图片&lt;/li&gt;
&lt;li&gt;单个图片文件分辨率上限为4K，大于4K则会被压到4K&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;导致了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编辑体验非常难受，有种回到了被word支配的年代的感觉&lt;/li&gt;
&lt;li&gt;备份比较麻烦，内容不够直观&lt;/li&gt;
&lt;li&gt;因为引入了数据库的原因，很多数据的关系就不再直白了，必须理解数据库表和数据的关系才能掌握
&lt;ul&gt;
&lt;li&gt;post和tag的关系，哪篇post有多少tag&lt;/li&gt;
&lt;li&gt;post和附件的关系，哪篇post有多少图片，图片在哪&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;这样的改版也造成后续软件切换有非常高的难度，因为不再是文件形式的数据保存，后续如果要换成其他软件，必须制作工具从数据库中导出数据才行&lt;/li&gt;
&lt;li&gt;数据同步和数据安全都不再可选，且dayone的云服务早期非常不稳定&lt;/li&gt;
&lt;li&gt;图片数量限制让人非常不愉快，特别是在做游记的时候&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以自dayone改版之后，一直有意向且在留意是否有比较好的工具可以转过去。&lt;/p&gt;
&lt;h1 id=&quot;5-个人感悟的工具选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E4%B8%AA%E4%BA%BA%E6%84%9F%E6%82%9F%E7%9A%84%E5%B7%A5%E5%85%B7%E9%80%89%E6%8B%A9&quot; aria-label=&quot;5 个人感悟的工具选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 个人感悟的工具选择&lt;/h1&gt;
&lt;p&gt;个人博客使用静态博客系统，剪藏笔记使用印象笔记，这个基本上不太需要动。但人生感悟这块数据太敏感了，而且太重要了，切不能随便交给一家厂商就完事了，一定要思考数据如何保证安全，如何保证在这家厂商服务关闭之后能简便切换到其他软件，阅读和编辑的连贯性。因此这块的工具选择有几点要求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以markdown为优先的编写体验&lt;/li&gt;
&lt;li&gt;以文件系统作为数据存储的方式&lt;/li&gt;
&lt;li&gt;可以有一定的高级数据关系支持：分类、tagging、搜索&lt;/li&gt;
&lt;li&gt;可以灵活切换到其他编辑软件&lt;/li&gt;
&lt;li&gt;可以进行便利的备份&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前看下来只有obsidian能完全满足上述需求。&lt;/p&gt;
&lt;h1 id=&quot;6-obsidian&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-obsidian&quot; aria-label=&quot;6 obsidian permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Obsidian&lt;/h1&gt;
&lt;h2 id=&quot;61-obsidian简介&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-obsidian%E7%AE%80%E4%BB%8B&quot; aria-label=&quot;61 obsidian简介 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 Obsidian简介&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://obsidian.md/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;官方主页&lt;/a&gt;直接提供&lt;code class=&quot;language-text&quot;&gt;Desktop app&lt;/code&gt;的下载链接，也可以通过&lt;a href=&quot;https://apps.apple.com/us/app/obsidian-connected-notes/id1557175442#?platform=ipad&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;App Store安装&lt;/a&gt;。Mobile版本的下载在&lt;a href=&quot;https://obsidian.md/mobile&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;这里&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;个人使用的是iPhone，所以使用对应的&lt;a href=&quot;https://help.obsidian.md/Obsidian/iOS+app&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;iOS app&lt;/a&gt;。这里推荐先下载iPhone app，然后使用mobile app在iCloud里创建Vault。如果反过来先使用Desktop app来创建Vault的话，在iCloud里会和mobile app存放在不同的位置，导致双端同步不一致。&lt;/p&gt;
&lt;p&gt;该软件的app都是免费的，直接可以下载使用，而且完全没有广告：&lt;a href=&quot;https://obsidian.md/pricing&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;官方Pricing页面&lt;/a&gt;。个人用户是完全免费使用的。&lt;/p&gt;
&lt;p&gt;其他有用的链接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;快捷键：&lt;a href=&quot;https://help.obsidian.md/How+to/Keyboard+shortcuts&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Keyboard shortcuts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Search：&lt;a href=&quot;https://help.obsidian.md/Plugins/Search&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Search&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;front matter：&lt;a href=&quot;https://help.obsidian.md/Advanced+topics/YAML+front+matter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;YAML front matter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;第三方（社区）插件：&lt;a href=&quot;https://help.obsidian.md/Advanced+topics/Third-party+plugins&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Third-party plugins&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;浏览和安装第三方插件直接可以在obsidian内部完成，比较便捷，免去了下载软件包手动解压到指定位置的操作&lt;/li&gt;
&lt;li&gt;api doc：&lt;a href=&quot;https://github.com/obsidianmd/obsidian-api&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Obsidian API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;sample plugin repo：&lt;a href=&quot;https://github.com/obsidianmd/obsidian-sample-plugin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Obsidian Sample Plugin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;必要插件：
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;&lt;a href=&quot;https://github.com/Darakah/obsidian-gallery&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Obsidian Gallery&lt;/a&gt;&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pjeby/tag-wrangler&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Obsidian Tag Wrangler Plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/obsidian-post-gallery&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;agreatfool/obsidian-post-gallery&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;obsidian的优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全免费，和&lt;a href=&quot;https://fsnot.es/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;FSNotes&lt;/a&gt;这种号称免费但在mobile市场收费的货色不同，是真的免费&lt;/li&gt;
&lt;li&gt;markdown优先的编辑模式，编辑/预览完全分离&lt;/li&gt;
&lt;li&gt;纯文件模式进行数据管理，可以把它理解为一款代码编辑IDE，以纯文件夹形式管理posts
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://textbundle.org/spec/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TextBundle&lt;/a&gt;格式的官方支持尚未实装：&lt;a href=&quot;https://forum.obsidian.md/t/textbundle-support/3585&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TextBundle support&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;拥有插件机制，可以发挥社区能量，进行功能的丰富化&lt;/li&gt;
&lt;li&gt;对一些批量操作支持非常优秀：
&lt;ul&gt;
&lt;li&gt;post重命名可以同步修改Vault中所有post内对应的内链地址&lt;/li&gt;
&lt;li&gt;tag重命名也能同步修改Vault中所有post内对应的文本（需上面提到的插件支持）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;搜索查询功能非常强大，可以做到从海量数据中找到需要查找的posts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然obsidian也有缺点和问题，目前来看最大的问题是这款软件更偏向桌面，对mobile的支持较一般，特别是第三方插件，很多都是只针对桌面版进行了研发（上面提到的gallery插件就是）。&lt;/p&gt;
&lt;p&gt;至少目前看来，这款软件是完全能满足我的需求的，甚至大大超出了我的预期。&lt;/p&gt;
&lt;h2 id=&quot;63-obsidian设置及使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#63-obsidian%E8%AE%BE%E7%BD%AE%E5%8F%8A%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;63 obsidian设置及使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3 Obsidian设置及使用&lt;/h2&gt;
&lt;p&gt;下面会简单介绍下如何设置及使用Obsidian，以桌面版为视角，之前也提到了mobile版本仍旧只是能用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;创建iCloud内Vault&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;之前也提到了，需要先使用Mobile app，按软件界面的要求设置Vault即可。这里需要记住创建出来的Vault文件夹的名字。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;定位MAC上的文件夹位置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;MAC上的数据是通过iCloud进行同步的，根据OS版本不同，位置可能会变动。目前我的OS是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;11.5.2&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;数据位置在：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;pwd&lt;/span&gt;
/Users/Jonathan/Library/Mobile Documents/iCloud~md~obsidian/Documents
$ ll
total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
drwxr-xr-x@  &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; Jonathan  staff   160B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:14 ./
drwxr-xr-x   &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; Jonathan  staff   128B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;:22 &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/
drwxr-xr-x@  &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; Jonathan  staff    64B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt;:51 .Trash/
drwxr-xr-x@ &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; Jonathan  staff   320B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;:54 .obsidian/
drwxr-xr-x@  &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; Jonathan  staff   160B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:14 Notes/
$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; ./.obsidian
$ ll
total &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;
drwxr-xr-x@ &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt; Jonathan  staff   320B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;:54 ./
drwxr-xr-x@  &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; Jonathan  staff   160B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:14 &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;/
-rw-r--r--@  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; Jonathan  staff   281B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:29 app.json
-rw-r--r--@  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; Jonathan  staff   102B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:29 appearance.json
-rw-r--r--@  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; Jonathan  staff    42B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:29 community-plugins.json
-rw-r--r--@  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; Jonathan  staff   249B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:29 core-plugins.json
-rw-r--r--@  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; Jonathan  staff   837B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;19&lt;/span&gt;:37 hotkeys.json
drwxr-xr-x@  &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; Jonathan  staff   128B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;:59 plugins/
drwxr-xr-x@  &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; Jonathan  staff    96B  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:30 themes/
-rw-r--r--@  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; Jonathan  staff   &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;.7K  &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;:29 workspace&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里我创建出来的Vault文件夹名字是&lt;code class=&quot;language-text&quot;&gt;Notes&lt;/code&gt;，可以看到在刚才的&lt;code class=&quot;language-text&quot;&gt;ll&lt;/code&gt;中存在。而Obsidian自己的数据（含配置、插件、主题等）则存放在&lt;code class=&quot;language-text&quot;&gt;.obsidian&lt;/code&gt;文件夹下，它是一个Vault一个专属的文件夹的，不存在global的设置。在有多个Vault需要共享同一份设置的时候会有点麻烦。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;打开MAC上的Vault&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;打开MAC版的Obsidian，然后按界面上的按钮指引打开刚才提到的iCloud文件夹即可（到Documents那层）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;软件设置&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;点击界面最左下角的&lt;code class=&quot;language-text&quot;&gt;Settings&lt;/code&gt;按钮，打开设置界面。后续的设置按界面操作即可，这里把完成的设置内容作为json代码贴在这里。注意插件需要手动到&lt;code class=&quot;language-text&quot;&gt;第三方插件 &gt; 社区插件&lt;/code&gt;浏览安装，搜索关键字为：&lt;code class=&quot;language-text&quot;&gt;gallery&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;tag&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;app.json&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;showFrontmatter&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;defaultViewMode&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;preview&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;showLineNumber&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;useTab&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;emacsyKeys&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;newLinkFormat&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;shortest&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;alwaysUpdateLinks&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;useMarkdownLinks&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;attachmentFolderPath&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;./&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;readableLineLength&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;appearance.json&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;baseFontSize&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;theme&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;obsidian&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;translucency&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;cssTheme&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Obsidian Nord&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;community-plugins.json&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;obsidian-gallery&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;tag-wrangler&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;core-plugins.json&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;file-explorer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;global-search&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;switcher&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;graph&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;backlink&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;tag-pane&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;page-preview&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;note-composer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;command-palette&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;markdown-importer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;outline&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;word-count&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;open-with-default-app&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;file-recovery&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;hotkeys.json&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;app:go-forward&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;modifiers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Ctrl&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Tab&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;app:go-back&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;modifiers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Ctrl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Shift&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Tab&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;workspace:edit-file-title&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;modifiers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Mod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Shift&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;R&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;tag-pane:open&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;modifiers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Mod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Shift&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;T&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;outline:open-for-current&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;modifiers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Mod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Shift&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;O&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;workspace:export-pdf&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;modifiers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Mod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Shift&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;P&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;workspace:copy-url&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;modifiers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Mod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&quot;Shift&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;U&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;快捷键主要就几个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开设置：CMD + ,&lt;/li&gt;
&lt;li&gt;编辑文件名：CMD + SHIFT + R&lt;/li&gt;
&lt;li&gt;显示TAG面板：CMD + SHIFT + T&lt;/li&gt;
&lt;li&gt;打开文件大纲：CMD + SHIFT + O&lt;/li&gt;
&lt;li&gt;导出为PDF：CMD + SHIFT + P&lt;/li&gt;
&lt;li&gt;前进：CTRL + TAB&lt;/li&gt;
&lt;li&gt;后退：CTRL + SHIFT + TAB ，这两者保持和浏览器等的操作一致&lt;/li&gt;
&lt;li&gt;复制Obsidian内部URL：CMD + SHIFT + U&lt;/li&gt;
&lt;li&gt;切换编辑/预览模式：CMD + E&lt;/li&gt;
&lt;li&gt;在所有文件中搜索：CMD + SHIFT + F&lt;/li&gt;
&lt;li&gt;在当前文件中搜索：CMD + F&lt;/li&gt;
&lt;li&gt;在当前文件中搜索并替换：CMD + OPT + F&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使用上和一般的MD编辑器没什么差别，使用&lt;code class=&quot;language-text&quot;&gt;CMD + E&lt;/code&gt;来切换编辑和预览模式。就几点需要注意下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文件名不要直接在软件外重命名，而是一定要使用Obsidian来重命名，这样才能全部更新Vault内其他文件内对应的内链位置&lt;/li&gt;
&lt;li&gt;同样的，重命名tag也一定要使用软件的插件功能来做&lt;/li&gt;
&lt;li&gt;在文件的任何位置编写&lt;code class=&quot;language-text&quot;&gt;#TAG_NAME&lt;/code&gt;的文本，即可创建&lt;code class=&quot;language-text&quot;&gt;TAG_NAME&lt;/code&gt;tag&lt;/li&gt;
&lt;li&gt;&lt;del&gt;gallery的配置使用如下&lt;/del&gt;
&lt;ul&gt;
&lt;li&gt;&lt;del&gt;type：grid | active-thumb，一般使用grid，active-thumb为可拖拽的grid但有bug&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;path：存放会展示在gallery里的图片的路径&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;imgWidth：grid内每个图片格的宽度，一般不要太大&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;divWidth：%值，指grid所处的div占页面的宽度多少&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;divAlign：left | right，指grid所处的div在页面的左侧还是右侧&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;reverseOrder：true | false，是否逆转图片的展示顺序&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;customList：自定义的图片展示顺序：&lt;code class=&quot;language-text&quot;&gt;customList=5 10 2 4&lt;/code&gt;&lt;/del&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;post-gallery额配置使用如下
&lt;ul&gt;
&lt;li&gt;name：在assets文件夹内，含图片的子文件夹名：&lt;code class=&quot;language-text&quot;&gt;assets/gallery00/*.jpg&lt;/code&gt; -&gt; &lt;code class=&quot;language-text&quot;&gt;name: gallery00&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;rowHeight：gallery内图片每行的高度，e.g 120&lt;/li&gt;
&lt;li&gt;margins：图片间的间距，e.g 5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;post-gallery&quot;&gt;&lt;pre class=&quot;language-post-gallery&quot;&gt;&lt;code class=&quot;language-post-gallery&quot;&gt;name: gallery00
rowHeight: 200
margins: 5&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;64-vault规划及front-matter定义&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#64-vault%E8%A7%84%E5%88%92%E5%8F%8Afront-matter%E5%AE%9A%E4%B9%89&quot; aria-label=&quot;64 vault规划及front matter定义 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4 Vault规划及front matter定义&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Vault&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;由于Obsidian仅只是一款简单的编辑软件，和dayone这样使用数据库来管理数据的软件不同，它是不会对数据的存放位置和结构进行定义的，所有的一切都交由使用者自己组织。这就对使用者提出了要求，你不能随随便便把所有的内容全部都扔到Vault的根目录下，这会导致后续浏览及搜索的困难，也不能把所有的内容都分得过细或扔到过多层的子文件夹中，这也会导致浏览的障碍。&lt;/p&gt;
&lt;p&gt;因此个人使用下面的格式来管理Vault：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;iCloud Documents /
                 | .obsidian
                 | Notes /
                         | ...
                         | 2019 / ...
                         | 2020 / ...
                         | 2021 /
                                | ...
                                | 08 /
                                     | 20210828-obsidian-instruction /
                                                                     | assets / ... / *.jpg
                                                                     | obsidian-instruction.md&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;格式：&lt;code class=&quot;language-text&quot;&gt;Notes / YYYY / MM / YYYYMMDD-slug / slug.md | assets&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tag&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;posts文件都是分布在年月日的多层子文件夹下，因此直接通过文件系统进行浏览是非常困难的。这就要求尽量要做好post的tag内容管理，尽量分门别类做细，后面才可以通过tag的方式来进行post的快速浏览和查找。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;#Tech #JavaScript
#Entertainment #Travel&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;个人Tag principles如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;每个post都一定要有category定义，因为obsidian本身没有category功能，所以可以把category作为tag放到post里，方便后续搜索，e.g
&lt;ul&gt;
&lt;li&gt;#Tech&lt;/li&gt;
&lt;li&gt;#Entertainment&lt;/li&gt;
&lt;li&gt;#Diary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;每个post都一定要有3个维度的时间信息，e.g
&lt;ul&gt;
&lt;li&gt;年 #Y2021&lt;/li&gt;
&lt;li&gt;月 #M202108 #M08&lt;/li&gt;
&lt;li&gt;日 #D20210828 #D0828&lt;/li&gt;
&lt;li&gt;因为obsidian规定tag必须以字母起始，所以必须加一个字符&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其他的tag就可以按post本身内容自行定义即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Front matter&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Obsidian本身对front matter基本上是完全不支持的，不解析其中的内容。但建议仍旧还是要做好front-matter的管理，录入一些原始数据，以便后续有新的plugin支持的时候，可以快速调整来生效。&lt;/p&gt;
&lt;p&gt;个人使用如下的front matter内容：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;...&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/2021/08/20210828-obsidian-instruction&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2021-08-28&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;slug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;obsidian-instruction&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;obsidian使用教程&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;altitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;latitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;38&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;longitude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;南京东路XXX&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;placename&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;XXX国际大酒店&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;district&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;黄浦区&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;city&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;上海市&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;province&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;上海&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;country&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;中国&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;weather&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;temperature&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;humidity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;78&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;weather&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;晴&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;13:33:27&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;aqi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;56&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;65-一些工具&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#65-%E4%B8%80%E4%BA%9B%E5%B7%A5%E5%85%B7&quot; aria-label=&quot;65 一些工具 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.5 一些工具&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/dayone2md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;agreatfool/dayone2md&lt;/a&gt;：将dayone的数据全部导出成上述文件夹格式md文件的命令行工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/obsidian-utils&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;agreatfool/obsidian-utils&lt;/a&gt;：帮助创建obsidian post的命令行工具，可以帮忙初始化title、tags、front-matter等信息&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/obsidian-post-gallery&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;agreatfool/obsidian-post-gallery&lt;/a&gt;：专注于post内gallery展示的插件&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[SS订阅转Clash]]></title><description><![CDATA[如何在ClashX中使用SS订阅]]></description><link>https://xenojoshua.com/posts/2021/08/ss-converter</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/08/ss-converter</guid><pubDate>Tue, 17 Aug 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85%E5%8F%8A%E4%BD%BF%E7%94%A8&quot;&gt;2. 安装及使用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h2&gt;
&lt;p&gt;有点不记得当时为啥要使用这个转换工具了，应该是最早的&lt;code class=&quot;language-text&quot;&gt;ClashX&lt;/code&gt;不支持&lt;code class=&quot;language-text&quot;&gt;ShadowSocks&lt;/code&gt;协议导致我不得不使用工具来进行转换。不过我今天写这篇文章的时候看了下Clash的文档，貌似支持列表里已经有ShadowSocks了，不过因为我还没实际测试过，所以这个结论先保留下。&lt;/p&gt;
&lt;p&gt;总之，之前因为Clash的支持原因，需要使用第三方工具将SS的订阅转换成Clash支持的格式然后Clash才能正常更新SS的订阅。具体就要使用到&lt;a href=&quot;https://github.com/tindy2013/subconverter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;tindy2013/subconverter&lt;/a&gt;这个工具。因为之前找了好几次，所以这次留篇笔记来记录下，方便后续查找。&lt;/p&gt;
&lt;h2 id=&quot;2-安装及使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85%E5%8F%8A%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;2 安装及使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 安装及使用&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;安装&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;参照这篇指引来安装docker container：&lt;a href=&quot;https://github.com/tindy2013/subconverter/blob/master/README-docker.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;subconverter-docker&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;always &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;25500&lt;/span&gt;:25500 tindy2013/subconverter:latest&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;使用&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在Clash中输入下面的链接，来替代你自己机场的SS订阅链接：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;http://127.0.0.1:25500/sub?target&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;clash&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;replace_this_with_your_ss_subscription_link&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;%CONFIG%&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最后的&lt;code class=&quot;language-text&quot;&gt;config&lt;/code&gt;那块是可选的，我基本上不配置。对应的文档在：&lt;a href=&quot;https://github.com/tindy2013/subconverter#advanced-usage&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Advanced Usage&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[How to do MySQL stress test]]></title><description><![CDATA[How to prepare and run a MySQL stress test and get the expected result]]></description><link>https://xenojoshua.com/posts/2021/07/mysql-stress</link><guid isPermaLink="false">https://xenojoshua.com/posts/2021/07/mysql-stress</guid><pubDate>Tue, 20 Jul 2021 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-foreword&quot;&gt;1. Foreword&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#scenario&quot;&gt;Scenario&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-db-metrics&quot;&gt;2. DB Metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-determine-stress&quot;&gt;3. Determine Stress&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-prepare-sql-statements&quot;&gt;4. Prepare SQL Statements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-prepare-lua-script&quot;&gt;5. Prepare LUA script&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-run-the-test&quot;&gt;6. Run the test&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#others&quot;&gt;Others&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#optimize-table&quot;&gt;Optimize table&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#test-the-server-io-first&quot;&gt;Test the server io first&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#reference&quot;&gt;Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#appendix&quot;&gt;Appendix&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sysbench---help&quot;&gt;sysbench —help&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sysbench-fileio-help&quot;&gt;sysbench fileio help&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-foreword&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-foreword&quot; aria-label=&quot;1 foreword permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. Foreword&lt;/h2&gt;
&lt;p&gt;In this article we will go through how to do a RDBMS stress test using tool &lt;code class=&quot;language-text&quot;&gt;sysbench&lt;/code&gt;. In the article we are talking about &lt;code class=&quot;language-text&quot;&gt;MySQL&lt;/code&gt;, as sysbench also supports other DBs like &lt;code class=&quot;language-text&quot;&gt;PostgreSQL&lt;/code&gt;, you can replace MySQL with other DBs according to your requirement.&lt;/p&gt;
&lt;h3 id=&quot;scenario&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#scenario&quot; aria-label=&quot;scenario permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Scenario&lt;/h3&gt;
&lt;p&gt;Say we have a BE application like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/07/mysql-stress/mysql-app.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;It contains several application containers and several DB instances, each app would establish one connection to each DB instance.&lt;/p&gt;
&lt;p&gt;Then we’d like to know under the target / high stress, what will happen to the DB instance, would they be able to handle the stress with ease or crash.&lt;/p&gt;
&lt;p&gt;To figure out this, we can’t simply use a client process to send batch of duplicated SQL queries to DB instance. We need to mock the business like our BE app would do.&lt;/p&gt;
&lt;p&gt;So several steps we need to do.&lt;/p&gt;
&lt;h2 id=&quot;2-db-metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-db-metrics&quot; aria-label=&quot;2 db metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. DB Metrics&lt;/h2&gt;
&lt;p&gt;First we need to figure out what’s the metrics we need to monitor in the stress test.&lt;/p&gt;
&lt;p&gt;Basically:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MySQL instance CPU usage&lt;/li&gt;
&lt;li&gt;MySQL instance Memory usage&lt;/li&gt;
&lt;li&gt;MySQL connection amount&lt;/li&gt;
&lt;li&gt;MySQL query amount&lt;/li&gt;
&lt;li&gt;MySQL table lock wait: &lt;code class=&quot;language-text&quot;&gt;show status;&lt;/code&gt; -&gt; &lt;code class=&quot;language-text&quot;&gt;table_locks_waited&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MySQL innodb lock wait: &lt;code class=&quot;language-text&quot;&gt;show status like &apos;innodb_row_lock%&apos;;&lt;/code&gt; -&gt; &lt;code class=&quot;language-text&quot;&gt;innodb_row_lock_waits&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;innodb_row_lock_time_avg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;MySQL slow sql log&lt;/li&gt;
&lt;li&gt;Host server CPU usage&lt;/li&gt;
&lt;li&gt;Host server Memory usage&lt;/li&gt;
&lt;li&gt;Host server io status: &lt;code class=&quot;language-text&quot;&gt;iostat -d -x -k 1&lt;/code&gt;, show device data show extend data show KB value refresh every 1 second
&lt;ul&gt;
&lt;li&gt;%util 1-100, 100 means all io occupied&lt;/li&gt;
&lt;li&gt;svctm closing to await means almost no wait&lt;/li&gt;
&lt;li&gt;await &gt; svctm means long io queue&lt;/li&gt;
&lt;li&gt;avgqu-sz : average queue size&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For more metrics you may want to learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run MySQL command: &lt;code class=&quot;language-text&quot;&gt;show status;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Download/View grafana dashboard: &lt;a href=&quot;https://github.com/percona/grafana-dashboards&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;percona/grafana-dashboards&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2021/07/mysql-stress/iostat-util.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;3-determine-stress&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-determine-stress&quot; aria-label=&quot;3 determine stress permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Determine Stress&lt;/h2&gt;
&lt;p&gt;In this step we need to figure out the expected stress level.&lt;/p&gt;
&lt;p&gt;3 items to be determined:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How many records shall be in db table&lt;/li&gt;
&lt;li&gt;How many connections&lt;/li&gt;
&lt;li&gt;How’s the expected TPS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DB performance may fluctuate markedly according to the amount of records in table and amount of connections.&lt;/p&gt;
&lt;p&gt;How (for example):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Records amount
&lt;ul&gt;
&lt;li&gt;App users 100K&lt;/li&gt;
&lt;li&gt;Records of each user 5&lt;/li&gt;
&lt;li&gt;Total records amount: 100K * 5 = 500K&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Connections amount
&lt;ul&gt;
&lt;li&gt;BE pod amount -&gt; connections amount&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TPS
&lt;ul&gt;
&lt;li&gt;Best is to see the production monitoring data, most real data&lt;/li&gt;
&lt;li&gt;Secondary is deducing, for example like
&lt;ul&gt;
&lt;li&gt;1k online user&lt;/li&gt;
&lt;li&gt;each user 1 api/sec&lt;/li&gt;
&lt;li&gt;1 api -&gt; 1 transaction&lt;/li&gt;
&lt;li&gt;1k * 1tps = 1k tps&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;4-prepare-sql-statements&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-prepare-sql-statements&quot; aria-label=&quot;4 prepare sql statements permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Prepare SQL Statements&lt;/h2&gt;
&lt;p&gt;In this step we need to figure out the SQL statements which would be used in the stress test.&lt;/p&gt;
&lt;p&gt;How:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;set up the staging backend server with monitoring, especially DB sql monitoring&lt;/li&gt;
&lt;li&gt;run app with user-like actions&lt;/li&gt;
&lt;li&gt;see the sql statements logged in binlog&lt;/li&gt;
&lt;li&gt;pick top X statements of &lt;code class=&quot;language-text&quot;&gt;CRUD&lt;/code&gt; each type, like:
&lt;ul&gt;
&lt;li&gt;SELECT: SQL1, SQL2, SQL3&lt;/li&gt;
&lt;li&gt;UPDATE: SQLa, SQLb, SQLc&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;also grab the CRUD ratio, like: 60% select 35% update 4% create 1% delete&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;5-prepare-lua-script&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-prepare-lua-script&quot; aria-label=&quot;5 prepare lua script permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Prepare LUA script&lt;/h2&gt;
&lt;p&gt;In this step we need to prepare the lua script which would be executed by the sysbench. There are multiple threads in sysbench, each thread will execute the LUA script rather than running SQL statement directly.&lt;/p&gt;
&lt;p&gt;The script will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;determine every time execution which type of CRUD SQL should be executed, finally the CRUD ratio should be consistent with the percentage we got in step 4&lt;/li&gt;
&lt;li&gt;select one SQL statement from the CRUD type SQL pool&lt;/li&gt;
&lt;li&gt;execute the SQL&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Using this LUA script we can mock the SQL executions just like the CRUD ratio we got in step 4, and SQLs are also we prepared in step 4.&lt;/p&gt;
&lt;p&gt;LUA example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;lua&quot;&gt;&lt;pre class=&quot;language-lua&quot;&gt;&lt;code class=&quot;language-lua&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;prepare&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;prepare of stress test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cleanup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cleanup of stress test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;help&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sysbench stress test; no special command line options available&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;thread_done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;db_disconnect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thread_id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-- CONST&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; SEARCH_KEY_PH &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^SK&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; RANDOM_INT_PH &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;^RI&quot;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-- PARAMS&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; totalRowsOfRecordsInDb &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; cmdSeed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        select &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        insert &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;150&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        delete &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        update &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6770&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    selectQueries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT plantId, userId, seedId, status, growTime, harvestTime, blightTime, rarity, residue, leaf FROM fs2_plant_plants WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT userId, finished FROM module_mission_finished WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT userId, activityId, decorId, finished, acceptedRewards, expensePoint FROM fs2_activity_party WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT userId, customerDefId, level, exp, rewards FROM fs2_customer_friendship WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT userId, missionId, progress, acceptTime, expireTime FROM module_mission_in_progress WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT userId, activityId, collect FROM fs2_activity_collect WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT userId, gridId, layer1Type, layer1, layer2Type, layer2, layer3Type, layer3 FROM fs2_grounds WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT decorId, decorDefId, userId, orient, cooldown, buildId, isUpgrade, effectCountLeft, resourceCountLeft, requestAccepted, output, withActivityOutput, freeMode FROM fs2_decoration WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT requestId, receiverId, senderId, helpId, type, info, time, expire, platformRequestId FROM fs2_social_request WHERE receiverId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    selectQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SELECT userId, customerDefIds FROM fs2_customer_event WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;


    insertQueries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    insertQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;insert into `fv_dev`.`fs2_pet` ( `status`, `userId`, `fodderId`, `feedUpCount`, `feedUpTime`, `petDefId`) values ( &apos;0&apos;, &apos;89&apos;, &apos;780003&apos;, &apos;1&apos;, &apos;1438223373&apos;, &apos;900001&apos;);&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    insertQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;insert into fs2_plant_plants (userId,seedId,status,growTime,harvestTime,blightTime,rarity,residue,leaf,soilId,soilType,soilCount,harvestCount,wood,requestAccepted,withActivityOutput) values (&apos;57332&apos;, &apos;110001&apos;, &apos;1&apos;, &apos;1428746759&apos;, &apos;1428746819&apos;, &apos;1429005959&apos;, &apos;0&apos;, &apos;0&apos;, &apos;0&apos;, &apos;0&apos;, &apos;0&apos;, &apos;0&apos;, &apos;0&apos;, &apos;0&apos;, null, null); &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;


    updateQueries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE module_achievement_in_progress SET progress = &apos;[3333333333,44444,5555555555555,7777777777777777777777,^RI,111111111111,22222222222222222222,999999999999999999999999,00000000]&apos; WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE module_profile_infos SET info = ^RI, time = ^RI WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;700&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE fs2_plant_plants SET seedId = ^RI, status = ^RI, growTime = ^RI, harvestTime = ^RI, blightTime = ^RI, rarity = ^RI, leaf = ^RI, residue = ^RI WHERE plantId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;700&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE module_profile SET  exp = exp + 1 WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE module_mission_in_progress SET progress = &apos;[3333333333,44444,5555555555555,7777777777777777777777,^RI,111111111111,22222222222222222222,999999999999999999999999,00000000]&apos;, acceptTime = ^RI WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE module_item SET  updateTime = ^RI WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;700&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE fs2_plant_seeds SET exp = ^RI WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE fs2_social_feed SET helpId = ^RI, status = ^RI WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE fs2_pet SET feedUpCount = ^RI, feedUpTime = ^RI, status = ^RI WHERE petId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE fs2_customer SET exp = ^RI, status = ^RI WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE fs2_customer_town SET missionId = ^RI, leaveTime = ^RI WHERE customerId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;
    updateQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;UPDATE fs2_activity SET count = ^RI, status = ^RI WHERE userId = ^SK;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;

    deleteQueries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    deleteQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;delete from fs2_plant_plants where userId=57332 limit 1;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;
    deleteQueries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;delete from fs2_pet where userId=89 limit 1;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-- LIB&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;seedTable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; seedSum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pairs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;seedTable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
            seedSum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; seedSum &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; value
        &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; randSeed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sb_rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; seedSum&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;

        &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; cmdType&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; prob &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pairs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;seedTable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
            sum &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sum &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; prob
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; randSeed &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; sum &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
                result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cmdType
            &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;



        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;processSleep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sleep 0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;-- 10ms&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-- EXEC&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; cmdType &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;cmdSeed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;--print(cmdType)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;--if cmdType == &quot;insert&quot; or cmdType == &quot;delete&quot; then&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;--    cmdType = &quot;update&quot;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;--end&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; querySeed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _G&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cmdType &lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Queries&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;local&lt;/span&gt; sql &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;querySeed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;--print(sql)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; cmdType &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;update&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt;
        sql &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;%^RI&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sb_rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; totalRowsOfRecordsInDb&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    sql &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sql&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;%^SK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sb_rand&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; totalRowsOfRecordsInDb&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;--processSleep() -- let the lua script sleep to make qps lower for testing, if necessary&lt;/span&gt;

    &lt;span class=&quot;token function&quot;&gt;db_query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sql&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You may find a sleep function &lt;code class=&quot;language-text&quot;&gt;processSleep&lt;/code&gt;, in old sysbench version there is no way to control the TPS speed, so this function could help to slow down the execution. In latest versions, sysbench provided the option to control tps, so it’s no longer necessary.&lt;/p&gt;
&lt;h2 id=&quot;6-run-the-test&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-run-the-test&quot; aria-label=&quot;6 run the test permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Run the test&lt;/h2&gt;
&lt;p&gt;In this step we will see how to run sysbench to execute the stress test.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ sysbench &lt;span class=&quot;token parameter variable&quot;&gt;--version&lt;/span&gt;
sysbench &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.18&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Several useful options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--threads&lt;/code&gt; : How many thread running inside the sysbench, each thread means a db connection&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--rate&lt;/code&gt; : TPS, 0 means no limit, query as fast as possible&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--events&lt;/code&gt; : Total requests to be made in the whole stress test, use this or &lt;code class=&quot;language-text&quot;&gt;--time&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--time&lt;/code&gt; : How long should the stress test last, in seconds, use this or &lt;code class=&quot;language-text&quot;&gt;--events&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Steps to run the stress test:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start the MySQL instance along with all the monitoring facilities&lt;/li&gt;
&lt;li&gt;Create database and table with schema SQL&lt;/li&gt;
&lt;li&gt;Create the initial records in the db table&lt;/li&gt;
&lt;li&gt;Run sysbench with low threads and rate, to warm up the MySQL instance (cache, index, etc…)&lt;/li&gt;
&lt;li&gt;Run sysbench with target rate&lt;/li&gt;
&lt;li&gt;See monitoring, check the CPU Memory iostat and lock waiting&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ sysbench &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--threads&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--time&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3600&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--percentile&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;99&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --report-interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --db-driver&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;mysql &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --mysql&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;. &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  ./test_strategy.lua &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  run&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After the test, see the monitoring system to grab the conclusion. Or may be need to analyse the cause of the performance issues.&lt;/p&gt;
&lt;h2 id=&quot;others&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#others&quot; aria-label=&quot;others permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Others&lt;/h2&gt;
&lt;h3 id=&quot;optimize-table&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#optimize-table&quot; aria-label=&quot;optimize table permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Optimize table&lt;/h3&gt;
&lt;p&gt;Use &lt;code class=&quot;language-text&quot;&gt;OPTIMIZE TABLE&lt;/code&gt; to resort index to restore the performance. After a lot of CRUD, the InnoDB index may be messed up, and the performance reduced. You can perform this command between several rounds of tests.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You can use OPTIMIZE TABLE to reclaim the unused space and to defragment the data file. After extensive changes to a table, this statement may also improve performance of statements that use the table, sometimes significantly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;OPTIMIZE TABLE works for InnoDB, MyISAM, and ARCHIVE tables.
OPTIMIZE TABLE is also supported for dynamic columns of in-memory NDB tables. It does not work for fixed-width columns of in-memory tables, nor does it work for Disk Data tables.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;For InnoDB tables, optimize table will simply perform an alter table to reclaim the space.&lt;/li&gt;
&lt;li&gt;If you have indexes, it will also resort the index pages, and update the statistics.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;OPTIMIZE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;TABLE&lt;/span&gt; XXX&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;test-the-server-io-first&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#test-the-server-io-first&quot; aria-label=&quot;test the server io first permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Test the server io first&lt;/h3&gt;
&lt;p&gt;You may need to test the server io before test db, since the io of some cloud servers is not the same as claimed. You can still use sysbench to do it.&lt;/p&gt;
&lt;p&gt;Create test file:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ sysbench &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-num&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-block-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;8k &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-total-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;4G &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-test-mode&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;rndrd &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-extra-flags&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;direct &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --max-requests&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--time&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1200&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--threads&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  fileio prepare&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Test random read performance:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ sysbench &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-num&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-block-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;8k &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-total-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;4G &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-test-mode&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;rndrd &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --file-extra-flags&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;direct &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --max-requests&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--time&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--threads&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  --report-interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  fileio run&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;reference&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#reference&quot; aria-label=&quot;reference permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Reference&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.guru99.com/performance-vs-load-vs-stress-testing.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Load Testing vs Stress Testing vs Performance Testing: Difference Discussed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://severalnines.com/database-blog/how-benchmark-performance-mysql-mariadb-using-sysbench&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to Benchmark Performance of MySQL &amp;#x26; MariaDB Using SysBench&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.thegeekstuff.com/2016/04/mysql-optimize-table/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to Optimize MySQL Tables and Defragment to Recover Space&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/75595737&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;漫谈MySQL的锁机制&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/iostat.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Docs » 工具参考篇 » 11. iostat 监视I/O子系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.programmersought.com/article/63521025630/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ioss for sysbench, iostat test server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;appendix&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#appendix&quot; aria-label=&quot;appendix permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Appendix&lt;/h2&gt;
&lt;h3 id=&quot;sysbench---help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#sysbench---help&quot; aria-label=&quot;sysbench   help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;sysbench —help&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ sysbench &lt;span class=&quot;token parameter variable&quot;&gt;--help&lt;/span&gt;
Usage:
  sysbench &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;. &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;testname&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;command&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

Commands implemented by &lt;span class=&quot;token function&quot;&gt;most&lt;/span&gt; tests: prepare run cleanup &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;

General options:
  &lt;span class=&quot;token parameter variable&quot;&gt;--threads&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                     number of threads to use &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--events&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                      limit &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; total number of events &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--time&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                        limit &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; total execution &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; seconds &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --forced-shutdown&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING        number of seconds to &lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt; after the &lt;span class=&quot;token parameter variable&quot;&gt;--time&lt;/span&gt; limit before forcing shutdown, or &lt;span class=&quot;token string&quot;&gt;&apos;off&apos;&lt;/span&gt; to disable &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --thread-stack-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;SIZE        size of stack per thread &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;64K&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--rate&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                        average transactions rate. &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; unlimited rate &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --report-interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N             periodically report intermediate statistics with a specified interval &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; seconds. &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; disables intermediate reports &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --report-checkpoints&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;LIST,&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; dump full statistics and reset all counters at specified points &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; time. The argument is a list of comma-separated values representing the amount of &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; seconds elapsed from start of &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt; when report checkpoint&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; must be performed. Report checkpoints are off by default. &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --debug&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;                print &lt;span class=&quot;token function&quot;&gt;more&lt;/span&gt; debugging info &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --validate&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;             perform validation checks where possible &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --help&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;                 print &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt; and &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --version&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;              print version and &lt;span class=&quot;token builtin class-name&quot;&gt;exit&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --config-file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;FILENAME          File containing &lt;span class=&quot;token builtin class-name&quot;&gt;command&lt;/span&gt; line options
  --tx-rate&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                     deprecated &lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--rate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --max-requests&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                deprecated &lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--events&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --max-time&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                    deprecated &lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--time&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --num-threads&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                 deprecated &lt;span class=&quot;token builtin class-name&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--threads&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

Pseudo-Random Numbers Generator options:
  --rand-type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING random numbers distribution &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;uniform,gaussian,special,pareto&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;special&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --rand-spec-iter&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N number of iterations used &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; numbers generation &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --rand-spec-pct&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N  percentage of values to be treated as &lt;span class=&quot;token string&quot;&gt;&apos;special&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;for special distribution&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --rand-spec-res&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N  percentage of &lt;span class=&quot;token string&quot;&gt;&apos;special&apos;&lt;/span&gt; values to use &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;for special distribution&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --rand-seed&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N      seed &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; random number generator. When &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;, the current &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt; is used as a RNG seed. &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --rand-pareto-h&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N  parameter h &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; pareto distribution &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

Log options:
  &lt;span class=&quot;token parameter variable&quot;&gt;--verbosity&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N verbosity level &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; - debug, &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; - only critical messages&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

  &lt;span class=&quot;token parameter variable&quot;&gt;--percentile&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N       percentile to calculate &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; latency statistics &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;-100&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;. Use the special value of &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; to disable percentile calculations &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;95&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --histogram&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; print latency histogram &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; report &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

General database options:

  --db-driver&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING  specifies database driver to use &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;help&apos;&lt;/span&gt; to get list of available drivers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mysql&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --db-ps-mode&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING prepared statements usage mode &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;auto, disable&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;auto&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --db-debug&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; print database-specific debug information &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;


Compiled-in database drivers:
  mysql - MySQL driver

mysql options:
  --mysql-host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;LIST,&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;          MySQL server &lt;span class=&quot;token function&quot;&gt;host&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;localhost&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;LIST,&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;          MySQL server port &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3306&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-socket&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;LIST,&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;        MySQL socket
  --mysql-user&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING              MySQL user &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;sbtest&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-password&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING          MySQL password &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-db&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING                MySQL database name &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;sbtest&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-ssl&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;             use SSL connections, &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; available &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; the client library &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-ssl-cipher&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING        use specific cipher &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; SSL connections &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-compression&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;     use compression, &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; available &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; the client library &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-debug&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;           trace all client library calls &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-ignore-errors&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;LIST,&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; list of errors to ignore, or &lt;span class=&quot;token string&quot;&gt;&quot;all&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1213,1020&lt;/span&gt;,1205&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --mysql-dry-run&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;on&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;         Dry run, pretend that all MySQL client API calls are successful without executing them &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;off&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

Compiled-in tests:
  fileio - File I/O &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;
  cpu - CPU performance &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;
  memory - Memory functions speed &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;
  threads - Threads subsystem performance &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;
  mutex - Mutex performance &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt;

See &lt;span class=&quot;token string&quot;&gt;&apos;sysbench &amp;lt;testname&gt; help&apos;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; a list of options &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; each test.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;sysbench-fileio-help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#sysbench-fileio-help&quot; aria-label=&quot;sysbench fileio help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;sysbench fileio help&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ sysbench fileio &lt;span class=&quot;token builtin class-name&quot;&gt;help&lt;/span&gt;
sysbench &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;.18 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;using bundled LuaJIT &lt;span class=&quot;token number&quot;&gt;2.1&lt;/span&gt;.0-beta2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

fileio options:
  --file-num&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N                  number of files to create &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --file-block-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N           block size to use &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; all IO operations &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16384&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --file-total-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;SIZE        total size of files to create &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;2G&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --file-test-mode&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING       &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt; mode &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;seqwr, seqrewr, seqrd, rndrd, rndwr, rndrw&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  --file-io-mode&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;STRING         &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; operations mode &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sync,async,mmap&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;sync&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --file-extra-flags&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;LIST,&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; list of additional flags to use to &lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt; files &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sync,dsync,direct&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --file-fsync-freq&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N           &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; fsync&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; after this number of requests &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; - don&lt;span class=&quot;token string&quot;&gt;&apos;t use fsync()) [100]
  --file-fsync-all[=on|off]     do fsync() after each write operation [off]
  --file-fsync-end[=on|off]     do fsync() at the end of test [on]
  --file-fsync-mode=STRING      which method to use for synchronization {fsync, fdatasync} [fsync]
  --file-merged-requests=N      merge at most this number of IO requests if possible (0 - don&apos;&lt;/span&gt;t merge&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  --file-rw-ratio&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;N             reads/writes ratio &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; combined &lt;span class=&quot;token builtin class-name&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[NSQ Note]]></title><link>https://xenojoshua.com/posts/2020/12/nsq-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/12/nsq-note</guid><pubDate>Thu, 31 Dec 2020 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E7%AE%80%E4%BB%8B&quot;&gt;2. 简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%85%A5%E9%97%A8%E4%BD%BF%E7%94%A8&quot;&gt;3. 入门使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E7%BB%84%E4%BB%B6&quot;&gt;3.1 组件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E7%9B%91%E6%8E%A7&quot;&gt;3.2 监控&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E7%BB%86%E8%8A%82%E6%B7%B1%E5%85%A5&quot;&gt;4. 细节深入&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#nsqd%E6%B6%88%E6%81%AF%E4%B8%8D%E6%8C%81%E4%B9%85&quot;&gt;nsqd消息不持久&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#at-least-once&quot;&gt;at least once&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%B6%88%E6%81%AF%E7%9A%84%E6%8A%95%E9%80%92%E6%98%AF%E6%97%A0%E5%BA%8F%E7%9A%84&quot;&gt;消息的投递是无序的&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#nsqlookupd%E5%BB%B6%E8%BF%9F&quot;&gt;nsqlookupd延迟&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%80%A7%E8%83%BD&quot;&gt;性能&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#topic%E5%92%8Cchannel&quot;&gt;topic和channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%87%AA%E5%8A%A8%E6%B6%88%E5%A4%B1%E7%9A%84topic%E5%92%8Cchannel&quot;&gt;自动消失的topic和channel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#max-in-flight&quot;&gt;max-in-flight&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%87%8F%E8%BD%BBgc%E5%8E%8B%E5%8A%9B&quot;&gt;减轻GC压力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%B6%88%E6%81%AF%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F&quot;&gt;消息生命周期&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#admin-metrics&quot;&gt;Admin Metrics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E4%BD%BF%E7%94%A8%E8%8C%83%E4%BE%8B&quot;&gt;5. 使用范例&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#pubbeforesub&quot;&gt;pubBeforeSub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#samemessagemultichannel&quot;&gt;sameMessageMultiChannel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#subbeforepub&quot;&gt;subBeforePub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#errormessage&quot;&gt;errorMessage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h2&gt;
&lt;p&gt;说到消息队列一般就会直接想起Kafka、Rocket、Rabbit之类的全功能消息队列。但实际上在应用程序制作的过程中，我们也很需要一些小而精巧的消息队列用来进行某些业务上的解耦，或者降低主业务的消耗、耗时等。 类似于redis作者的这个：&lt;a href=&quot;https://github.com/antirez/disque&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;antirez / disque&lt;/a&gt;。其中Nsq就是一款非常小巧而实用的消息队列，特别是它还基于Go语言编写，特别符合性能要求以及当前云原生的大方向。&lt;/p&gt;
&lt;h2 id=&quot;2-简介&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E7%AE%80%E4%BB%8B&quot; aria-label=&quot;2 简介 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 简介&lt;/h2&gt;
&lt;p&gt;Nsq的官方网站在：&lt;a href=&quot;https://nsq.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nsq.io&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;一些比较关键的文档位置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/overview/quick_start.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Quick Start&lt;/a&gt;：快速上手使用&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/overview/features_and_guarantees.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;FEATURES &amp;#x26; GUARANTEES&lt;/a&gt;：一些核心功能点，和需要注意的特性&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/overview/faq.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;FAQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/overview/performance.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Performance&lt;/a&gt;：官方的性能测试指标&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/overview/design.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Design&lt;/a&gt;：Nsq的核心设计，应该是所有官方文档中最重要的一篇了&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/overview/internals.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;INTERNALS&lt;/a&gt;：一些Nsq内部实现相关的细节&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，还有一份PPT，虽然年代比较久远了（2012年），但基本上把所有Nsq中比较重要的点都提及到了，如果需要快速过一遍的话，看这篇PPT也是个不错的选择：&lt;a href=&quot;https://speakerdeck.com/snakes/nsq-nyc-golang-meetup&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;NSQ - NYC Golang Meetup&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;3-入门使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%85%A5%E9%97%A8%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;3 入门使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 入门使用&lt;/h2&gt;
&lt;p&gt;快速入门可以查看官方文档：&lt;a href=&quot;https://nsq.io/overview/quick_start.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Quick Start&lt;/a&gt;。Node的npm包在：&lt;a href=&quot;https://www.npmjs.com/package/nsqjs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nsqjs&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;31-组件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E7%BB%84%E4%BB%B6&quot; aria-label=&quot;31 组件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 组件&lt;/h3&gt;
&lt;p&gt;Nsq主要有3个组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;nsqd：真正的消息队列服务进程，消息收发都是由客户端直接和nsqd沟通完成，没有任何第三方中间成员&lt;/li&gt;
&lt;li&gt;nsqlookupd：消息队列的拓扑管理，主要负责：
&lt;ul&gt;
&lt;li&gt;nsqd的注册，存活管理&lt;/li&gt;
&lt;li&gt;topic和channel的管理，所有的topic有哪些，分别分布在哪几个nsqd上lookupd都知道&lt;/li&gt;
&lt;li&gt;客户端会先到lookupd上查询目标的topic，找到之后再与某个匹配的nsqd进行连接，最后收发消息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;nsqadmin：管理界面，功能非常丰富&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于各组件的启动参数，以及HTTP的API，都可以在官方文档中找到。需要记住的只有一点，末尾为0的端口都是TCP端口，1的端口都是HTTP端口。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqd.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;NSQD&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqd.html#debugging-and-profiling&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Debugging and Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqd.html#tls&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TLS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqd.html#auth&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;AUTH&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqd.html#end-to-end-processing-latency&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;End-to-End Processing Latency&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqd.html#statsd--graphite-integration&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Statsd / Graphite Integration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqlookupd.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;NSQLOOKUPD&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqlookupd.html#deletion-and-tombstones&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deletion and Tombstones&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqadmin.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;NSQADMIN&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqadmin.html#statsd--graphite-integration&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;statsd / Graphite Integration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqadmin.html#admin-notifications&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Admin Notifications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/nsqadmin.html#metrics&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Metrics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/utilities.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;UTILITIES&lt;/a&gt;：一系列实用的Nsq工具组件
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/utilities.html#nsq_stat&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nsq_stat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/utilities.html#nsq_tail&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nsq_tail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/utilities.html#nsq_to_file&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nsq_to_file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/utilities.html#nsq_to_http&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nsq_to_http&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/utilities.html#nsq_to_nsq&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;nsq_to_nsq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nsq.io/components/utilities.html#to_nsq&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;to_nsq&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;32-监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;32 监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 监控&lt;/h3&gt;
&lt;p&gt;作为go语言编写的组件，理所当然的Nsq的各组件会暴露HTTP的&lt;code class=&quot;language-text&quot;&gt;/debug/pprof&lt;/code&gt;终端，作为性能查询的输出终端。&lt;/p&gt;
&lt;h2 id=&quot;4-细节深入&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E7%BB%86%E8%8A%82%E6%B7%B1%E5%85%A5&quot; aria-label=&quot;4 细节深入 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 细节深入&lt;/h2&gt;
&lt;p&gt;接下来的章节，我会把所有我个人觉得比较重要的Nsq相关内容都列进去。&lt;/p&gt;
&lt;h3 id=&quot;nsqd消息不持久&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#nsqd%E6%B6%88%E6%81%AF%E4%B8%8D%E6%8C%81%E4%B9%85&quot; aria-label=&quot;nsqd消息不持久 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;nsqd消息不持久&lt;/h3&gt;
&lt;p&gt;默认行为是所有收到的消息都存储在nsqd的内存中，且没有任何内建的replication机制。所以默认情况下，节点挂掉的话，消息会丢失，如果这种情况不可接受，就需要自己做一些机制来规避消息丢失。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;--mem-queue-size&lt;/code&gt;参数可以限定存储在内存中的消息数量，如果超量，则会将后续的消息存储在磁盘上。将该值设置为0可以将消息全部存储在磁盘上。&lt;/p&gt;
&lt;h3 id=&quot;at-least-once&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#at-least-once&quot; aria-label=&quot;at least once permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;at least once&lt;/h3&gt;
&lt;p&gt;消息消费失败或超时会requeue，并在后续重新进行分发，所以一条消息可能会被多次投递到client进行消费，以保证该消息确定被消费完毕。消费者需要做好幂等，否则一条消息可能会别重复消费多次。&lt;/p&gt;
&lt;h3 id=&quot;消息的投递是无序的&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%B6%88%E6%81%AF%E7%9A%84%E6%8A%95%E9%80%92%E6%98%AF%E6%97%A0%E5%BA%8F%E7%9A%84&quot; aria-label=&quot;消息的投递是无序的 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;消息的投递是无序的&lt;/h3&gt;
&lt;p&gt;nsqd只管将消息按顺序投递出去，但消息可能因为网络原因等导致最终消费的顺序和投递的顺序不一致。&lt;/p&gt;
&lt;h3 id=&quot;nsqlookupd延迟&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#nsqlookupd%E5%BB%B6%E8%BF%9F&quot; aria-label=&quot;nsqlookupd延迟 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;nsqlookupd延迟&lt;/h3&gt;
&lt;p&gt;服务发现被设计为最终一致。在扩散的过程中，可能会有时间差。客户端会最终从nsqlookupd获得所有的topic信息。&lt;/p&gt;
&lt;p&gt;测试应用中很可能出现的一情况就是：nsqlookupd上并没有任何topic消息，producer创建，nsqd上创建出topic，并在之后同步topic信息到nsqlookupd。而在这之前早得多consumer就已经连上nsqlookupd并没有收到任何topic的信息，这中间会有一个时间差。consumer会静止在那里，直到配置的lookup间隔时间到了，然后consumer会再次查询nsqlookupd，并最终或得到topic信息以及所属的nsqd。&lt;/p&gt;
&lt;p&gt;可以看下这几个comment：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nsqio/nsqio.github.io/issues/42#issuecomment-432905203&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;docs: clarify when topics are created automatically #42 #comment-432905203&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/nsqio/nsqio.github.io/issues/42#issuecomment-432905514&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;docs: clarify when topics are created automatically #42 #comment-432905514&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;性能&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%80%A7%E8%83%BD&quot; aria-label=&quot;性能 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;性能&lt;/h3&gt;
&lt;p&gt;看官方文档：&lt;a href=&quot;https://nsq.io/overview/performance.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Performance&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;topic和channel&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#topic%E5%92%8Cchannel&quot; aria-label=&quot;topic和channel permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;topic和channel&lt;/h3&gt;
&lt;p&gt;估计这是使用Nsq的程序员最初最难搞懂的东西。一般来说其他的消息队列都是将消息发布到topic中，然后多个consumer消费一个topic。但Nsq在topic和consumer之间还插入了一个channel的概念。&lt;/p&gt;
&lt;p&gt;这里主要是看一个图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/12/nsq-note/nsq_topic_channel.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;需要理解的最重要的概念是，同一个topic下的所有channel，都会得到进入topic的消息的拷贝。同样一份消息，进入topic后会分别拷贝并进入每一个channel，每个channel都需要各自的consumer把消息消费掉，否则就会造成消息积压。&lt;/p&gt;
&lt;p&gt;简单来说：如果你希望和一般的消息队列一样的 topic =&gt; consumers，那么就让所有该topic下的消费者使用同一个channel即可。&lt;/p&gt;
&lt;p&gt;channel的设计让Nsq可以做一些其他消息队列做不到的用途，最为常见的是：消息广播。多个consumer都需要在某个业务触发的时候得到通知，那么就在某个topic下，让所有的consumer都定义一个自己的channel连接进去（topic_channel_node_1/…），这样所有的consumer都各自占据了一个channel，而所有的channel都会得到topic内消息的拷贝，所以他们会都得到同样的消息通知。&lt;/p&gt;
&lt;h3 id=&quot;自动消失的topic和channel&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%87%AA%E5%8A%A8%E6%B6%88%E5%A4%B1%E7%9A%84topic%E5%92%8Cchannel&quot; aria-label=&quot;自动消失的topic和channel permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;自动消失的topic和channel&lt;/h3&gt;
&lt;p&gt;topic和channel都是持久化的，默认情况下在创建成功后，他们都是不会自动消失的，时间长了之后清理就会比较麻烦。而上面的例子中那种类似消息通知的情况，其实topic和channel都是生命周期非常短暂的，一般我们希望他们在没用了之后就被销毁掉。&lt;/p&gt;
&lt;p&gt;在topic和channel的名字后面添加&lt;code class=&quot;language-text&quot;&gt;#ephemeral&lt;/code&gt;可以做到这点，当所有连接在topic或channel上的producer/consumer都断开连接之后，nsqd就会自动删除该topic或channel。&lt;/p&gt;
&lt;p&gt;需要注意的是，&lt;code class=&quot;language-text&quot;&gt;#ephemeral&lt;/code&gt;命名的topic/channel在超过&lt;code class=&quot;language-text&quot;&gt;--mem-queue-size&lt;/code&gt;的限制之后不会将消息写入磁盘，而是直接丢弃。这点行为上和普通的topic/channel非常不同，一定要小心注意。&lt;/p&gt;
&lt;h3 id=&quot;max-in-flight&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#max-in-flight&quot; aria-label=&quot;max in flight permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;max-in-flight&lt;/h3&gt;
&lt;p&gt;客户端可以设置该值（比如说10），然后客户端在连接到nsqd的时候会发送&lt;code class=&quot;language-text&quot;&gt;RDY 10&lt;/code&gt;过去，nsqd就会知道该client的同时处理能力。在接下来的消息推送过程中，nsqd会不断向该client推送消息，直到目前已分发且尚未反馈结果的消息数量达到该数值（10）为止。这是为了更好的性能，client程序如果实现了多线程的话，可以充分利用线程和CPU来消费消息，而不是只有一个线程在工作，其他的都在闲置。&lt;/p&gt;
&lt;p&gt;对于node程序来说，这个数值就没有意义了，因为node进程只有一个工作线程。&lt;/p&gt;
&lt;p&gt;还可以看下这个comment：&lt;a href=&quot;https://github.com/nsqio/go-nsq/issues/221#issuecomment-352865779&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Question about concurrency and Max in Flight #221&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;减轻gc压力&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%87%8F%E8%BD%BBgc%E5%8E%8B%E5%8A%9B&quot; aria-label=&quot;减轻gc压力 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;减轻GC压力&lt;/h3&gt;
&lt;p&gt;见官方文档：&lt;a href=&quot;https://nsq.io/overview/internals.html#reducing-gc-pressure&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Reducing GC Pressure&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;消息生命周期&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%B6%88%E6%81%AF%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F&quot; aria-label=&quot;消息生命周期 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;消息生命周期&lt;/h3&gt;
&lt;p&gt;一条消息的生命周期（消费端）主要是控制在client手中，这点和普通的消息队列的设计理念完全不同，这里需要花点时间稍微整理下。&lt;/p&gt;
&lt;p&gt;消息的创建是producer连接到nsqd，并进行publish的操作，这点没有任何问题。创建成功消息就收到了，失败的话，则消息在nsqd上不存在。&lt;/p&gt;
&lt;p&gt;消息的消费由nsqd向连接的consumer进行推送：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;消息已分发且尚未反馈（未到超时时间），状态：In-Flight&lt;/li&gt;
&lt;li&gt;消息已分发且超时没有反馈（该超时的时长是在客户端设置的！），状态：Time Out，该消息会被nsqd重新requeue（REQ）
&lt;ul&gt;
&lt;li&gt;消息在处理中，且耗时很长，可以由客户端进行 Touch，这样该消息就不会Time Out&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;消息发送后，可以由客户端主动进行requeue（REQ）
&lt;ul&gt;
&lt;li&gt;requeue行为可以附带设置延迟（Deferred）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;消息发送后，如果客户端出错被认为是有问题的，客户端自身需要恢复，则客户端可以将该消息反馈为backoff，这个操作会导致：
&lt;ul&gt;
&lt;li&gt;nsqd会将该消息requeue，消息本身会再次（如果设置延迟的话，也会Deferred）分发&lt;/li&gt;
&lt;li&gt;此外这个操作会导致客户端将自身的RDY设置为0，意味着这个客户端短时间内将拒绝处理任何消息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;消息发送后，如果该消息之前被requeue则该消息会附带Attempts（重试）数，客户端在尝试失败后，会匹配失败次数，如果超过限制，则该消息会被DISCARD，即客户端会直接将该消息标记为Finished（FIN）
&lt;ul&gt;
&lt;li&gt;如果客户端的max attempts设置为0，则可以无限次重试，不会被discard&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;消息发送后，可以由客户端标记为完成Finished（FIN）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以看到Nsq的客户端有很大的权利，特别是失败重试的决策是由客户端做的，如果超限消息就会被丢弃，标记为完成。&lt;/p&gt;
&lt;p&gt;更多关于Timeout相关，请见comment：&lt;a href=&quot;https://github.com/nsqio/nsq/issues/1028#issuecomment-385126434&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Timeout options #1028&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;关于requeue和backoff的详细分析，可以看这篇：&lt;a href=&quot;https://github.com/judwhite/NsqSharp/wiki/NSQ-Requeue-and-Backoff&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;NSQ Requeue and Backoff&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;admin-metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#admin-metrics&quot; aria-label=&quot;admin metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://nsq.io/components/nsqadmin.html#metrics&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Admin Metrics&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Admin统计数据里的一些词汇可以简单解释下：&lt;/p&gt;
&lt;p&gt;Message Queues：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Depth：当前存储在内存和磁盘上的消息总量（尚未被分发）&lt;/li&gt;
&lt;li&gt;In-Flight：目前已经被分发，但尚未被标记为 完成（FIN）、重新入队（REQ）或是超时的消息总量&lt;/li&gt;
&lt;li&gt;Deferred：目前被重新入队且显式标记为推迟处理并且尚未到重新分发阶段的消息总量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Statistics：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Requeued：消息因超时或被显式要求而重新入队的次数&lt;/li&gt;
&lt;li&gt;Timed Out：消息因超过设定的超时时长未响应，而被标记为超时的次数&lt;/li&gt;
&lt;li&gt;Messages：在节点启动之后收到的消息总数&lt;/li&gt;
&lt;li&gt;Rate：过去两次statsd间隔间，每秒新收到的消息数量&lt;/li&gt;
&lt;li&gt;Connections：连接总数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Client Connections：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;NSQd Host：Address of the nsqd node this client is connected to.&lt;/li&gt;
&lt;li&gt;In-flight：当前发送给该client等待返回的消息数量&lt;/li&gt;
&lt;li&gt;Ready Count：当前client节点最高in-flight可能的消息数量&lt;/li&gt;
&lt;li&gt;Finished：所有当前client节点标记为FIN的消息数量&lt;/li&gt;
&lt;li&gt;Requeued：同上，REQ&lt;/li&gt;
&lt;li&gt;Messages：所有发送给该client节点的消息数量&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;5-使用范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E4%BD%BF%E7%94%A8%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;5 使用范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 使用范例&lt;/h2&gt;
&lt;p&gt;光说理论上的东西比较枯燥，实践操作也是比较重要的，下面可以通过几个例子来看下Nsq的一些行为。&lt;/p&gt;
&lt;h3 id=&quot;pubbeforesub&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#pubbeforesub&quot; aria-label=&quot;pubbeforesub permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;pubBeforeSub&lt;/h3&gt;
&lt;p&gt;If there is no topic on &lt;code class=&quot;language-text&quot;&gt;nsqd&lt;/code&gt; (first execution), reader will suck for a long time. Since at the first time reader connect to lookupd, there hasn’t been updated with the published topics info yet. So it will suck until readers retrieve topics info next time.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;pubBeforeSub:
    Two writers initialized
    Two writers publish &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; messages each into topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC1&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;total &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    One of the writer publish &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; message into topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC2_UNI&quot;&lt;/span&gt;
    Two readers created &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC1&quot;&lt;/span&gt; with the same channel &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC1_READER_CHANNEL&quot;&lt;/span&gt;
    One reader created &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC2_UNI&quot;&lt;/span&gt; with channel &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC2_UNI#ephemeral&quot;&lt;/span&gt;
    -
    Two readers share the total &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; messages &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC1&quot;&lt;/span&gt;
    One reader consume the message &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC2_UNI&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;➜  couchnsq git:&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;master&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; ✗ ./bash/nsq_run.sh
  Nsq:Writer:bgF6l bgF6l: ready +0ms
  Nsq:Writer:Plwtx Plwtx: ready +0ms
  Nsq:Reader:oiFQg oiFQg: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4250&quot;&lt;/span&gt; +0ms
  Nsq:Reader:oiFQg oiFQg: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4150&quot;&lt;/span&gt; +0ms
  Nsq:Reader:MmLbX MmLbX: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4250&quot;&lt;/span&gt; +0ms
  Nsq:Reader:MmLbX MmLbX: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4150&quot;&lt;/span&gt; +0ms
  Nsq:Reader:8hpju 8hpju: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4250&quot;&lt;/span&gt; +0ms
  Nsq:Reader:oiFQg oiFQg: message 0e38318eeb01e000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC1:jQ77FfY8lS&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +16ms
  Nsq:Message oiFQg: message 0e38318eeb01e000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38318eeb01e000
  Nsq:Message &quot;&lt;/span&gt; +0ms
  Nsq:Reader:MmLbX MmLbX: message 0e38318eeb01e001 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC1:ONvD8mH4Jq&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +16ms
  Nsq:Message MmLbX: message 0e38318eeb01e001 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38318eeb01e001
  Nsq:Message &quot;&lt;/span&gt; +1ms
  Nsq:Reader:8hpju 8hpju: ready +17ms
  Nsq:Reader:MmLbX MmLbX: message 0e38318eeb01e002 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC1:7xjankTlzU&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +3ms
  Nsq:Message MmLbX: message 0e38318eeb01e002 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38318eeb01e002
  Nsq:Message &quot;&lt;/span&gt; +3ms
  Nsq:Reader:oiFQg oiFQg: message 0e38318eeb435000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC1:bQOiIt7BLE&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +5ms
  Nsq:Message oiFQg: message 0e38318eeb435000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38318eeb435000
  Nsq:Message &quot;&lt;/span&gt; +1ms
  Nsq:Reader:8hpju 8hpju: message 0e38318eec435000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC2_UNI:Ms10V0jtpc&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +3ms
  Nsq:Message 8hpju: message 0e38318eec435000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38318eec435000
  Nsq:Message &quot;&lt;/span&gt; +1ms
  Nsq:Reader:MmLbX MmLbX: message 0e38318eeb435001 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC1:APZJDBiVP9&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +3ms
  Nsq:Message MmLbX: message 0e38318eeb435001 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38318eeb435001
  Nsq:Message &quot;&lt;/span&gt; +1ms
  Nsq:Reader:MmLbX MmLbX: message 0e38318eeb435002 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC1:CXF6AQVBDr&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +53ms
  Nsq:Message MmLbX: message 0e38318eeb435002 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38318eeb435002
  Nsq:Message &quot;&lt;/span&gt; +53ms
^C  Nsq:Writer:bgF6l bgF6l: closed +1m
  Nsq:Writer:Plwtx Plwtx: closed +1m
  Nsq:Reader:oiFQg oiFQg: notReady +26s
  Nsq:Reader:MmLbX MmLbX: notReady +25s
  Nsq:Reader:8hpju 8hpju: notReady +26s
NsqTest: all cleared&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;samemessagemultichannel&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#samemessagemultichannel&quot; aria-label=&quot;samemessagemultichannel permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;sameMessageMultiChannel&lt;/h3&gt;
&lt;p&gt;Multiple channels subscribe the same topic will receive duplicate messages.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;sameMessageMultiChannel:
    Two writers initialized
    One of the writer publish &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; message into topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC_SAME&quot;&lt;/span&gt;
    Two readers created &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC_SAME&quot;&lt;/span&gt; with two channels &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC_SAME_CHANNEL_1/2&quot;&lt;/span&gt; subscribe the same topic
    -
    Two readers receive the same message&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;➜  couchnsq git:&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;master&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; ✗ ./bash/nsq_run.sh
  Nsq:Writer:oeAOC oeAOC: ready +0ms
  Nsq:Writer:EdW9U EdW9U: ready +0ms
  Nsq:Reader:SuqpY SuqpY: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4250&quot;&lt;/span&gt; +0ms
  Nsq:Reader:vKCk9 vKCk9: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4250&quot;&lt;/span&gt; +0ms
  Nsq:Reader:vKCk9 vKCk9: ready +5ms
  Nsq:Reader:SuqpY SuqpY: ready +6ms
  Nsq:Reader:vKCk9 vKCk9: message 0e38322140035000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC_SAME:Hn4tB5UA0N&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +3ms
  Nsq:Message vKCk9: message 0e38322140035000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38322140035000
  Nsq:Message &quot;&lt;/span&gt; +0ms
  Nsq:Reader:SuqpY SuqpY: message 0e38322140035000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC_SAME:Hn4tB5UA0N&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +3ms
  Nsq:Message SuqpY: message 0e38322140035000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38322140035000
  Nsq:Message &quot;&lt;/span&gt; +0ms
^C  Nsq:Writer:oeAOC oeAOC: closed +3s
  Nsq:Writer:EdW9U EdW9U: closed +3s
  Nsq:Reader:vKCk9 vKCk9: notReady +3s
  Nsq:Reader:SuqpY SuqpY: notReady +3s
NsqTest: all cleared&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;subbeforepub&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#subbeforepub&quot; aria-label=&quot;subbeforepub permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;subBeforePub&lt;/h3&gt;
&lt;p&gt;If the topic not deleted before execution (or first run). Reader will suck for a long time, the reason have been explained previously.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;subBeforePub:
    Two writers initialized
    One reader create to subscribe an non-existing topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC_UNKNOWN&quot;&lt;/span&gt;
    One of the writer &lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt; 1000ms, &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; publish &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; message into topic &lt;span class=&quot;token string&quot;&gt;&quot;TOPIC_UNKNOWN&quot;&lt;/span&gt;
    -
    One reader &lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; a long &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;then&lt;/span&gt; receive the message&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;➜  couchnsq git:&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;master&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; ✗ ./bash/nsq_run.sh
  Nsq:Writer:2Fr6p 2Fr6p: ready +0ms
  Nsq:Writer:vFIw5 vFIw5: ready +0ms
  Nsq:Reader:uR6Lp uR6Lp: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4150&quot;&lt;/span&gt; +0ms
  Nsq:Reader:uR6Lp uR6Lp: ready +5ms
  Nsq:Reader:uR6Lp uR6Lp: message 0e38323df741e000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;TOPIC_UNKNOWN:kCwBySUMY0&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +984ms
  Nsq:Message uR6Lp: message 0e38323df741e000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;0&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;FIN 0e38323df741e000
  Nsq:Message &quot;&lt;/span&gt; +0ms
^C  Nsq:Writer:2Fr6p 2Fr6p: closed +3s
  Nsq:Writer:vFIw5 vFIw5: closed +3s
  Nsq:Reader:uR6Lp uR6Lp: notReady +2s
NsqTest: all cleared&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;errormessage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#errormessage&quot; aria-label=&quot;errormessage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;errorMessage&lt;/h3&gt;
&lt;p&gt;Send error message, and message would be requeue with backoff in the reader, finally it would be discarded (finished).&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;maxAttempts&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;➜  couchnsq git:&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;master&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; ✗ ./bash/nsq_run.sh
  Nsq:Writer:5P9rd 5P9rd: ready +0ms
  Nsq:Writer:KKhyz KKhyz: ready +0ms
  Nsq:Reader:hSWmK hSWmK: nsqd connected: &lt;span class=&quot;token string&quot;&gt;&quot;10.10.2.126:4150&quot;&lt;/span&gt; +0ms
  Nsq:Reader:hSWmK hSWmK: ready +5ms
  Nsq:Reader:hSWmK hSWmK: message 0e3832a5bb01e000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;should throw error:WGZ9VlLLPa&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +4ms
  Nsq:Reader:hSWmK hSWmK: message 0e3832a5bb01e000 error &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; requeue, attempts: &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; +1ms
  Nsq:Message hSWmK: message 0e3832a5bb01e000 backoff +0ms
  Nsq:Message hSWmK: message 0e3832a5bb01e000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;REQ 0e3832a5bb01e000 2000
  Nsq:Message &quot;&lt;/span&gt; +1ms
  Nsq:Reader:hSWmK hSWmK: message 0e3832a5bb01e000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;should throw error:WGZ9VlLLPa&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +4s
  Nsq:Reader:hSWmK hSWmK: message 0e3832a5bb01e000 error &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; requeue, attempts: &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; +0ms
  Nsq:Message hSWmK: message 0e3832a5bb01e000 backoff +4s
  Nsq:Message hSWmK: message 0e3832a5bb01e000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;REQ 0e3832a5bb01e000 2000
  Nsq:Message &quot;&lt;/span&gt; +0ms
  Nsq:Reader:hSWmK hSWmK: message 0e3832a5bb01e000 got: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;should throw error:WGZ9VlLLPa&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +7s
  Nsq:Reader:hSWmK hSWmK: message 0e3832a5bb01e000 error &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; requeue, attempts: &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; +0ms
  Nsq:Message hSWmK: message 0e3832a5bb01e000 backoff +7s
  Nsq:Message hSWmK: message 0e3832a5bb01e000 respond: &lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;REQ 0e3832a5bb01e000 2000
  Nsq:Message &quot;&lt;/span&gt; +0ms
  Nsq:Reader:hSWmK hSWmK: message discarded: &lt;span class=&quot;token string&quot;&gt;&quot;{&quot;&lt;/span&gt;msg&lt;span class=&quot;token string&quot;&gt;&quot;:&quot;&lt;/span&gt;should throw error:WGZ9VlLLPa&lt;span class=&quot;token string&quot;&gt;&quot;}&quot;&lt;/span&gt; +11s
^C  Nsq:Writer:5P9rd 5P9rd: closed +23s
  Nsq:Writer:KKhyz KKhyz: closed +23s
  Nsq:Reader:hSWmK hSWmK: notReady +2s
NsqTest: all cleared&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[使用frp内网穿透进行ssh登录]]></title><link>https://xenojoshua.com/posts/2020/10/frp</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/10/frp</guid><pubDate>Mon, 19 Oct 2020 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot;&gt;前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9E%B6%E6%9E%84%E4%B8%8E%E5%9C%BA%E6%99%AF%E7%90%86%E8%A7%A3&quot;&gt;架构与场景理解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85&quot;&gt;安装&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9C%8D%E5%8A%A1%E7%AB%AF&quot;&gt;服务端&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%A2%E6%88%B7%E7%AB%AF&quot;&gt;客户端&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%9C%80%E7%BB%88%E4%BD%BF%E7%94%A8&quot;&gt;最终使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#links&quot;&gt;Links&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot; aria-label=&quot;前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;前言&lt;/h2&gt;
&lt;p&gt;内网穿透工具frp，有需要的人肯定已经了解它是什么了，不知道的可以去官网看下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/fatedier/frp&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;fatedier/frp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;架构与场景理解&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%9E%B6%E6%9E%84%E4%B8%8E%E5%9C%BA%E6%99%AF%E7%90%86%E8%A7%A3&quot; aria-label=&quot;架构与场景理解 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;架构与场景理解&lt;/h2&gt;
&lt;p&gt;这块网上其实已经有相当多的文章进行过阐述了，这里就简单说一些我的理解。&lt;/p&gt;
&lt;p&gt;首先需要明确角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户：需要从外部（公网上）访问&lt;code class=&quot;language-text&quot;&gt;内部服务&lt;/code&gt;的人&lt;/li&gt;
&lt;li&gt;frp服务端：处于公网上，拥有固定IP或者固定域名的主机；必须是主机，需要可以在这台主机上安装frp的服务端程序&lt;/li&gt;
&lt;li&gt;frp客户端：处于内网上，缺失固定IP或者从公网上无法访问得到的一些局域网内主机；同样必须是主机，必须可以安装frp的客户端程序&lt;/li&gt;
&lt;li&gt;内部服务：可以是和frp客户端安装在同一台主机上的应用程序，也可能是和frp客户端处于同一内网的某一台主机上的一些应用程序&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果内部服务这台主机在公网上可以直接访问得到，那么用户就可以直接过去访问，就没有frp什么事情了。但很多情况就是如此不尽如人意，某些服务和主机就是隐藏在一些内部私有的网络里面的，在公网上是没办法直接访问的。&lt;/p&gt;
&lt;p&gt;这时候就需要在公网的主机上安装frp服务端程序，作为一个大家的目标（后续用户和frp客户端都会主动连接到这台主机上，这个主机是双向标的）。用户连接上来是为了访问内部服务，而frp客户端连接上来，则是为了告知frp服务端，内部服务到底在哪里。因为处于内网的服务，frp服务端也不能主动得知，必须frp客户端主动连接上去告知服务端，我在这里。&lt;/p&gt;
&lt;p&gt;上面是一些比较感性的理解，具体的可以看图（注意图上的&lt;code class=&quot;language-text&quot;&gt;s&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;c&lt;/code&gt;，frps就是刚才说的frp服务端，而frpc则是frp客户端）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/10/frp/frp_arch.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85&quot; aria-label=&quot;安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;安装&lt;/h2&gt;
&lt;p&gt;安装分为服务端和客户端两部分。frp在大部分的linux发行版本上都是没有的，所以一般需要直接从github上下载release包，具体可以到&lt;a href=&quot;https://github.com/fatedier/frp/releases&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;这里&lt;/a&gt;查看。&lt;/p&gt;
&lt;p&gt;下面的例子都以ubuntu为例，应用场景都是：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;用户 =&gt; frp服务端（公网） =&gt; frp客户端（私有网络） =&gt; 目标内部主机ssh（私有网络）&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;服务端&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%9C%8D%E5%8A%A1%E7%AB%AF&quot; aria-label=&quot;服务端 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;服务端&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;uname&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt;
x86_64
$ &lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; https://github.com/fatedier/frp/releases/download/v0.34.1/frp_0.34.1_linux_amd64.tar.gz
$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; zxvf frp_0.34.1_linux_amd64.tar.gz
$ &lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; ./frp_0.34.1_linux_amd64.tar.gz
$ &lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ./frp_0.34.1_linux_amd64 ./frp
$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; frp
$ &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; frps.ini&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token key attr-name&quot;&gt;bind_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;7000&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;some_secret_string&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;dashboard_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;7500&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;dashboard_user&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;user_name&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;dashboard_pwd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;user_password&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bind_port：frp客户端连接frp服务端的端口号&lt;/li&gt;
&lt;li&gt;token：frp客户端连接服务端需要一致的秘钥（客户端和服务端两者的ini配置文件里这个字串必须一致）&lt;/li&gt;
&lt;li&gt;dashboard_port：frp服务端暴露出来，让管理员监控的面板的端口号&lt;/li&gt;
&lt;li&gt;dashboard_user：监控面板的用户名&lt;/li&gt;
&lt;li&gt;dashboard_pwd：监控面板的用户密码&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接下来创建ubuntu的开机启动和daemon控制：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; /etc/systemd/system/frps.service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;填写内容：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;frps daemon&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;After&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;syslog.target  network.target&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Wants&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;network.target&lt;/span&gt;

&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;simple&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;ExecStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;/path_to_frp/frps -c /path_to_frp/frps.ini&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;always&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;RestartSec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;1min&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;ExecStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;/usr/bin/killall frps&lt;/span&gt;

&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;Install&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;WantedBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;multi-user.target&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;启动、设置开机启动、重启，三个命令：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl start frps
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl &lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; frps
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl restart frps&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;客户端&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%AE%A2%E6%88%B7%E7%AB%AF&quot; aria-label=&quot;客户端 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;客户端&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;uname&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-m&lt;/span&gt;
x86_64
$ &lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; https://github.com/fatedier/frp/releases/download/v0.34.1/frp_0.34.1_linux_amd64.tar.gz
$ &lt;span class=&quot;token function&quot;&gt;tar&lt;/span&gt; zxvf frp_0.34.1_linux_amd64.tar.gz
$ &lt;span class=&quot;token function&quot;&gt;rm&lt;/span&gt; ./frp_0.34.1_linux_amd64.tar.gz
$ &lt;span class=&quot;token function&quot;&gt;mv&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; ./frp_0.34.1_linux_amd64 ./frp
$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; frp
$ &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; frpc.ini&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;common&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;server_addr&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;some_ip&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;server_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;7000&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;token&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;some_secret_string&lt;/span&gt;

&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;ssh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;tcp&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;local_ip&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;127.0.0.1&lt;/span&gt; 
&lt;span class=&quot;token key attr-name&quot;&gt;local_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;22&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;remote_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;6000&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;server_addr：frp服务端所在的机器的IP，也就是公网上的那台&lt;/li&gt;
&lt;li&gt;server_port：这个端口号记得和之前服务端的配置一致&lt;/li&gt;
&lt;li&gt;token：这个也必须和之前服务端的配置一致&lt;/li&gt;
&lt;li&gt;local_port：内部服务所在那台机器，也就目标登录机的ssh端口号&lt;/li&gt;
&lt;li&gt;remote_port：这个端口号，是指&lt;code class=&quot;language-text&quot;&gt;frpc的local_port&lt;/code&gt;应该映射到&lt;code class=&quot;language-text&quot;&gt;frps主机上的哪个端口号&lt;/code&gt;，也就是最终用户ssh登录时使用的端口号&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;仍旧需要创建ubuntu的开机启动和daemon控制：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; /etc/systemd/system/frpc.service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;填写内容：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;frpc daemon&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;After&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;syslog.target  network.target&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Wants&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;network.target&lt;/span&gt;

&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;Service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;simple&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;ExecStart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;/path_to_frp/frpc -c /path_to_frp/frpc.ini&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;Restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;always&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;RestartSec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;1min&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;ExecStop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;/usr/bin/killall frpc&lt;/span&gt;

&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;Install&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;WantedBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value attr-value&quot;&gt;multi-user.target&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;启动、设置开机启动、重启，三个命令：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl start frpc
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl &lt;span class=&quot;token builtin class-name&quot;&gt;enable&lt;/span&gt; frpc
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; systemctl restart frpc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;最终使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%9C%80%E7%BB%88%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;最终使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;最终使用&lt;/h2&gt;
&lt;p&gt;最终用户ssh登录的时候，使用的命令如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;ssh&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6000&lt;/span&gt; user@frps_ip&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;links&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#links&quot; aria-label=&quot;links permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/fatedier/frp/issues/176&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;frp怎样开机启动和后台运行?#176&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/42071021&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;搭建frp用作内网SSH穿透&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zjun.info/2020/frptest.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;frp内网穿透原理及实战应用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sspai.com/post/52523&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用frp进行内网穿透&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hi-linux.com/posts/25686.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;推荐一款很好用的内网穿透工具 FRP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[使用proxychains进行命令行proxy设置]]></title><link>https://xenojoshua.com/posts/2020/10/proxychains</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/10/proxychains</guid><pubDate>Mon, 19 Oct 2020 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot;&gt;前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85&quot;&gt;安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#mac%E4%B8%8B%E7%9A%84sip%E9%97%AE%E9%A2%98&quot;&gt;MAC下的SIP问题&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot; aria-label=&quot;前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;前言&lt;/h2&gt;
&lt;p&gt;proxychains是一款相当好用的命令行命令proxy设置工具。一般来说使用ssh登录、curl、wget等一系列命令，有的时候都很需要进行proxy设置，理由么大家都懂的。这时候有像proxychains这样的工具就会非常方便。&lt;/p&gt;
&lt;p&gt;官网：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rofl0r/proxychains-ng&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;rofl0r/proxychains-ng&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%AE%89%E8%A3%85&quot; aria-label=&quot;安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;安装&lt;/h2&gt;
&lt;p&gt;在MAC下安装仍旧非常简单：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ brew update &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;
$ brew &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; proxychains-ng &lt;span class=&quot;token parameter variable&quot;&gt;--verbose&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后创建配置文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;mkdir&lt;/span&gt; ~/.proxychains
$ &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt; ~/.proxychains/proxychains.conf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;内容如下，其实也就没几条有用的：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# proxychains.conf  VER 4.x&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#        HTTP, SOCKS4a, SOCKS5 tunneling proxifier with DNS.&lt;/span&gt;


&lt;span class=&quot;token comment&quot;&gt;# The option below identifies how the ProxyList is treated.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# only one option should be uncommented at time,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# otherwise the last appearing option will be accepted&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
dynamic_chain
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Dynamic - Each connection will be done via chained proxies&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# all proxies chained in the order as they appear in the list&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# at least one proxy must be online to play in chain&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# (dead proxies are skipped)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# otherwise EINTR is returned to the app&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#strict_chain&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Strict - Each connection will be done via chained proxies&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# all proxies chained in the order as they appear in the list&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# all proxies must be online to play in chain&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# otherwise EINTR is returned to the app&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#round_robin_chain&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Round Robin - Each connection will be done via chained proxies&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# of chain_len length&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# all proxies chained in the order as they appear in the list&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# at least one proxy must be online to play in chain&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# (dead proxies are skipped).&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# the start of the current proxy chain is the proxy after the last&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# proxy in the previously invoked proxy chain.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# if the end of the proxy chain is reached while looking for proxies&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# start at the beginning again.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# otherwise EINTR is returned to the app&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# These semantics are not guaranteed in a multithreaded environment.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#random_chain&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Random - Each connection will be done via random proxy&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# (or proxy chain, see  chain_len) from the list.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# this option is good to test your IDS :)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Make sense only if random_chain or round_robin_chain&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#chain_len = 2&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Quiet mode (no output from library)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#quiet_mode&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Proxy DNS requests - no leak for DNS data&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#proxy_dns&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# set the class A subnet number to use for the internal remote DNS mapping&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# we use the reserved 224.x.x.x range by default,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# if the proxified app does a DNS request, we will return an IP from that range.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# on further accesses to this ip we will send the saved DNS name to the proxy.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# in case some control-freak app checks the returned ip, and denies to&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# connect, you can use another subnet, e.g. 10.x.x.x or 127.x.x.x.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# of course you should make sure that the proxified app does not need&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# *real* access to this subnet.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# i.e. dont use the same subnet then in the localnet section&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#remote_dns_subnet 127&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#remote_dns_subnet 10&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#remote_dns_subnet 224&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Some timeouts in milliseconds&lt;/span&gt;
tcp_read_time_out 15000
tcp_connect_time_out 8000

&lt;span class=&quot;token comment&quot;&gt;### Examples for localnet exclusion&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## localnet ranges will *not* use a proxy to connect.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## Exclude connections to 192.168.1.0/24 with port 80&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# localnet 192.168.1.0:80/255.255.255.0&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;## Exclude connections to 192.168.100.0/24&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# localnet 192.168.100.0/255.255.255.0&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;## Exclude connections to ANYwhere with port 80&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# localnet 0.0.0.0:80/0.0.0.0&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;## RFC5735 Loopback address range&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## if you enable this, you have to make sure remote_dns_subnet is not 127&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## you&apos;ll need to enable it if you want to use an application that&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;## connects to localhost.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# localnet 127.0.0.0/255.0.0.0&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;## RFC1918 Private Address Ranges&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# localnet 10.0.0.0/255.0.0.0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# localnet 172.16.0.0/255.240.0.0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# localnet 192.168.0.0/255.255.0.0&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# ProxyList format&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#       type  ip  port [user pass]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#       (values separated by&apos;tab&apos;or&apos;blank&apos;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#       only numeric ipv4 addresses are valid&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#        Examples:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#        socks5  192.168.67.78    1080    lamer    secret&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#        http    192.168.89.3     8080    justu    hidden&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#        socks4  192.168.1.49     1080&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#        http    192.168.39.93    8080&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#       proxy types: http, socks4, socks5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#        ( auth types supported:&quot;basic&quot;-http&quot;user/pass&quot;-socks )&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token section&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token section-name selector&quot;&gt;ProxyList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# add proxy here ...&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# meanwile&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# defaults set to&quot;tor&quot;&lt;/span&gt;
socks5 127.0.0.1 6153
http 127.0.0.1 6152&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里需要注意，安装完之后的命令名为：&lt;code class=&quot;language-text&quot;&gt;proxychains4&lt;/code&gt;，而不是proxychains。&lt;/p&gt;
&lt;h2 id=&quot;mac下的sip问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#mac%E4%B8%8B%E7%9A%84sip%E9%97%AE%E9%A2%98&quot; aria-label=&quot;mac下的sip问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;MAC下的SIP问题&lt;/h2&gt;
&lt;p&gt;MAC下如果使用proxychains来进行操作的话，会发现一些命令其实并没有生效。这里就会遇到一个SIP的问题，具体可以看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@xiaoqinglin2018/mac-osx-%E4%BD%BF%E7%94%A8proxychains-ng-91ba61472fdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Mac OSX 使用proxychains-ng&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面的处理方法是完全关闭SIP，这其实是不太可取的，这里还有另一个解决思路，见：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.tcdw.net/post/proxychains-with-sip/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;故事：试图不关闭 SIP 在 macOS Sierra 上使用 proxychains-ng&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后使用的命令会如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;cp&lt;/span&gt; /usr/bin/ssh ~/Prog/Cmd
$
$ proxychains4 ~/Prog/Cmd/ssh &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;22&lt;/span&gt; user@ip&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Koa2 中间件范例]]></title><link>https://xenojoshua.com/posts/2020/07/koa-middleware</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/07/koa-middleware</guid><pubDate>Thu, 02 Jul 2020 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot;&gt;前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%B8%AD%E9%97%B4%E4%BB%B6%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F&quot;&gt;中间件执行顺序&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%B4%8B%E8%91%B1%E5%BC%8F%E7%9A%84%E8%B0%83%E7%94%A8%E9%A1%BA%E5%BA%8F&quot;&gt;洋葱式的调用顺序&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%B8%AD%E6%96%AD%E7%9A%84%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8&quot;&gt;中断的链式调用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%B8%8D%E4%BD%BF%E7%94%A8await&quot;&gt;不使用await&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%BB%93%E8%AE%BA&quot;&gt;结论&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot; aria-label=&quot;前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;前言&lt;/h2&gt;
&lt;p&gt;发现之前对koa的中间件的理解还不够完全，这里做点笔记。&lt;/p&gt;
&lt;h2 id=&quot;中间件执行顺序&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E4%B8%AD%E9%97%B4%E4%BB%B6%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F&quot; aria-label=&quot;中间件执行顺序 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;中间件执行顺序&lt;/h2&gt;
&lt;p&gt;这里主要需要理解&lt;code class=&quot;language-text&quot;&gt;next&lt;/code&gt;函数。这个函数有几个点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;调用next函数，就会触发下一个中间件的业务逻辑执行（异步），但不会离开当前中间件，如果在next之后有逻辑代码的话，会正常执行&lt;/li&gt;
&lt;li&gt;该函数调用是异步的，因此可以await等待后续的中间件执行结束返回回来&lt;/li&gt;
&lt;li&gt;以next函数为分隔线，上面是顺序执行，下面是倒叙执行，上面的由上向下，下面的由下向上&lt;/li&gt;
&lt;li&gt;next函数的显示执行构成了一个中间件的调用链，如果任何一个中间件没有调用next，则链条会在当前中间件中断，后续即便注册了再多的中间件也不会被执行&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;看几个例子：&lt;/p&gt;
&lt;h3 id=&quot;洋葱式的调用顺序&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%B4%8B%E8%91%B1%E5%BC%8F%E7%9A%84%E8%B0%83%E7%94%A8%E9%A1%BA%E5%BA%8F&quot; aria-label=&quot;洋葱式的调用顺序 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;洋葱式的调用顺序&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最后的输出是：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1a
2a
3a
3b
2b
1b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;中断的链式调用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E4%B8%AD%E6%96%AD%E7%9A%84%E9%93%BE%E5%BC%8F%E8%B0%83%E7%94%A8&quot; aria-label=&quot;中断的链式调用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;中断的链式调用&lt;/h3&gt;
&lt;p&gt;如果某个中间件没有调用next，则后续的调用链会中断。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最后的输出是：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1a
2a
1b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;不使用await&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E4%B8%8D%E4%BD%BF%E7%94%A8await&quot; aria-label=&quot;不使用await permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;不使用await&lt;/h3&gt;
&lt;p&gt;如果在调用next的时候不使用await的话，当前的中间件触发下一个中间件的执行（异步）后不会等待后续中间件返回，后续的业务逻辑会&lt;code class=&quot;language-text&quot;&gt;立即&lt;/code&gt;继续执行。会打乱洋葱回调的顺序。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3a&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3b&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;最后的输出是：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1a
2a
3a
2b
3b
1b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;结论&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%BB%93%E8%AE%BA&quot; aria-label=&quot;结论 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;结论&lt;/h2&gt;
&lt;p&gt;主要有下面几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;制作通用的中间件的时候，必须在代码中执行&lt;code class=&quot;language-text&quot;&gt;return next();&lt;/code&gt;将调用链继续下去，否则后面的中间件将会失效&lt;/li&gt;
&lt;li&gt;一般编写中间件，如果某些业务需要等其他中间件执行结束后处理则使用&lt;code class=&quot;language-text&quot;&gt;await next();&lt;/code&gt;，否则一律&lt;code class=&quot;language-text&quot;&gt;return next();&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;next调用返回的是一个Promise，因此也可以使用&lt;code class=&quot;language-text&quot;&gt;next().catch&lt;/code&gt;之类的方式来进行错误处理&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[MaterialUI Notes]]></title><link>https://xenojoshua.com/posts/2020/06/material-ui</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/06/material-ui</guid><pubDate>Wed, 10 Jun 2020 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot;&gt;前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#notes&quot;&gt;Notes&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%A0%B7%E5%BC%8F&quot;&gt;样式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%A0%85%E6%A0%BC%E7%B3%BB%E7%BB%9F&quot;&gt;栅格系统&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%BD%91%E6%A0%BC%E6%96%AD%E7%82%B9&quot;&gt;网格断点&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%96%AD%E7%82%B9%E9%9A%90%E8%97%8F&quot;&gt;断点隐藏&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%B5%81%E5%BC%8F%E7%BD%91%E6%A0%BC&quot;&gt;流式网格&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B8%B8%E7%94%A8%E5%AE%B9%E5%99%A8&quot;&gt;常用容器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%97%B4%E8%B7%9D%E8%AE%BE%E7%BD%AE&quot;&gt;间距设置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%BD%E9%AB%98%E5%B0%BA%E5%AF%B8%E8%AE%BE%E7%BD%AE&quot;&gt;宽高尺寸设置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%A2%9C%E8%89%B2%E7%B3%BB%E7%BB%9F&quot;&gt;颜色系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%98%B4%E5%BD%B1&quot;&gt;阴影&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B1%82%E7%BA%A7&quot;&gt;层级&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%96%87%E5%AD%97%E9%93%B8%E6%8E%92&quot;&gt;文字铸排&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%BB%9F%E4%B8%80%E9%A3%8E%E6%A0%BC%E7%B3%BB%E7%BB%9F&quot;&gt;统一风格系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#typescript&quot;&gt;Typescript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot; aria-label=&quot;前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;前言&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://material-ui.com/zh/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;MaterialUI&lt;/a&gt;算是现在比较常见的UIKit了，用的人多，社区比较大，而且各种环境和框架的移植也很丰富，用起来比较简单和方便。当然使用的时候因为一些特有的概念和语法糖，还是需要一点上手时间。&lt;/p&gt;
&lt;p&gt;官方的教程：&lt;a href=&quot;https://material-ui.com/zh/getting-started/usage/#quick-start&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Tutorial&lt;/a&gt;（基本上没用）。&lt;/p&gt;
&lt;p&gt;一些资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://material-ui.com/zh/components/material-icons/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Material Icons 图标&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://material-ui.com/zh/getting-started/installation/#font-icons&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;字体的安装&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://material-ui.com/store/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Material 主题商店&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;notes&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#notes&quot; aria-label=&quot;notes permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Notes&lt;/h2&gt;
&lt;h3 id=&quot;样式&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%A0%B7%E5%BC%8F&quot; aria-label=&quot;样式 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;样式&lt;/h3&gt;
&lt;p&gt;直接的样式处理及样式的编程，见文档：&lt;a href=&quot;https://material-ui.com/zh/styles/basics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;@material-ui/styles&lt;/a&gt;。简单范例：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; makeStyles &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@material-ui/core/styles&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Button &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@material-ui/core/Button&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; useStyles &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  root&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    background&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    border&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    borderRadius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    boxShadow&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0 3px 5px 2px rgba(255, 105, 135, .3)&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;white&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    height&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    padding&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;0 30px&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Hook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; classes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Button className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;root&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;Hook&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Button&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;栅格系统&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%A0%85%E6%A0%BC%E7%B3%BB%E7%BB%9F&quot; aria-label=&quot;栅格系统 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;栅格系统&lt;/h3&gt;
&lt;p&gt;栅格系统是布局的基础，官方文档在：&lt;a href=&quot;https://material-ui.com/zh/components/grid/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grid 栅格&lt;/a&gt;。当然，MaterialUI也提供了直接使用&lt;a href=&quot;https://material-ui.com/zh/system/flexbox/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Flexbox&lt;/a&gt;来进行布局自定义的能力。另外，在做响应式布局的时候，&lt;a href=&quot;https://material-ui.com/zh/components/hidden/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Hidden&lt;/a&gt;组件也是非常重要的，能在某些分辨率下隐藏一些组件的显示。&lt;/p&gt;
&lt;p&gt;栅格系统使用 Grid “盒子”组件实现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为了达到高度的灵活性，盒子组件运用了用 CSS 的 Flexible Box 模块 。&lt;/li&gt;
&lt;li&gt;它有两种类型的布局：containers，items。&lt;/li&gt;
&lt;li&gt;而项目宽度以百分比设置，因此相对于其父元素，它们总是流动的和变换大小的。&lt;/li&gt;
&lt;li&gt;子元素则自带 padding 来和其他元素间隔。&lt;/li&gt;
&lt;li&gt;你可以找到五个网格断点：xs，sm，md，lg 和 xl。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;网格断点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%BD%91%E6%A0%BC%E6%96%AD%E7%82%B9&quot; aria-label=&quot;网格断点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;网格断点&lt;/h4&gt;
&lt;p&gt;首先需要了解响应式布局的网格断点，见文档：&lt;a href=&quot;https://material-ui.com/zh/customization/breakpoints/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Breakpoints&lt;/a&gt;。要注意，虽然断点的尺寸是有预定义值的，但也是可以自定义改动的。&lt;/p&gt;
&lt;p&gt;每个断点（一个键）匹配一个固定的屏幕宽度（一个值）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;xs，超小：0px&lt;/li&gt;
&lt;li&gt;sm，小：600px&lt;/li&gt;
&lt;li&gt;md，中等：960px&lt;/li&gt;
&lt;li&gt;lg，大：1280px&lt;/li&gt;
&lt;li&gt;xl，超大：1920px&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;value         |0px     600px    960px    1280px   1920px
key           |xs      sm       md       lg       xl
screen width  |--------|--------|--------|--------|--------&gt;
range         |   xs   |   sm   |   md   |   lg   |   xl&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 样式的屏幕尺寸感知，并自适应&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;styles&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; theme &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  root&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    padding&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;spacing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;breakpoints&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;down&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;sm&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      backgroundColor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;palette&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondary&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;breakpoints&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;up&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;md&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      backgroundColor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;palette&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;primary&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;breakpoints&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;up&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;lg&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      backgroundColor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; green&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;断点隐藏&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%96%AD%E7%82%B9%E9%9A%90%E8%97%8F&quot; aria-label=&quot;断点隐藏 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;断点隐藏&lt;/h4&gt;
&lt;p&gt;一般在做响应式设计的时候，会用到&lt;a href=&quot;https://material-ui.com/zh/components/hidden/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Hidden组件&lt;/a&gt;，该组件有3组属性可以控制当前组件在某些断点情况下的显示和隐藏：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;*Up：使用任何断点&lt;code class=&quot;language-text&quot;&gt;up&lt;/code&gt;属性的元素，给定的 子节点 将在&lt;code class=&quot;language-text&quot;&gt;断点以及断点以上&lt;/code&gt;时被隐藏。&lt;/li&gt;
&lt;li&gt;*Down：使用任何断点&lt;code class=&quot;language-text&quot;&gt;down&lt;/code&gt;属性的元素，给定 子节点 将在&lt;code class=&quot;language-text&quot;&gt;断点以及断点以下&lt;/code&gt;时被隐藏。&lt;/li&gt;
&lt;li&gt;*Only：利用断点&lt;code class=&quot;language-text&quot;&gt;only&lt;/code&gt;属性，给定 子节点 将被隐藏在&lt;code class=&quot;language-text&quot;&gt;指定的断点&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;innerWidth  |xs      sm       md       lg       xl
            |--------|--------|--------|--------|--------&gt;
width       |   xs   |   sm   |   md   |   lg   |   xl

smUp        |   show | hide
mdDown      |                     hide | show&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;看几个例子：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Up&lt;/strong&gt;&lt;br&gt;
*Up：使用任何断点&lt;code class=&quot;language-text&quot;&gt;up&lt;/code&gt;属性的元素，给定的 子节点 将在&lt;code class=&quot;language-text&quot;&gt;断点以及断点以上&lt;/code&gt;时被隐藏。playground：&lt;a href=&quot;https://codesandbox.io/s/zlpm4?file=/demo.tsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.container}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xsUp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;xsUp&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;smUp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;smUp&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;mdUp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;mdUp&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lgUp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;lgUp&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xlUp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;xlUp&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-up-lg.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-up-md.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-up-sm.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-up-xs.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Down&lt;/strong&gt;&lt;br&gt;
*Down：使用任何断点&lt;code class=&quot;language-text&quot;&gt;down&lt;/code&gt;属性的元素，给定 子节点 将在&lt;code class=&quot;language-text&quot;&gt;断点以及断点以下&lt;/code&gt;时被隐藏。playground：&lt;a href=&quot;https://codesandbox.io/s/5d4xk?file=/demo.tsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.container}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xsDown&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;xsDown&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;smDown&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;smDown&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;mdDown&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;mdDown&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lgDown&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;lgDown&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xlDown&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;xlDown&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-down-lg.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-down-md.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-down-sm.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-down-xs.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Only&lt;/strong&gt;&lt;br&gt;
*Only：利用断点&lt;code class=&quot;language-text&quot;&gt;only&lt;/code&gt;属性，给定 子节点 将被隐藏在&lt;code class=&quot;language-text&quot;&gt;指定的断点&lt;/code&gt;。playground：&lt;a href=&quot;https://codesandbox.io/s/6nury?file=/demo.tsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.container}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;only&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;lg&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hidden on lg&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Hidden&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;only&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;sm&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hidden on sm&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &amp;lt;Hidden only={[&apos;sm&apos;, &apos;lg&apos;]}&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Paper&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{classes.paper}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Hidden on sm and lg&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Paper&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-only-lg.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-only-md.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/hidden-only-sm.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;流式网格&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%B5%81%E5%BC%8F%E7%BD%91%E6%A0%BC&quot; aria-label=&quot;流式网格 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;流式网格&lt;/h4&gt;
&lt;p&gt;实际组件的空间占用布局是按&lt;a href=&quot;https://material-ui.com/zh/components/grid/#fluid-grids&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Fluid grids 流式网格&lt;/a&gt;来排放的。举个例子：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; makeStyles&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; createStyles&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Theme &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@material-ui/core/styles&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Paper &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@material-ui/core/Paper&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Grid &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@material-ui/core/Grid&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; useStyles &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;makeStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theme&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Theme&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;createStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    root&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      flexGrow&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    paper&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      padding&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;spacing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      textAlign&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;center&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; theme&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;palette&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;secondary&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CenteredGrid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; classes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;root&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid container spacing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/06/material-ui/grid-effect-01.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;例子中的&lt;code class=&quot;language-text&quot;&gt;xs&lt;/code&gt;是指前面提到的断点。只有屏幕尺寸在xs及其上的断点的情况下，才会按此布局。里面的数值是相对的，第一行最大值为12，后面第二行的6就是其一半。这个例子的playground：&lt;a href=&quot;https://codesandbox.io/s/hpyjz?file=/demo.tsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;定义尺寸的时候可以对一个组件设置多个网格断点情况下的大小，这样做的话，可以让组件排布顺应不同的屏幕尺寸发生变化，看下面的例子：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/06/material-ui/grid-effect-02.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2020/06/material-ui/grid-effect-03.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;例子中，在屏幕尺寸大于sm的情况下（从大到小匹配），sm的尺寸定义发挥作用：第二行的组件占比都为6，第二行2个组件各占一半，同样的第三行占比设为3，一行正好4个组件都放进去。&lt;/p&gt;
&lt;p&gt;然后在屏幕尺寸缩小之后，尺寸小于sm，且大于xs，则xs的尺寸定义发挥作用：原来第二行各分一半的2个组件分别占了一行，原来第三行的4个组件分为了两行，每行两个。这个例子的playground：&lt;a href=&quot;https://codesandbox.io/s/2ysg9?file=/demo.tsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;常用容器&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%B8%B8%E7%94%A8%E5%AE%B9%E5%99%A8&quot; aria-label=&quot;常用容器 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;常用容器&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://material-ui.com/zh/components/container/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Container&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;页面的主要容器，一般来说所有的内容都会放在Container内。Container的最大宽度，使用&lt;code class=&quot;language-text&quot;&gt;maxWidth&lt;/code&gt;来设置，里面的值需要设置刚才的断点值：xs、sm、md、lg、xl。另，Container的&lt;a href=&quot;https://material-ui.com/zh/api/container/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;API文档&lt;/a&gt;，属性相关内容都在这里。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Container maxWidth&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sm&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://material-ui.com/zh/components/box/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Box&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;包装容器，一般用来将某几个组件包装在一起做位置偏移或样式添加等操作。Box默认为一个div，也可以使用&lt;code class=&quot;language-text&quot;&gt;component&lt;/code&gt;来设置实际的HTML标签：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Box&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;span&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{1}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Button&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Box&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://material-ui.com/zh/components/grid/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grid&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最基本的容器组件，通过将该组件相互嵌套使用，就可以组成非常复杂的页面布局。另，Grid的&lt;a href=&quot;https://material-ui.com/zh/api/grid/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;API文档&lt;/a&gt;，组件属性需要到这里查阅。&lt;/p&gt;
&lt;p&gt;嵌套的情况下，&lt;code class=&quot;language-text&quot;&gt;container&lt;/code&gt;属性表示是包在外层的Grid，&lt;code class=&quot;language-text&quot;&gt;item&lt;/code&gt;则表示是从属于外层包装的Grid。如果有多层嵌套，则中间层的Grid既是container又是item。看个例子，playground在&lt;a href=&quot;https://codesandbox.io/s/jf0r8?file=/demo.tsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// defining FormRow&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;FormRow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Fragment&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;item&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;item&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Paper className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;classes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;paper&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;item&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Paper&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Fragment&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// using FormRow&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid container spacing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid container item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; spacing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;FormRow &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid container item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; spacing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;FormRow &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Grid container item xs&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; spacing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;FormRow &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Grid&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/06/material-ui/grid-effect-04.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;间距设置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%97%B4%E8%B7%9D%E8%AE%BE%E7%BD%AE&quot; aria-label=&quot;间距设置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;间距设置&lt;/h3&gt;
&lt;p&gt;在MaterialUI中设置间距有已经做好的语法糖，直接使用即可，文档：&lt;a href=&quot;https://material-ui.com/zh/system/spacing/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Spacing&lt;/a&gt;，还有&lt;a href=&quot;https://material-ui.com/zh/customization/spacing/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Theme Spacing&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;其中属性是其中之一：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;m - 对于设置margin&lt;/li&gt;
&lt;li&gt;p - 对于设置padding&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;哪边边是其中之一：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;t - 对于设置* margin-top或padding-top*的类&lt;/li&gt;
&lt;li&gt;b - 对于设置margin-bottom的类或padding-bottom的类&lt;/li&gt;
&lt;li&gt;l - 对于设置margin-left或padding-left的类&lt;/li&gt;
&lt;li&gt;r - 对于设置margin-right或padding-right的类&lt;/li&gt;
&lt;li&gt;x - 对于设置* -left和* -right的类&lt;/li&gt;
&lt;li&gt;y - 对于设置* -top和* -bottom的类&lt;/li&gt;
&lt;li&gt;空白 - 用于在元素的所有4个边上设置边距或填充的类&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面提到的属性的值，是数字，意思是&lt;code class=&quot;language-text&quot;&gt;几份&lt;/code&gt;。比如说&lt;code class=&quot;language-text&quot;&gt;my={1}&lt;/code&gt;就是上下添加一份的margin。下面的例子中，一份就是8px（MaterialUI的默认值一份就是8px）。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; theme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  spacing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box m&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// margin: -16px;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box m&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// margin: 0px;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box m&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// margin: 4px;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box m&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// margin: 16px;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;宽高尺寸设置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%AE%BD%E9%AB%98%E5%B0%BA%E5%AF%B8%E8%AE%BE%E7%BD%AE&quot; aria-label=&quot;宽高尺寸设置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;宽高尺寸设置&lt;/h3&gt;
&lt;p&gt;见文档：&lt;a href=&quot;https://material-ui.com/zh/system/sizing/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Sizing&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Numbers in [0,1] are multiplied by 100 and converted to % values.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Numbers are converted to pixel values.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;75%&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// String values are used as raw CSS.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// 100%&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;颜色系统&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%A2%9C%E8%89%B2%E7%B3%BB%E7%BB%9F&quot; aria-label=&quot;颜色系统 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;颜色系统&lt;/h3&gt;
&lt;p&gt;MaterialUI提供了配色相关的解决方案，见：&lt;a href=&quot;https://material-ui.com/zh/customization/color/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Color 颜色&lt;/a&gt;（如果需要选择颜色代码的话，就直接在这个文档页面上查找），以及&lt;a href=&quot;https://material-ui.com/zh/customization/palette/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Theme Palette&lt;/a&gt;，以及&lt;a href=&quot;https://material-ui.com/zh/system/palette/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Palette 调色&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;warning.main&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box bgcolor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;info.main&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;阴影&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%98%B4%E5%BD%B1&quot; aria-label=&quot;阴影 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;阴影&lt;/h3&gt;
&lt;p&gt;MaterialUI的阴影直接使用属性&lt;code class=&quot;language-text&quot;&gt;boxShadow&lt;/code&gt;就能实现了，文档：&lt;a href=&quot;https://material-ui.com/zh/system/shadows/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Shadow&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box boxShadow&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;层级&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%B1%82%E7%BA%A7&quot; aria-label=&quot;层级 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;层级&lt;/h3&gt;
&lt;p&gt;有时候一些元素会在同位置上进行重叠，这时候就需要确定它们的层级来进行相互覆盖的定义。在CSS中我们会使用&lt;code class=&quot;language-text&quot;&gt;z-index&lt;/code&gt;来操作，在MaterialUI中，一般使用属性&lt;code class=&quot;language-text&quot;&gt;zIndex&lt;/code&gt;来操作，且MaterialUI已经定义了一些，一般直接使用即可，&lt;a href=&quot;https://material-ui.com/zh/system/positions/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;范例&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box zIndex&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tooltip&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box zIndex&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;modal&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://material-ui.com/zh/customization/z-index/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;预定义数值&lt;/a&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mobile stepper（移动设备起步）: 1000&lt;/li&gt;
&lt;li&gt;speed dial: 1050&lt;/li&gt;
&lt;li&gt;app bar（应用栏）：1100&lt;/li&gt;
&lt;li&gt;drawer（抽屉）：1200&lt;/li&gt;
&lt;li&gt;modal（浮层）：1300&lt;/li&gt;
&lt;li&gt;snackbar：1400&lt;/li&gt;
&lt;li&gt;tooltip（提示）：1500&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;文字铸排&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%96%87%E5%AD%97%E9%93%B8%E6%8E%92&quot; aria-label=&quot;文字铸排 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;文字铸排&lt;/h3&gt;
&lt;p&gt;组件内文字内容的Typography，MaterialUI有属性可以直接控制，不需要手动编写CSS。见文档：&lt;a href=&quot;https://material-ui.com/zh/system/typography/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Typography&lt;/a&gt;，以及&lt;a href=&quot;https://material-ui.com/zh/customization/typography/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Theme Typography&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box textAlign&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;left&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;                &lt;span class=&quot;token comment&quot;&gt;// right, left, center&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box fontWeight&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fontWeightRegular&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// light, regular, medium, 500, bold&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box fontSize&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fontSize&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;             &lt;span class=&quot;token comment&quot;&gt;// default, h6.fontSize, 16&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box fontStyle&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;normal&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;              &lt;span class=&quot;token comment&quot;&gt;// normal, italic, oblique&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box letterSpacing&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;               &lt;span class=&quot;token comment&quot;&gt;// 字符间距，这里的数值就是6px&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box lineHeight&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;normal&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;             &lt;span class=&quot;token comment&quot;&gt;// normal, 10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果需要在页面上直接展示文字，建议使用组件Typography，见文档：&lt;a href=&quot;https://material-ui.com/zh/components/typography/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Typography&lt;/a&gt;。此外，还有&lt;a href=&quot;https://material-ui.com/zh/api/typography/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;API文档&lt;/a&gt;，组件的属性需要到这里查阅。&lt;/p&gt;
&lt;p&gt;看一个例子，该例子的playground在：&lt;a href=&quot;https://codesandbox.io/s/lpul9?file=/demo.tsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Grid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{12}&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;sm&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;container&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Grid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xs&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;container&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;direction&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;column&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;spacing&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;{2}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Grid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;item&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Typography&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;gutterBottom&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;subtitle1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        Standard license
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Typography&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Typography&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;body2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;gutterBottom&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        Full resolution 1920x1080 • JPEG
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Typography&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Typography&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;body2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;textSecondary&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        ID: 1030114
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Typography&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Grid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Grid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Typography&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;body2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;cursor:&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&apos;pointer&apos;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;}}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        Remove
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Typography&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Grid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Grid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Grid&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Typography&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;subtitle1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;$19.00&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Typography&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Grid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Grid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2020/06/material-ui/typography-effect-01.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;该组件的&lt;code class=&quot;language-text&quot;&gt;noWrap&lt;/code&gt;属性默认值为false，也就是说遇到文字过长的情况下会进行回行。如果将这个属性设置为true，则文字过长的部分会被截断，并显示为省略号。&lt;/p&gt;
&lt;h3 id=&quot;统一风格系统&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%BB%9F%E4%B8%80%E9%A3%8E%E6%A0%BC%E7%B3%BB%E7%BB%9F&quot; aria-label=&quot;统一风格系统 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;统一风格系统&lt;/h3&gt;
&lt;p&gt;MaterialUI有一套统一的设计方案，方便开发者在App级别对所有的组件进行统一的样式及风格定义。官方文档：&lt;a href=&quot;https://material-ui.com/zh/system/basics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;@material-ui/system&lt;/a&gt;。一般来说项目大的话，肯定有需要进行这部分的调整。如果使用的是官方Store中的一些Template，一般它们已经做好了对应的功能。&lt;/p&gt;
&lt;p&gt;这部分比较庞大，细节很多。这里放一个简单例子，直观感受下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ThemeProvider &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;styled-components&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; theme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  spacing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  palette&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    primary&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#007bff&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ThemeProvider theme&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* children */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ThemeProvider&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;更多的细节可以查看MaterialUI的&lt;a href=&quot;https://material-ui.com/zh/customization/theming/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Customization&lt;/a&gt;个性化文档。&lt;/p&gt;
&lt;h3 id=&quot;typescript&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#typescript&quot; aria-label=&quot;typescript permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Typescript&lt;/h3&gt;
&lt;p&gt;MaterialUI对Typescript支持很好，官方文档：&lt;a href=&quot;https://material-ui.com/zh/guides/typescript/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TypeScript&lt;/a&gt;。里面细节还是有点多的，需要慢慢习惯用法。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Next.js Notes]]></title><link>https://xenojoshua.com/posts/2020/06/nextjs-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/06/nextjs-note</guid><pubDate>Tue, 09 Jun 2020 02:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#0-%E5%89%8D%E8%A8%80&quot;&gt;0. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84&quot;&gt;1. 文件结构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E8%B7%AF%E7%94%B1&quot;&gt;2. 路由&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-ssr-csr-static&quot;&gt;4. SSR CSR Static&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-nextjs%E7%9A%84%E5%85%B6%E4%BB%96%E7%9F%A5%E8%AF%86%E7%82%B9&quot;&gt;5. Next.js的其他知识点&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-css%E7%9B%B8%E5%85%B3&quot;&gt;5.1 CSS相关&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E5%8F%98%E9%87%8F%E9%85%8D%E7%BD%AE&quot;&gt;5.2 变量配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#53-api%E5%90%8E%E7%AB%AF&quot;&gt;5.3 API后端&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#54-%E8%87%AA%E5%AE%9A%E4%B9%89app&quot;&gt;5.4 自定义App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#55-%E8%87%AA%E5%AE%9A%E4%B9%89document&quot;&gt;5.5 自定义Document&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-react%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5&quot;&gt;6. React相关概念&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-state&quot;&gt;6.1 state&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-effect&quot;&gt;6.2 effect&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9C%8D%E5%8A%A1%E5%99%A8&quot;&gt;7. 自定义服务器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-%E9%97%AE%E9%A2%98%E5%8F%8A%E8%A7%A3%E5%86%B3&quot;&gt;8. 问题及解决&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#81-typeorm&quot;&gt;8.1 TypeORM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;0-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#0-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;0 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;0. 前言&lt;/h2&gt;
&lt;p&gt;最近在尝试使用&lt;a href=&quot;https://nextjs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Next.js&lt;/a&gt;，虽说比直接裸用react简单不少，但还是有不少自有的特殊概念，因此这里开篇笔记，做下记录。&lt;/p&gt;
&lt;p&gt;入门Next.js可以阅读官方的教程：&lt;a href=&quot;https://nextjs.org/learn/basics/create-nextjs-app&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Create a Next.js App&lt;/a&gt;。关于Next.js的优势，为什么要使用Next.js以及很多关于Next.js的细节等，可以查看这篇博文：&lt;a href=&quot;https://www.freecodecamp.org/news/the-next-js-handbook/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The Next.js Handbook&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;version&lt;code class=&quot;language-text&quot;&gt;9.4.4&lt;/code&gt;已知问题（会列一些对使用有影响的）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vercel/next.js/issues/5214&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;trailing slash in link … 404 … #5214&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;1-文件结构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84&quot; aria-label=&quot;1 文件结构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 文件结构&lt;/h2&gt;
&lt;p&gt;默认被占用的路径只有两个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;project_root/pages&lt;/code&gt;：用来作为页面路由使用&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;project_root/public&lt;/code&gt;：用来进行静态文件输出&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;2-路由&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E8%B7%AF%E7%94%B1&quot; aria-label=&quot;2 路由 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 路由&lt;/h2&gt;
&lt;p&gt;路由部分Next.js做了简化，默认是使用文件夹的形式，在&lt;code class=&quot;language-text&quot;&gt;project_root/pages/name.js|tsx&lt;/code&gt;下的文件，会映射为&lt;code class=&quot;language-text&quot;&gt;your_site/name&lt;/code&gt;这个路径，见官方文档：&lt;a href=&quot;https://nextjs.org/docs/basic-features/pages&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Pages&lt;/a&gt;。这样使用上非常简便，正常使用的话，就完全不需要引入第三方的类库（类似于&lt;code class=&quot;language-text&quot;&gt;react-router&lt;/code&gt;），也不需要使用编程的方式在代码中定义路由。更多细节：&lt;a href=&quot;https://nextjs.org/docs/routing/introduction&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Routing&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;但上述的路由不能很好支持&lt;code class=&quot;language-text&quot;&gt;your_site/user/:user_id&lt;/code&gt;这样的需求。类似这样的需求在Next.js中也有解决方案，被称为&lt;code class=&quot;language-text&quot;&gt;dynamic route&lt;/code&gt;。官方文档在：&lt;a href=&quot;https://nextjs.org/docs/routing/dynamic-routes&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Dynamic Routes&lt;/a&gt;。只需要把page文件的名字定义为：&lt;code class=&quot;language-text&quot;&gt;pages/post/[pid].js&lt;/code&gt;就OK。多参数的路径，类似：&lt;code class=&quot;language-text&quot;&gt;pages/post/[pid]/[comment].js&lt;/code&gt;，也是一样处理，这种路径在query参数中获取到的object就会含有多个键。&lt;/p&gt;
&lt;p&gt;如果需要编程的方式来进行route操作的话，见文档：&lt;a href=&quot;https://nextjs.org/docs/api-reference/next/router&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;next/router&lt;/a&gt;。如果官方以文件夹形式管理的自动化route无法满足需求的话，还有功能强大的插件形式的route可以使用：&lt;a href=&quot;https://github.com/fridays/next-routes&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Dynamic Routes for Next.js&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;4-ssr-csr-static&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-ssr-csr-static&quot; aria-label=&quot;4 ssr csr static permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. SSR CSR Static&lt;/h2&gt;
&lt;p&gt;Next.js默认支持了服务端渲染等提升前端获取速度和渲染性能的功能，但这也要求开发者必须谨慎对待组件的初始化和生命周期，因为显然运行在服务端和客户端的代码在获取组件初始化需要的数据时的方法是不一样的。&lt;/p&gt;
&lt;p&gt;这部分的文档在：&lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Data fetching&lt;/a&gt;，以及&lt;a href=&quot;https://nextjs.org/docs/advanced-features/automatic-static-optimization&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Automatic Static Optimization&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;如果一个Page里&lt;code class=&quot;language-text&quot;&gt;getServerSideProps&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;getInitialProps&lt;/code&gt;存在的话，该Page就会被识别为服务端渲染（SSR），会在每次请求的时候进行渲染。而如果这两者皆不存在的话，该页面就会在服务器启动并构建的时候生成静态页面，后续每次请求的时候都会直接返回该静态页面。此外，在DEV模式的情况下，即便是静态渲染的Page也会在每次请求的时候触发渲染，需要注意。&lt;/p&gt;
&lt;p&gt;主要方法有以下几个：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching#getstaticpaths-static-generation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;getStaticPaths&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个方法一般是配合&lt;code class=&quot;language-text&quot;&gt;dynamic route&lt;/code&gt;进行使用，会在Next.js服务器启动，并进行服务器静态构建的时候运行。其作用是告诉后续的&lt;code class=&quot;language-text&quot;&gt;getStaticProps&lt;/code&gt;某个动态路径的可能项。如果这个page你不需要静态构建，或者这个page也不是dynamic route，那就不需要实现这个函数。&lt;/p&gt;
&lt;p&gt;举例来说&lt;code class=&quot;language-text&quot;&gt;pages/user/[id].js&lt;/code&gt;代码中的&lt;code class=&quot;language-text&quot;&gt;getStaticProps&lt;/code&gt;就需要返回：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getStaticPaths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    paths&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; params&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;2&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fallback&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; or &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;paths和fallback都是必须的键。fallback的意思是，当遇到客户端访问到一个并不存在于启动构建时制作的paths列表里的路径，Next.js应该允许客户端继续访问，还是直接返回一个404。这里要注意，如果fallback为true，也就是允许客户端继续访问的话，page代码一定要做好容错性，否则很容易导致页面报错。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;getStaticProps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这个方法也是在Next.js服务器启动的时候，进行服务器静态构建的时候运行。其作用是用来给静态生成的页面提供props。同样的，如果这个page你不需要静态构建，那就不需要实现这个函数。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getStaticProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// will be passed to the page component as props&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果是&lt;code class=&quot;language-text&quot;&gt;dynamic route&lt;/code&gt;的情况，该函数的context会包含&lt;code class=&quot;language-text&quot;&gt;getStaticPaths&lt;/code&gt;提供的路径信息：&lt;code class=&quot;language-text&quot;&gt;context.params = { id: &apos;1&apos; }&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;getServerSideProps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;同样是运行在服务器端，但并不是在Next.js构建时候运行，而是在每一次单独的请求到达的时候触发。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getServerSideProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// will be passed to the page component as props&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://nextjs.org/docs/api-reference/data-fetching/getInitialProps&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;getInitialProps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;基本上已弃用，如果是静态生成页面的话，使用&lt;code class=&quot;language-text&quot;&gt;getStaticProps&lt;/code&gt;；如果是服务端渲染的话，使用&lt;code class=&quot;language-text&quot;&gt;getServerSideProps&lt;/code&gt;。如果仅只是客户端渲染的页面，则使用React的effect就可以了。&lt;/p&gt;
&lt;h2 id=&quot;5-nextjs的其他知识点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-nextjs%E7%9A%84%E5%85%B6%E4%BB%96%E7%9F%A5%E8%AF%86%E7%82%B9&quot; aria-label=&quot;5 nextjs的其他知识点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Next.js的其他知识点&lt;/h2&gt;
&lt;h3 id=&quot;51-css相关&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-css%E7%9B%B8%E5%85%B3&quot; aria-label=&quot;51 css相关 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 CSS相关&lt;/h3&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://nextjs.org/docs/basic-features/built-in-css-support&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Built-In CSS Support&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Next.js的CSS有很多细节，最主要的是命名后缀的问题，使用&lt;code class=&quot;language-text&quot;&gt;*.module.css&lt;/code&gt;的话，生成出来的页面上的CSS是会附带随机后缀的，就不会造成冲突。而如果需要引入global的css的话，则需要创建&lt;code class=&quot;language-text&quot;&gt;pages/_app.js&lt;/code&gt;文件，在这里修改。&lt;/p&gt;
&lt;p&gt;jsx支持相关可以查阅这篇文档：&lt;a href=&quot;https://github.com/vercel/styled-jsx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;styled-jsx&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;52-变量配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E5%8F%98%E9%87%8F%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;52 变量配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 变量配置&lt;/h3&gt;
&lt;p&gt;环境变量的官方文档：&lt;a href=&quot;https://nextjs.org/docs/basic-features/environment-variables&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Next.js默认直接支持环境变量配置。基本上有配置相关需求就直接使用这个解决方案就OK了。&lt;/p&gt;
&lt;h3 id=&quot;53-api后端&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#53-api%E5%90%8E%E7%AB%AF&quot; aria-label=&quot;53 api后端 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3 API后端&lt;/h3&gt;
&lt;p&gt;之前提到的route都是pages下的页面，一般来说还需要前后端交互使用的&lt;code class=&quot;language-text&quot;&gt;/api/*&lt;/code&gt;，这个在Next.js中被称为：&lt;a href=&quot;https://nextjs.org/docs/api-routes/introduction&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;API Routes&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;54-自定义app&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#54-%E8%87%AA%E5%AE%9A%E4%B9%89app&quot; aria-label=&quot;54 自定义app permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.4 自定义App&lt;/h3&gt;
&lt;p&gt;创建&lt;code class=&quot;language-text&quot;&gt;pages/_app.js&lt;/code&gt;代码文件，就可以在里面进行一些应用级别的初始化工作。官方文档：&lt;a href=&quot;https://nextjs.org/docs/advanced-features/custom-app&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Custom App&lt;/a&gt;。自定义App的可能需求为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Persisting layout between page changes&lt;/li&gt;
&lt;li&gt;Keeping state when navigating pages&lt;/li&gt;
&lt;li&gt;Custom error handling using componentDidCatch&lt;/li&gt;
&lt;li&gt;Inject additional data into pages&lt;/li&gt;
&lt;li&gt;Add global CSS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可能的应用场景：&lt;code class=&quot;language-text&quot;&gt;准备全局变量&lt;/code&gt;。在一款WEB应用中，某些数据是所有的页面都会有需求的，比如说当前session的最基本用户信息和权限信息等。而_app是所有的页面的基本入口，每个页面的渲染都会先经过它，那么其实就可以在这个代码中做这些事情。&lt;/p&gt;
&lt;p&gt;页面渲染的先后顺序：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Resolution order&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// On the server:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 1. app.getInitialProps&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 2. page.getInitialProps&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 3. document.getInitialProps&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 4. app.render&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 5. page.render&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 6. document.render&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// On the server with error:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 1. document.getInitialProps&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 2. app.render&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 3. page.render&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 4. document.render&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// On the client&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 1. app.getInitialProps&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 2. page.getInitialProps&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 3. app.render&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 4. page.render&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// _app.tsx&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; App&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;AppContext&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;next/app&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AppPageProps&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AppProps &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  your_global_page_props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;getInitialProps&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;appCtx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; AppContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; appProps &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInitialProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;appCtx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    appProps&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pageProps &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        your_global_page_props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; AppPageProps&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;appProps&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// yourpage.tsx&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;AppPageProps&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../_app&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;YourPageProps&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; AppPageProps &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;YourPage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; YourPageProps&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// { your_global_page_props: &quot;&quot; }&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;55-自定义document&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#55-%E8%87%AA%E5%AE%9A%E4%B9%89document&quot; aria-label=&quot;55 自定义document permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.5 自定义Document&lt;/h3&gt;
&lt;p&gt;创建&lt;code class=&quot;language-text&quot;&gt;pages/_document.js&lt;/code&gt;代码文件，就可以在里面改动全局的&lt;code class=&quot;language-text&quot;&gt;&amp;lt;html&gt;&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;&amp;lt;body&gt;&lt;/code&gt;。官方文档：&lt;a href=&quot;https://nextjs.org/docs/advanced-features/custom-document&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Custom Document&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Document is only rendered in the server.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;6-react相关概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-react%E7%9B%B8%E5%85%B3%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;6 react相关概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. React相关概念&lt;/h2&gt;
&lt;p&gt;Next.js和React的关系还是比较简单的。React本身的功能其实很简单，它就只是一个渲染引擎，而用来做应用的时候，你除了渲染之外还需要很多东西，而这些，React是给不了你的，必须你自己去组织。比如说最基本的请求路由，比如说打包用的webpack，比如说js transformation的babel，以及提升整体性能的服务端渲染和静态生成等等等等。&lt;/p&gt;
&lt;p&gt;Next.js实际上就是在React的基础上，提供这些做应用必须的组件和功能之后的框架库。所以在使用Next.js进行开发的时候，React的知识也是必须的，否则就无法正确处理渲染相关的问题了。作为基本的使用者，React其实只有3大组的概念是必须要厘清楚的。&lt;/p&gt;
&lt;h3 id=&quot;61-state&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-state&quot; aria-label=&quot;61 state permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 state&lt;/h3&gt;
&lt;p&gt;React的官方文档在：&lt;a href=&quot;https://reactjs.org/docs/hooks-state.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Using the State Hook&lt;/a&gt;。主要代码其实就只有一句：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCount&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;useState&lt;/code&gt;函数接受一个状态的默认值，然后返回一个数组，数组的0位是state变量，1位是改变这个state变量的方法，名字可以自己命名。&lt;/p&gt;
&lt;p&gt;State的值调整需要注意内存的问题，有的时候不是仅仅只是修改对象的值就可以了。特别是遇到复杂的state，一个object或者数组里有嵌套的object和数组的时候，需要非常注意内存拷贝的问题。具体的可以看这个帖子：&lt;a href=&quot;https://stackoverflow.com/a/49502115&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;React: how to update state.item[1] in state using setState?&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;62-effect&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-effect&quot; aria-label=&quot;62 effect permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 effect&lt;/h3&gt;
&lt;p&gt;React的官方文档在：&lt;a href=&quot;https://reactjs.org/docs/hooks-effect.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Using the Effect Hook - React&lt;/a&gt;。只要是涉及到状态变化的，都属于effect的范畴。一个React组件里可以使用&lt;code class=&quot;language-text&quot;&gt;useEffect&lt;/code&gt;函数注册多个effect事件。第二个参数的指定可以决定该effect事件应该在什么时候触发。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[]&lt;/code&gt;，效果同&lt;code class=&quot;language-text&quot;&gt;componentDidMount&lt;/code&gt;，仅只在组件mount的时候触发一次。同时，在这种effect中提供一个回调函数返回，则等同于&lt;code class=&quot;language-text&quot;&gt;componentWillUnmount&lt;/code&gt;，这个回调函数会在组件被unmount的时候被触发，用来做析构。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// your effect here&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// unmount&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;无参数&lt;/code&gt;，效果同&lt;code class=&quot;language-text&quot;&gt;componentDidUpdate&lt;/code&gt;，每次组件re-render都会触发。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// your effect here&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// no optional argument&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[foo]&lt;/code&gt;，在数组中放入prop或state，则该effect只会在这个prop或state发生变化的时候触发。这个数组里可以放入复数的变量，表示监听多个变量的变化，任何一个发生变化都会触发该effect。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// your effect here&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;foo&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;7-自定义服务器&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-%E8%87%AA%E5%AE%9A%E4%B9%89%E6%9C%8D%E5%8A%A1%E5%99%A8&quot; aria-label=&quot;7 自定义服务器 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. 自定义服务器&lt;/h2&gt;
&lt;p&gt;在大部分情况下，使用&lt;code class=&quot;language-text&quot;&gt;next [start]&lt;/code&gt;命令启动的服务器就已经足够满足需求了，但某些时候，我们仍旧有需求需要自定义一些服务端的功能，这时候就需要改造Next.js自带的服务端功能了。&lt;/p&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://nextjs.org/docs/advanced-features/custom-server&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Custom Server&lt;/a&gt;。koa的例子可以在官方范例代码库中进行查看：&lt;a href=&quot;https://github.com/vercel/next.js/tree/master/examples/custom-server-koa&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Custom Koa Server example&lt;/a&gt;。此外，还有一篇博客讲得不错：&lt;a href=&quot;https://cloudreports.net/nextjs-koajs-create-custom-nextjs-server-with-koajs/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;NextJs + KoaJs Create custom NextJs server with KoaJs&lt;/a&gt;。以及，另一个例子可以参考：&lt;a href=&quot;https://github.com/fridays/next-routes#on-the-server&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;fridays/next-routes#on-the-server&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;不过官方的文档给出的信息其实也相当有限，没有任何对于&lt;code class=&quot;language-text&quot;&gt;next&lt;/code&gt;命令的细致解释，如果想要知道官方启动命令实际上做了什么，就只能去阅读源码了。简单看了下，除了启动服务器之外，next命令还是做了不少事情的，如果想要在保证这些功能的情况下兼容koa的话，是相当困难的。&lt;/p&gt;
&lt;p&gt;这里更建议的做法是启一个纯粹的koa后端作为API的服务器，而将基本的前端页面和pages交给Next.js来进行服务。这样就可以绕开必须改动或者无法使用next命令的情况。&lt;/p&gt;
&lt;h2 id=&quot;8-问题及解决&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-%E9%97%AE%E9%A2%98%E5%8F%8A%E8%A7%A3%E5%86%B3&quot; aria-label=&quot;8 问题及解决 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. 问题及解决&lt;/h2&gt;
&lt;h3 id=&quot;81-typeorm&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#81-typeorm&quot; aria-label=&quot;81 typeorm permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1 TypeORM&lt;/h3&gt;
&lt;p&gt;初始Versions&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;next: 9.4.4
typeorm: 0.0.25&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在添加一系列typeorm相关代码之后，next.js的编译会遇到报错（无法正常build）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Syntax error: Support for the experimental syntax &apos;decorators-legacy&apos; isn&apos;t currently enabled&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解决方法见：&lt;a href=&quot;https://stackoverflow.com/a/52765213&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Syntax error - Support for the experimental syntax ‘decorators-legacy’ isn’t currently enabled&lt;/a&gt;，需要在项目根目录添加文件&lt;code class=&quot;language-text&quot;&gt;.babelrc&lt;/code&gt;，并添加内容（关于babel的客制化，官方文档见：&lt;a href=&quot;https://nextjs.org/docs/advanced-features/customizing-babel-config&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Customizing Babel Config&lt;/a&gt;）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;plugins&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&quot;@babel/plugin-proposal-decorators&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;legacy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;presets&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;next/babel&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;当然还需要安装扩展：&lt;code class=&quot;language-text&quot;&gt;yarn add @babel/plugin-proposal-decorators -D&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;接下来会遇到第二个报错：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;error - ./node_modules/typeorm/browser/driver/DriverFactory.js
Attempted import error: &apos;AuroraDataApiPostgresDriver&apos; is not exported from &apos;./postgres/PostgresDriver&apos;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解决方法见：&lt;a href=&quot;https://github.com/typeorm/typeorm/issues/6110&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Typeorm/browser cannot be compiled since version 0.2.25 #6110&lt;/a&gt;，解决方案简单粗暴，将typeorm的版本降到&lt;code class=&quot;language-text&quot;&gt;0.2.24&lt;/code&gt;即可。&lt;/p&gt;
&lt;p&gt;然后会遇到第三个报错：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;warn  - ./node_modules/typeorm/browser/driver/react-native/ReactNativeDriver.js
Module not found: Can&apos;t resolve &apos;react-native-sqlite-storage&apos; in &apos;./node_modules/typeorm/browser/driver/react-native&apos;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;解决方法见：&lt;a href=&quot;https://github.com/typeorm/typeorm/issues/2158#issuecomment-626984473&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;browser: Can’t resolve ‘react-native-sqlite-storage’ #2158&lt;/a&gt;。创建一个假的stub package即可。&lt;/p&gt;
&lt;p&gt;然后就可以在&lt;code class=&quot;language-text&quot;&gt;_app.tsx:MyApp.getInitialProps&lt;/code&gt;进行数据库连接的初始化。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;getConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err &lt;span class=&quot;token keyword&quot;&gt;instanceof&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ConnectionNotFoundError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Database&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getConnectionOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;到实际使用的时候最后仍旧会有问题（参见：&lt;a href=&quot;https://github.com/vercel/next.js/discussions/12254&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Use TypeORM with Next.js #12254&lt;/a&gt;）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;RepositoryNotFoundError: No repository for &quot;...&quot; was found. Looks like this entity is not registered in current &quot;default&quot; connection?
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;简单来说就是和数据库的连接正常建立了，但本地的entities文件找不到。我尝试过很多方法来解决这个问题，但最终都不能很好解决。猜想可能是next会创建build文件，而build文件中找不到entities（虽然我也尝试过给予entities绝对路径，但最后也不行）。最后还是放弃了在SSR中使用typeorm，所有的next.js中的数据访问全部都通过API来访问后端的koa服务器来解决，不再进行服务器代码直接处理。&lt;/p&gt;
&lt;p&gt;这样当然会有不小的性能损耗，其实绕开typeorm直接在服务器自己建立连接来访问数据库也是可行的，不过小项目就算了，代码量多了维护起来比较麻烦。&lt;/p&gt;
&lt;h2 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nextjs.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://nextjs.org/learn/basics/create-nextjs-app&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Create a Next.js App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.freecodecamp.org/news/the-next-js-handbook/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The Next.js Handbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://learnku.com/articles/40668&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Next.js 入门超详解教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vercel/next.js/issues/7607&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;[RFC] Dynamic Routes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/fridays/next-routes&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;fridays/next-routes&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/fridays/next-routes/issues/19&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Koa usage #19&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://web.dev/route-prefetching-in-nextjs/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Route prefetching in Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://reactjs.org/docs/hooks-state.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Using the State Hook - React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://reactjs.org/docs/hooks-effect.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Using the Effect Hook - React&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.robinwieruch.de/react-hooks-fetch-data&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to fetch data with React Hooks?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;useEffect 完整指南&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.carbonfive.com/replacing-component-lifecycle-methods-with-react-hooks/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Replacing Component Lifecycle Methods with React Hooks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/a/54004148&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Should I use one or many useEffect in component?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vercel/next.js/issues/2252&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Where to store persistent/global data? #2252&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/5d8ad2c7518825091471fd26&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Next.js实践总结 - 登录授权验证最佳方案&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/5c07a0bbf265da613438308c&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Next.js脚手架进阶 — 封装fetch &amp;#x26;&amp;#x26; 增加中间件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/5b868b45e51d4538ae4db7ca&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Next.js踩坑入门系列（三）— 目录重构&amp;#x26;&amp;#x26;再谈路由&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cloudreports.net/nextjs-koajs-create-custom-nextjs-server-with-koajs/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;NextJs + KoaJs Create custom NextJs server with KoaJs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[youtube-dl 及 ffmpeg 相关]]></title><link>https://xenojoshua.com/posts/2020/05/youtube-dl</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/05/youtube-dl</guid><pubDate>Mon, 18 May 2020 06:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-youtube-dl-403&quot;&gt;1. youtube-dl 403&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%89%8B%E5%8A%A8%E4%B8%8B%E8%BD%BD%E5%8F%8A%E8%A7%86%E9%A2%91%E5%89%AA%E8%BE%91%E7%9B%B8%E5%85%B3&quot;&gt;2. 手动下载及视频剪辑相关&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-youtube-dl-403&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-youtube-dl-403&quot; aria-label=&quot;1 youtube dl 403 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. youtube-dl 403&lt;/h2&gt;
&lt;p&gt;在使用&lt;a href=&quot;https://github.com/ytdl-org/youtube-dl&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;youtube-dl&lt;/a&gt;进行下载的时候，时不时会遇到403报错，导致无法正常进行下载。搜了下，github上关于403报错的issue还真不少，有效的解决方案全部是要求使用extension从浏览器中导出cookie信息到文件，然后使用&lt;code class=&quot;language-text&quot;&gt;--cookies&lt;/code&gt;导入，就能正常使用了。但实际上操作下来，仍旧会报错。&lt;/p&gt;
&lt;p&gt;其实只需要一个简单命令就能解决了：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ youtube-dl --rm-cache-dir&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;2-手动下载及视频剪辑相关&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%89%8B%E5%8A%A8%E4%B8%8B%E8%BD%BD%E5%8F%8A%E8%A7%86%E9%A2%91%E5%89%AA%E8%BE%91%E7%9B%B8%E5%85%B3&quot; aria-label=&quot;2 手动下载及视频剪辑相关 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 手动下载及视频剪辑相关&lt;/h2&gt;
&lt;p&gt;有的时候因为某些原因，使用软件下载不是很好处理，就需要手动操作，一般来说可用的下载网站随便google下就能找到，这里列几个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bitdownloader.com/en2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://bitdownloader.com/en2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.savethevideo.com/download&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://www.savethevideo.com/download&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下载下来的某些源是没有音频的，就需要手动处理下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 抽取withsound.mp4中的音频到audio.aac文件&lt;/span&gt;
$ ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; withsound.mp4 &lt;span class=&quot;token parameter variable&quot;&gt;-vn&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-acodec&lt;/span&gt; copy audio.aac
&lt;span class=&quot;token comment&quot;&gt;# 不改变任何内容，直接结合视频/音频封装为MKV/MP4&lt;/span&gt;
$ ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; videoplayback.webm &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; audio.aac &lt;span class=&quot;token parameter variable&quot;&gt;-c:v&lt;/span&gt; copy &lt;span class=&quot;token parameter variable&quot;&gt;-c:a&lt;/span&gt; copy &lt;span class=&quot;token parameter variable&quot;&gt;-strict&lt;/span&gt; experimental output.mkv
$ ffmpeg &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; videoplayback.mp4 &lt;span class=&quot;token parameter variable&quot;&gt;-i&lt;/span&gt; audio.aac &lt;span class=&quot;token parameter variable&quot;&gt;-c:v&lt;/span&gt; copy &lt;span class=&quot;token parameter variable&quot;&gt;-c:a&lt;/span&gt; copy &lt;span class=&quot;token parameter variable&quot;&gt;-strict&lt;/span&gt; experimental output.mp4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Concurrency]]></title><link>https://xenojoshua.com/posts/2020/05/golang-concurrency</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/05/golang-concurrency</guid><pubDate>Sun, 03 May 2020 05:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E8%B5%84%E6%96%99&quot;&gt;2. 资料&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E9%A2%9D%E5%A4%96%E7%9A%84%E5%87%A0%E7%82%B9&quot;&gt;3. 额外的几点&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h2&gt;
&lt;p&gt;Go语言的并发支持在语言上是第一级原生直接支持的，就像异步事件在Node.js上是语言原生支持的一样。Go语言的并发与其他语言的多线程使用还有点不太一样，在使用的时候需要从思路上理解这个”原生支持”的概念，才能用好。因此这篇博文就对其中的一些内容做个整理，此外在&lt;a href=&quot;https://github.com/agreatfool/golang-practice&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;golang-practice&lt;/a&gt;这个代码库中进行实践操作，并进行监控观察效果。&lt;/p&gt;
&lt;h2 id=&quot;2-资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E8%B5%84%E6%96%99&quot; aria-label=&quot;2 资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 资料&lt;/h2&gt;
&lt;p&gt;因着Go语言在国内的火热，大量分析和资料其实都有了，这里我尽量多做整理，不做重复发明轮子的无用功：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;channel &amp;#x26; goroutine&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483671&amp;#x26;idx=1&amp;#x26;sn=1706ffa6deee44a367c34ef84448f55f&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发模型：轻松入门流水线模型&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;channel的基本运用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483680&amp;#x26;idx=1&amp;#x26;sn=de463ebbd088c0acf6c2f0b5f179f38d&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发模型：轻松入门流水线FAN模式&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;channel的多routine协同工作&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483702&amp;#x26;idx=1&amp;#x26;sn=50825426986120a0b306e0f6da176951&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发模型：轻松入门select&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;select的使用，routine的情况判断&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483714&amp;#x26;idx=1&amp;#x26;sn=383e060fbf824d956dab6dc0a5555352&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发模型：select进阶&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;select的高级运用，需要排除的select的分支处理，select的阻塞运用等&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483689&amp;#x26;idx=1&amp;#x26;sn=7dfed7ffb000752a456125513ed99c26&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发模型：并发协程的优雅退出&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;routine的退出方法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483724&amp;#x26;idx=1&amp;#x26;sn=6890ab956c2f0020e9107ef60a388d5b&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发模型：轻松入门协程池&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;和FAN模式有异曲同工之妙&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483788&amp;#x26;idx=1&amp;#x26;sn=3b9d237029bfaa02847b4dacdc118173&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发：再也不愁选channel还是选锁&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;channel和锁的选择问题，根据情况有不同的选择&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s/m8HjfS0tJCibD8hSRIxrBA&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发模型：一招教你无阻塞读写通道&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;巧用select，在阻塞的情况下进入到不同的分支做到零等待&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483803&amp;#x26;idx=1&amp;#x26;sn=7be293f3d03e892058bebbdebed68cb5&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;总结了才知道，原来channel有这么多用法！&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;总结了所有的channel用法和细节&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;sync &amp;#x26; lock&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=Mzg3MTA0NDQ1OQ==&amp;#x26;mid=2247483768&amp;#x26;idx=1&amp;#x26;sn=dd94f808b9ee48d0fe2661d9a5efdd96&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang并发的次优选择：sync包&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;sync包及锁的基本运用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;3-额外的几点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E9%A2%9D%E5%A4%96%E7%9A%84%E5%87%A0%E7%82%B9&quot; aria-label=&quot;3 额外的几点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 额外的几点&lt;/h2&gt;
&lt;p&gt;上面的资料可能因为时间问题，没有提到Context，实际上在真实场景中，对多routine的退出协作使用的更多的是context：&lt;a href=&quot;https://blog.golang.org/context&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Concurrency Patterns: Context&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;channel和锁之间的选择简单来说就是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果有共享内存需要在多个routine之间共用，选择锁&lt;/li&gt;
&lt;li&gt;如果所有的内存都无需在routine之间共享，选择channel&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[grpc_tools_node_protoc_ts 对 @grpc/grpc-js 的支持]]></title><link>https://xenojoshua.com/posts/2020/04/grpc-js-support</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/04/grpc-js-support</guid><pubDate>Thu, 23 Apr 2020 12:02:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-grpcgrpc-js&quot;&gt;1. @grpc/grpc-js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-grpcgrpc-js&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-grpcgrpc-js&quot; aria-label=&quot;1 grpcgrpc js permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. @grpc/grpc-js&lt;/h2&gt;
&lt;p&gt;最近&lt;a href=&quot;https://www.npmjs.com/package/grpc_tools_node_protoc_ts&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc_tools_node_protoc_ts&lt;/a&gt;收到一个issue，问我可不可以支持&lt;a href=&quot;https://www.npmjs.com/package/@grpc/grpc-js&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;@grpc/grpc-js&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这个库倒是不陌生，前几年就已经有了，只不过一直都没有过1.0的正式版本，一直在开发阶段。最近看了下，已经到&lt;code class=&quot;language-text&quot;&gt;1.0.1&lt;/code&gt;版本了，基本上功能完备。和提issue的人讨论了下，主要诉求是使用这个纯js实现的库做到更小的docker镜像，以及在electron这种容器中使用的时候更容易构建。应该说理由还是相当充分的，于是就花了1天多点的时间做了下migration。&lt;/p&gt;
&lt;p&gt;因为版本做完之后用英文已经写过一遍文档了，这里就不啰嗦了，直接看英语文档即可：&lt;a href=&quot;https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/master/doc/grpcjs_support.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;@grpc/grpc-js support&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[grpc-tools@1.8.1 安装问题]]></title><link>https://xenojoshua.com/posts/2020/04/grpc-tools</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/04/grpc-tools</guid><pubDate>Wed, 22 Apr 2020 01:52:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E9%97%AE%E9%A2%98&quot;&gt;1. 问题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E8%A7%A3%E5%86%B3&quot;&gt;2. 解决&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E9%97%AE%E9%A2%98&quot; aria-label=&quot;1 问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 问题&lt;/h2&gt;
&lt;p&gt;安装最新版本&lt;code class=&quot;language-text&quot;&gt;grpc-tools@1.8.1&lt;/code&gt;的时候遇到了不少问题，这里做下记录。&lt;/p&gt;
&lt;p&gt;环境：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# OS
# MacOS@10.14.6
$ node --version
# v10.15.2
$ npm --version
# 6.14.4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;安装1.8.1版本的时候，直接使用npm进行会报错：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ npm install grpc-tools@1.8.1 -g

npm install grpc-tools@1.8.1 -g
/usr/local/bin/grpc_tools_node_protoc -&gt; /usr/local/lib/node_modules/grpc-tools/bin/protoc.js
/usr/local/bin/grpc_tools_node_protoc_plugin -&gt; /usr/local/lib/node_modules/grpc-tools/bin/protoc_plugin.js

&gt; grpc-tools@1.8.1 install /usr/local/lib/node_modules/grpc-tools
&gt; node-pre-gyp install

node-pre-gyp WARN Using needle for node-pre-gyp https download
node-pre-gyp ERR! install error
node-pre-gyp ERR! stack Error: 503 status code downloading tarball https://node-precompiled-binaries.grpc.io/grpc-tools/v1.8.1/darwin-x64.tar.gz
node-pre-gyp ERR! stack     at PassThrough.&amp;lt;anonymous&gt; (/usr/local/lib/node_modules/grpc-tools/node_modules/node-pre-gyp/lib/install.js:149:27)
node-pre-gyp ERR! stack     at PassThrough.emit (events.js:194:15)
node-pre-gyp ERR! stack     at ClientRequest.&amp;lt;anonymous&gt; (/usr/local/lib/node_modules/grpc-tools/node_modules/needle/lib/needle.js:482:9)
node-pre-gyp ERR! stack     at Object.onceWrapper (events.js:277:13)
node-pre-gyp ERR! stack     at ClientRequest.emit (events.js:189:13)
node-pre-gyp ERR! stack     at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:556:21)
node-pre-gyp ERR! stack     at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
node-pre-gyp ERR! stack     at Socket.socketOnData (_http_client.js:442:20)
node-pre-gyp ERR! stack     at Socket.emit (events.js:189:13)
node-pre-gyp ERR! stack     at addChunk (_stream_readable.js:284:12)
node-pre-gyp ERR! System Darwin 18.7.0
node-pre-gyp ERR! command &quot;/usr/local/bin/node&quot; &quot;/usr/local/lib/node_modules/grpc-tools/node_modules/.bin/node-pre-gyp&quot; &quot;install&quot;
node-pre-gyp ERR! cwd /usr/local/lib/node_modules/grpc-tools
node-pre-gyp ERR! node -v v10.15.2
node-pre-gyp ERR! node-pre-gyp -v v0.12.0
node-pre-gyp ERR! not ok
503 status code downloading tarball https://node-precompiled-binaries.grpc.io/grpc-tools/v1.8.1/darwin-x64.tar.gz
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! grpc-tools@1.8.1 install: `node-pre-gyp install`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the grpc-tools@1.8.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/Jonathan/.npm/_logs/2020-04-22T01_31_02_124Z-debug.log&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;2-解决&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E8%A7%A3%E5%86%B3&quot; aria-label=&quot;2 解决 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 解决&lt;/h2&gt;
&lt;p&gt;多番尝试之后，直接下载&lt;a href=&quot;https://github.com/grpc/grpc-node&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://github.com/grpc/grpc-node&lt;/a&gt;代码到本地，然后将解压文件中的&lt;code class=&quot;language-text&quot;&gt;packages/grpc-tools&lt;/code&gt;拷贝到&lt;code class=&quot;language-text&quot;&gt;/usr/local/lib/node_modules&lt;/code&gt;文件夹下。&lt;/p&gt;
&lt;p&gt;这样就能使用npm命令检查到这个包了（虽然仍有部分报错信息）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ npm list -g --depth=0 | grep grpc-tools
# ├── grpc-tools@1.8.1
# npm ERR! missing: node-pre-gyp@^0.12.0, required by grpc-tools@1.8.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;但实际使用的时候仍旧会有问题：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Error: spawn /usr/local/lib/node_modules/grpc-tools/bin/protoc ENOENT&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;意思是说找不到包下的bin文件夹下的&lt;code class=&quot;language-text&quot;&gt;protoc&lt;/code&gt;文件，之前bin文件的链接是这么做的：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/usr/local/bin/grpc_tools_node_protoc -&gt; /usr/local/lib/node_modules/grpc-tools/bin/protoc.js
/usr/local/bin/grpc_tools_node_protoc_plugin -&gt; /usr/local/lib/node_modules/grpc-tools/bin/protoc_plugin.js&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;包的bin文件夹下面也确实有这两个js文件，但确实没有不带js后缀的bin文件。&lt;/p&gt;
&lt;p&gt;然后下载了之前安装错误时候提到的那个tar包：&lt;a href=&quot;https://node-precompiled-binaries.grpc.io/grpc-tools/v1.8.1/darwin-x64.tar.gz&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://node-precompiled-binaries.grpc.io/grpc-tools/v1.8.1/darwin-x64.tar.gz&lt;/a&gt;，解压之后发现里面就只有一个bin文件夹，而文件夹内就正好有两个不带js后缀的bin文件，将这两个解压出来的文件放到&lt;code class=&quot;language-text&quot;&gt;/usr/local/lib/node_modules/grpc-tools/bin&lt;/code&gt;下。后续就能正常使用了。&lt;/p&gt;
&lt;p&gt;至于为什么会503报错，以及为什么bin文件夹下有两套文件，这个就暂时先不去考虑了。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[日语自学笔记]]></title><link>https://xenojoshua.com/posts/2020/03/japanese</link><guid isPermaLink="false">https://xenojoshua.com/posts/2020/03/japanese</guid><pubDate>Wed, 11 Mar 2020 14:22:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%AD%A6%E4%B9%A0%E7%BB%8F%E9%AA%8C&quot;&gt;1. 学习经验&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#11-%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8D&quot;&gt;1.1 自我介绍&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#12-%E6%A0%B8%E5%BF%83%E8%AF%AD%E6%B3%95%E7%82%B9%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF%E6%8E%A8%E8%8D%90&quot;&gt;1.2 核心语法点学习路线推荐&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#13-%E5%A8%B1%E4%B9%90%E4%B8%8E%E5%AD%A6%E4%B9%A0&quot;&gt;1.3 娱乐与学习&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90&quot;&gt;2. 学习资源&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E5%AD%A6%E6%A0%A1%E8%AF%AD%E6%B3%95--%E6%95%99%E8%82%B2%E8%AF%AD%E6%B3%95&quot;&gt;2.1 学校语法 / 教育语法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E5%87%BA%E5%8F%A3%E6%97%A5%E8%AF%AD--%E5%A4%A7%E5%AE%B6%E7%9A%84%E6%97%A5%E6%9C%AC%E8%AF%AD&quot;&gt;2.2 出口日语 / 大家的日本语&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-%E6%97%B6%E9%9B%A8%E6%97%A5%E8%AF%AD&quot;&gt;2.3 时雨日语&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#24-japanese-grammar-guide--%E6%97%A5%E8%AF%AD%E8%AF%AD%E6%B3%95%E6%8C%87%E5%8D%97&quot;&gt;2.4 Japanese Grammar Guide / 日语语法指南&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#25-%E6%A0%87%E5%87%86%E6%97%A5%E8%AF%AD%E8%AF%AD%E6%B3%95%E9%A1%BE%E6%98%8E%E8%80%80%E7%89%88&quot;&gt;2.5 标准日语语法顾明耀版&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#26-%E5%85%B6%E4%BB%96&quot;&gt;2.6 其他&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#27-%E8%BD%AF%E4%BB%B6&quot;&gt;2.7 软件&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%9F%BA%E7%A1%80&quot;&gt;3. 基础&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E4%BA%94%E5%8D%81%E9%9F%B3&quot;&gt;3.1 五十音&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E5%9F%BA%E6%9C%AC%E5%8F%91%E9%9F%B3&quot;&gt;3.2 基本发音&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E5%8A%A8%E8%AF%8D&quot;&gt;4. 动词&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E6%B4%BB%E7%94%A8&quot;&gt;4.1 活用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E6%B4%BB%E7%94%A8%E5%BD%A2&quot;&gt;4.2 活用形&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#421-%E6%9C%AA%E7%84%B6%E5%BD%A2&quot;&gt;4.2.1 未然形&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#422-%E8%BF%9E%E7%94%A8%E5%BD%A2&quot;&gt;4.2.2 连用形&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#453-%E7%BB%88%E6%AD%A2%E5%BD%A2&quot;&gt;4.5.3 终止形&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#454-%E8%BF%9E%E4%BD%93%E5%BD%A2&quot;&gt;4.5.4 连体形&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#455-%E5%81%87%E5%AE%9A%E5%BD%A2&quot;&gt;4.5.5 假定形&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#456-%E5%91%BD%E4%BB%A4%E5%BD%A2&quot;&gt;4.5.6 命令形&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E5%8A%A8%E8%AF%8D%E5%88%86%E7%B1%BB&quot;&gt;4.3 动词分类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%A7%84%E5%BE%8B&quot;&gt;4.4 活用的规律&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#441-%E4%BA%94%E6%AE%B5%E5%8A%A8%E8%AF%8D&quot;&gt;4.4.1 五段动词&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#442-%E4%B8%80%E6%AE%B5%E5%8A%A8%E8%AF%8D&quot;&gt;4.4.2 一段动词&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#443-%E3%82%B5%E5%8F%98%E5%8A%A8%E8%AF%8D&quot;&gt;4.4.3 サ变动词&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#444-%E3%82%AB%E5%8F%98%E5%8A%A8%E8%AF%8D&quot;&gt;4.4.4 カ变动词&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#446-%E9%9F%B3%E4%BE%BF&quot;&gt;4.4.6 音便&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#45-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%8C%83%E5%BC%8F&quot;&gt;4.5 活用的范式&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E5%BD%A2%E5%AE%B9%E8%AF%8D&quot;&gt;5. 形容词&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-%E6%B4%BB%E7%94%A8&quot;&gt;5.1 活用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%A7%84%E5%BE%8B&quot;&gt;5.2 活用的规律&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#53-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%8C%83%E5%BC%8F&quot;&gt;5.3 活用的范式&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-%E5%BD%A2%E5%AE%B9%E5%8A%A8%E8%AF%8D&quot;&gt;6. 形容动词&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-%E6%B4%BB%E7%94%A8&quot;&gt;6.1 活用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%A7%84%E5%BE%8B&quot;&gt;6.2 活用的规律&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#63-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%8C%83%E5%BC%8F&quot;&gt;6.3 活用的范式&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-%E5%8A%A8%E8%AF%8D%E7%9A%84%E4%BD%93%E6%97%B6%E6%80%81&quot;&gt;7. 动词的体、时、态&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#71-%E7%90%86%E8%A7%A3%E5%8A%A8%E8%AF%8D%E7%9A%84%E4%BD%93%E6%97%B6%E6%80%81&quot;&gt;7.1 理解动词的体、时、态&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#72-%E4%BD%93%E6%97%B6%E6%80%81%E8%AF%A6%E8%A7%A3&quot;&gt;7.2 体时态详解&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#721-%E4%B8%80%E8%88%AC%E6%97%B6%E6%80%81&quot;&gt;7.2.1 一般时态&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#722-%E8%BF%9B%E8%A1%8C%E6%97%B6%E6%80%81%E6%8C%81%E7%BB%AD%E4%BD%93&quot;&gt;7.2.2 进行时态（持续体）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#723-%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%9C%E7%8A%B6%E6%80%81%E5%AD%98%E7%BB%AD%E4%BD%93-%E5%AE%8C%E6%88%90%E6%97%B6%E6%80%81&quot;&gt;7.2.3 行为结果、状态（存续体）/ 完成时态△&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#724-%E5%AE%8C%E6%88%90%E6%97%B6%E6%80%81%E5%AE%8C%E6%88%90%E4%BD%93&quot;&gt;7.2.4 完成时态（完成体）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#725-%E5%AE%8C%E6%88%90%E5%87%86%E5%A4%87%E5%87%86%E5%A4%87%E4%BD%93-%E5%AE%8C%E6%88%90%E6%97%B6%E6%80%81--%E5%B0%86%E6%9D%A5%E6%89%93%E7%AE%97&quot;&gt;7.2.5 完成准备（准备体）/ 完成时态△ / 将来打算&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#726-%E8%A2%AB%E5%8A%A8%E6%80%81&quot;&gt;7.2.6 被动态&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#727-%E4%BD%BF%E5%8A%A8%E6%80%81%E5%91%BD%E4%BB%A4%E6%94%BE%E4%BB%BB&quot;&gt;7.2.7 使动态：命令、放任&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#728-%E5%8F%AF%E8%83%BD%E6%80%81%E8%83%BD%E5%8A%9B%E5%8F%AF%E8%83%BD%E6%80%A7%E8%AE%B8%E5%8F%AF&quot;&gt;7.2.8 可能态：能力、可能性、许可&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#729-%E8%87%AA%E7%84%B6%E5%8F%91%E7%94%9F%E6%80%81&quot;&gt;7.2.9 自然发生态&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-%E7%96%91%E9%9A%BE--%E6%80%BB%E7%BB%93&quot;&gt;8. 疑难 / 总结&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#81-%E5%8F%91%E9%9F%B3%E5%8D%95%E8%AF%8D%E7%9A%84%E4%BF%83%E9%9F%B3%E9%95%BF%E9%9F%B3&quot;&gt;8.1 发音：单词的促音/长音&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#82-%E5%8F%91%E9%9F%B3%E6%B8%85%E9%9F%B3%E6%B5%8A%E9%9F%B3%E5%8C%BA%E5%88%86&quot;&gt;8.2 发音：清音浊音区分&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#83-%E5%8A%A8%E8%AF%8D%E8%87%AA%E5%8A%A8%E8%AF%8D%E4%BB%96%E5%8A%A8%E8%AF%8D%E5%8C%BA%E5%88%86&quot;&gt;8.3 动词：自动词他动词区分&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#84-%E5%8A%A8%E8%AF%8D%E5%88%86%E7%B1%BB%E7%BB%A7%E7%BB%AD%E7%9E%AC%E9%97%B4%E7%8A%B6%E6%80%81%E5%BD%A2%E5%AE%B9%E6%80%A7&quot;&gt;8.4 动词分类：继续、瞬间、状态、形容性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#85-%E5%8A%A8%E8%AF%8D%E5%88%86%E5%8F%A5%E4%B8%AD%E7%9A%84%E6%97%B6&quot;&gt;8.5 动词：分句中的时&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#86-%E5%8A%A8%E8%AF%8D%E8%A1%A5%E5%8A%A9%E5%8A%A8%E8%AF%8D%E7%9A%84%E6%97%B6%E6%80%81%E5%8F%98%E5%8C%96&quot;&gt;8.6 动词：补助动词的时态变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#87-%E5%8A%A8%E8%AF%8D%E6%8E%88%E5%8F%97%E8%A1%A8%E7%8E%B0&quot;&gt;8.7 动词：授受表现&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#88-%E6%A0%BC%E5%8A%A9%E8%AF%8D%E5%B8%B8%E7%94%A8%E6%95%B4%E7%90%86&quot;&gt;8.8 格助词：常用整理&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#881-%E5%B8%B8%E7%94%A8%E5%9C%BA%E6%99%AF%E6%95%B4%E7%90%86&quot;&gt;8.8.1 常用场景整理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#882-%E3%81%8C-%E4%B8%8E-%E3%82%92&quot;&gt;8.8.2 が 与 を&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#883-%E3%81%AB-%E4%B8%8E-%E3%82%92&quot;&gt;8.8.3 に 与 を&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#884-%E3%81%AF-%E4%B8%8E-%E3%81%8C&quot;&gt;8.8.4 は 与 が&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#885-%E3%81%A8-%E7%9A%84%E7%BB%86%E8%8A%82%E4%B8%8E-%E3%81%AB%E3%82%92-%E7%9A%84%E6%AF%94%E8%BE%83%E4%BB%A5%E5%8F%8A-%E3%81%A3%E3%81%A6&quot;&gt;8.8.5 と 的细节，与 に/を 的比较，以及 って&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#886-%E3%81%8B%E3%82%89-%E4%B8%8E-%E3%81%A7%E5%8E%9F%E6%9D%90%E6%96%99%E7%9A%84%E5%8C%BA%E5%88%AB&quot;&gt;8.8.6 から 与 で，原材料的区别&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#89-%E5%85%B6%E4%BB%96%E5%8A%A9%E8%AF%8D&quot;&gt;8.9 其他助词&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#891-%E3%81%A6-%E7%9A%84%E7%BB%86%E8%8A%82%E4%B8%AD%E9%A1%BF%E3%81%AA%E3%81%84%E3%81%A6&quot;&gt;8.9.1 て 的细节：中顿、ない+て&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#892-%E3%81%AA%E3%81%8C%E3%82%89&quot;&gt;8.9.2 ながら&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#893-%E3%81%A6%E3%82%82%E3%81%A7%E3%82%82-%E8%BF%9E%E7%BB%AD%E5%8A%A9%E8%AF%8D&quot;&gt;8.9.3 ても/でも 连续助词&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#894-%E3%81%A7%E3%82%82-%E6%8F%90%E7%A4%BA%E5%8A%A9%E8%AF%8D&quot;&gt;8.9.4 でも 提示助词&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#895-%E3%81%A8%E3%81%8B&quot;&gt;8.9.5 とか&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#810-%E8%A1%A5%E5%8A%A9%E5%BD%A2%E5%AE%B9%E8%AF%8D&quot;&gt;8.10 补助形容词&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#x-%E9%80%9F%E6%9F%A5%E8%A1%A8&quot;&gt;X. 速查表&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#xi-%E4%BD%93%E6%97%B6%E6%80%81&quot;&gt;X.I 体时态&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xii-%E5%8A%A8%E8%AF%8D%E6%B4%BB%E7%94%A8%E5%BD%A2&quot;&gt;X.II 动词活用形&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xiii-%E5%8A%A8%E8%AF%8D%E6%B4%BB%E7%94%A8&quot;&gt;X.III 动词活用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xiv-%E5%8A%A8%E8%AF%8D%E9%9F%B3%E4%BE%BF&quot;&gt;X.IV 动词音便&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xv-%E5%BD%A2%E5%AE%B9%E8%AF%8D%E6%B4%BB%E7%94%A8&quot;&gt;X.V 形容词活用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xvi-%E5%BD%A2%E5%AE%B9%E8%AF%8D%E8%AF%AD%E6%B3%95&quot;&gt;X.VI 形容词语法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xvii-%E5%BD%A2%E5%AE%B9%E5%8A%A8%E8%AF%8D%E6%B4%BB%E7%94%A8&quot;&gt;X.VII 形容动词活用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xviii-%E5%BD%A2%E5%AE%B9%E5%8A%A8%E8%AF%8D%E8%AF%AD%E6%B3%95&quot;&gt;X.VIII 形容动词语法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xix-%E6%A0%BC%E5%8A%A9%E8%AF%8D%E8%AF%AD%E6%B3%95&quot;&gt;X.IX 格助词语法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xx-%E5%85%B6%E4%BB%96%E5%B8%B8%E7%94%A8%E5%8A%A9%E8%AF%8D%E8%AF%AD%E6%B3%95&quot;&gt;X.X 其他常用助词语法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xi-%E5%B8%B8%E7%94%A8%E8%A1%A8%E8%BE%BE&quot;&gt;XI. 常用表达&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%95%B0%E5%AD%97%E7%9A%84%E8%A1%A8%E8%BE%BE&quot;&gt;数字的表达&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%87%8F%E8%AF%8D%E7%9A%84%E8%A1%A8%E8%BE%BE&quot;&gt;量词的表达&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%AE%97%E6%95%B0%E8%AE%A1%E7%AE%97&quot;&gt;算数计算&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%97%B6%E9%97%B4%E6%97%A5%E6%9C%9F%E7%9A%84%E8%A1%A8%E8%BE%BE&quot;&gt;时间日期的表达&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9C%B0%E7%82%B9%E7%9A%84%E8%A1%A8%E8%BE%BE&quot;&gt;地点的表达&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%97%AE%E8%B7%AF%E7%9A%84%E8%A1%A8%E8%BE%BE&quot;&gt;问路的表达&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B9%B6%E5%88%97%E5%85%B3%E7%B3%BB%E5%A4%9A%E9%A1%B9%E5%8A%A8%E4%BD%9C%E5%A4%9A%E4%B8%AA%E7%9B%AE%E6%A0%87%E7%9A%84%E8%A1%A8%E8%BE%BE&quot;&gt;并列关系、多项动作（多个目标）的表达&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#xii-%E8%AF%AD%E6%B3%95%E8%A7%A3%E6%9E%90%E8%8C%83%E4%BE%8B&quot;&gt;XII. 语法解析范例&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h2 id=&quot;1-学习经验&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%AD%A6%E4%B9%A0%E7%BB%8F%E9%AA%8C&quot; aria-label=&quot;1 学习经验 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 学习经验&lt;/h2&gt;
&lt;p&gt;自己算了下，总共大概花了3个月左右时间学语法，纯语法，不包括单词之类的，算是有点心得，也做了点笔记，可以分享，故有此文。&lt;/p&gt;
&lt;h3 id=&quot;11-自我介绍&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#11-%E8%87%AA%E6%88%91%E4%BB%8B%E7%BB%8D&quot; aria-label=&quot;11 自我介绍 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.1 自我介绍&lt;/h3&gt;
&lt;p&gt;日语学习这方面来说，我也算得上是一个怪人，至少是很偏门的类型，因此这里先做下介绍，也方便读者看是不是合适跟着我的套路来，不至于一下子就带到坑里去。&lt;/p&gt;
&lt;p&gt;正式开始日语学习前的状态：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语法：駄目，生肉漫画能啃个大概意思，生肉小说基本残念&lt;/li&gt;
&lt;li&gt;词汇：一般动画、影视剧里常见的词汇都OK，但因为没有认真学过，所以其实还是駄目&lt;/li&gt;
&lt;li&gt;听力：尚可，生肉动画、影视剧能看个大概，意思能大致理解&lt;/li&gt;
&lt;li&gt;书写：全然駄目，促音、长音之类都不知道，日语输入法也从来没打过，基本上写不出任何东西&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;80后，算是赶上了一个好年代，电视台直接有引进，小学开始接触日本动画；文字上接触日语是从MD的RPG梦幻之星4千年纪的终结开始。将近30年积累下来，到开始正式学日语之前，生肉游戏只要带语音的，都能大概啃下来，PS4上的うたわれるもの1-3，全部都是生肉，直接啃穿没问题。&lt;/p&gt;
&lt;p&gt;19年12月裸考JLPT N2：159/180分。（不得不吐槽JLPT，这证书对于验证语言能力参考价值极低）&lt;/p&gt;
&lt;p&gt;大致上这样。&lt;/p&gt;
&lt;p&gt;这里怀念下当年在电视上能直接看高质量的动画：机器猫、太空堡垒、圣斗士星矢、灌篮高手、超音战士、十二生肖守护神、宇宙骑士、魔神英雄传、魔神坛斗士、罗德岛战记、宠物小精灵、中华小当家，我印象最深的就有这些。&lt;a href=&quot;https://www.bilibili.com/read/cv1341081/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;〔转载〕80后看过的引进动画片，来这里考古吧！—— 考验童年记忆的时刻到了&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;12-核心语法点学习路线推荐&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#12-%E6%A0%B8%E5%BF%83%E8%AF%AD%E6%B3%95%E7%82%B9%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF%E6%8E%A8%E8%8D%90&quot; aria-label=&quot;12 核心语法点学习路线推荐 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.2 核心语法点学习路线推荐&lt;/h3&gt;
&lt;p&gt;开始学日语之前，我的语感和语言积累其实都蛮不错的，但正式开始学习仍旧吃了不少苦头。回过头来我看了下市面上各种各样的教材和教程，感觉都没有在堆量的教学开始之前，把核心路线（纯核心语法）抽出来讲解。&lt;/p&gt;
&lt;p&gt;无论是学校语法还是教育语法，无论是培训班还是大学老师，讲课一般都是：五十音，然后开始一课课讲内容，语法细节一点点铺在每一课中。这种做法有其好处，随着时间的消费，词汇、阅读能力、语感、语法都同步慢慢推进，非常均衡。只要时间（课时）够，后面自然就能融会贯通。但这套做法不适合我，我已经有了足量的准备，只是核心语法点没有入手而已。因此我最后的做法是把顾明耀的语法书整本啃完，然后自己梳理出一套核心语法点，当然这仍旧是很伤的一件事情，因为顾明耀的语法书说是教学书，不如说是论文资料，无论大小的语法细节里面都放进去了。对于我这样想要把核心路径整理出来的人来说，除了花时间从头到尾过一遍之外没有好的办法，事实上我也是这么做的。&lt;/p&gt;
&lt;p&gt;然后，我这里就整理出了一套核心路径，其实新手也完全能按着这个路径来学：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;选门派：&lt;a href=&quot;#ID21000&quot;&gt;学校语法/教育语法&lt;/a&gt;，选一边；可选项是：直接学校语法，或教育语法入门之后再转学校语法（反过来不行）；不推荐教育语法（标日）&lt;/li&gt;
&lt;li&gt;发音：接下来自然是&lt;a href=&quot;#ID31000&quot;&gt;五十音&lt;/a&gt;，和&lt;a href=&quot;#ID32000&quot;&gt;如何发音&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;动词：动词是日语的绝对核心，对于动词的细分（继续、瞬间等等）甚至能影响到语法的应用，在其他语言里这简直是不可想象的
&lt;ul&gt;
&lt;li&gt;活用理解：&lt;a href=&quot;#ID41000&quot;&gt;什么是活用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;活用形理解：活用的种类，以及这些种类的形对应的使用场景，对于各个形的理解非常重要，只有理解了形对应的场景，才能在表达的时候选择正确的活用形来用；&lt;a href=&quot;#ID42000&quot;&gt;活用形讲解&lt;/a&gt;、&lt;a href=&quot;#IDX_II&quot;&gt;全活用形速查表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;动词分类：活用根据动词的类型有几套不同的规则，在对动词进行活用之前显然需要先分辨它属于哪一类；&lt;a href=&quot;#ID43000&quot;&gt;动词分类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;如何活用：如何对动词进行活用；&lt;a href=&quot;#ID44000&quot;&gt;如何活用讲解&lt;/a&gt;、&lt;a href=&quot;#IDX_III&quot;&gt;全活用速查表&lt;/a&gt;以及&lt;a href=&quot;#IDX_IV&quot;&gt;全音便速查表&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;形容词、形容动词：都归类于体言，因此也都有活用，需要花点心思
&lt;ul&gt;
&lt;li&gt;形容词：&lt;a href=&quot;#ID50000&quot;&gt;形容词讲解&lt;/a&gt;、&lt;a href=&quot;#IDX_V&quot;&gt;全活用速查表&lt;/a&gt;、&lt;a href=&quot;#IDX_VI&quot;&gt;全语法点速查表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;形容动词：&lt;a href=&quot;#ID60000&quot;&gt;形容动词讲解&lt;/a&gt;、&lt;a href=&quot;#IDX_VII&quot;&gt;全活用速查表&lt;/a&gt;、&lt;a href=&quot;#IDX_VIII&quot;&gt;全语法点速查表&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;动词的体时态：打个不恰当的比喻，之前的活用类似英语里的&lt;code class=&quot;language-text&quot;&gt;do -&gt; doing&lt;/code&gt;的变化的学习，而体时态则类似于了解了变化之后再去学什么样的语义情况下要用这样的变化（类似进行时就要用ing这样的意思），因此要把动词真的用起来，体时态必不可少
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#ID71000&quot;&gt;理解动词的体、时、态&lt;/a&gt;：分别理解什么是体时态；以及，&lt;a href=&quot;#IDX_I&quot;&gt;全体时态速查表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ID72000&quot;&gt;体时态详解&lt;/a&gt;：有点复杂度的，很难整理出一个捷径，只能一个个仔细过&lt;/li&gt;
&lt;li&gt;补助动词：体时态里涉及到了大量的补助动词，而且在不同的体时态中，一些补助动词的语法点还各不相同，结果就是从单个补助动词的角度来看，语法点都散落在各处，因此这里整理了&lt;a href=&quot;#ID72001&quot;&gt;补助动词速查表&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;格助词：如果说动词、补助动词、体时态算是日语的大脑和四肢的话，格助词就是连接各处的关节，可想而知其重要性
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#IDX_IX&quot;&gt;全格助词语法点速查表&lt;/a&gt;：这是从各格助词的角度整理的语法点表格，一般来说看到某个格助词不理解其用法可以查这里&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ID88010&quot;&gt;常用场景整理速查表&lt;/a&gt;：这是从格助词的使用场合角度整理的语法点表格，如果需要针对某个语法点进行格助词之间的横向比较可以查这里；此外，该章节的后半部分还罗列了一些核心格助词之间的异同和使用难点&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;其他助词：没有格助词那么重要，但也是语法中的重要组成部分，这里有整理一份比较常用见的&lt;a href=&quot;#IDX_X&quot;&gt;助词语法速查表&lt;/a&gt;，同样有&lt;a href=&quot;#ID89000&quot;&gt;使用难点&lt;/a&gt;整理&lt;/li&gt;
&lt;li&gt;到这里基本上所有的核心语法点都全了，发音有了、词汇可以自己背单词、动词+补助动词+体时态+格助词则组成了健全的大脑和四肢，一般的理解以及表达就都OK了，后面就是熟练度的问题&lt;/li&gt;
&lt;li&gt;最后&lt;a href=&quot;#IDXI&quot;&gt;常用表达&lt;/a&gt;这里，整理了一些日常应用中绕不开必然会遇到/需要的知识点&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;13-娱乐与学习&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#13-%E5%A8%B1%E4%B9%90%E4%B8%8E%E5%AD%A6%E4%B9%A0&quot; aria-label=&quot;13 娱乐与学习 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.3 娱乐与学习&lt;/h3&gt;
&lt;p&gt;也说说看片和学习之间的关系。语法这块弄完之后我也尝试过用看片的方式进行学习，效果真的拔群，但操作是这样的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下双语字幕的片&lt;/li&gt;
&lt;li&gt;第一遍看片所有语法点不清晰的地方和单词不认识的地方全部暂停，单词全部摘录到软件里，语法全部搞清楚&lt;/li&gt;
&lt;li&gt;摘录的单词全部过一遍，保证能清晰读出来，搞清楚自动他动&lt;/li&gt;
&lt;li&gt;第二遍以及后续N遍看片，跟着片子进行shadowing&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可见，所谓的看片学习，里面已经完全不存在娱乐的成分了。经常是第一遍&lt;code class=&quot;language-text&quot;&gt;看完&lt;/code&gt;之后我根本已经忘记了片子里讲了什么（摘录单词和看语法打断了）。所以说娱乐和学习真的不能两全，当然如果只是培养语感的话，倒是可以的。&lt;/p&gt;
&lt;h2 id=&quot;2-学习资源&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%AD%A6%E4%B9%A0%E8%B5%84%E6%BA%90&quot; aria-label=&quot;2 学习资源 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 学习资源&lt;/h2&gt;
&lt;h3 id=&quot;21-学校语法--教育语法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E5%AD%A6%E6%A0%A1%E8%AF%AD%E6%B3%95--%E6%95%99%E8%82%B2%E8%AF%AD%E6%B3%95&quot; aria-label=&quot;21 学校语法  教育语法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 学校语法 / 教育语法&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID21000&quot;&gt;&lt;/span&gt;
在开始学语法之前一定要选好门派，后面一般不会轻易更换。不过对新手来说也可以先从教育语法学起，有点基础后再换学校语法（一般不会有反过来的做法）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;学校语法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更注重语法本身的细节。优点是语法分析清晰，学成之后基础扎实，不容易犯错，遇到再难的表达也能轻易分解并分析其语法理论，且因其资历较深（历史久远）有大量配套的教材和工具等。缺点是入门学习较难，适合有基础的学生（或日语母语学生）学习。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;特征：活用分为五段动词、一段动词、サ变动词、カ变动词。&lt;/li&gt;
&lt;li&gt;经典教材：新编日语（高校日语教学广泛使用）、标准日语语法顾明耀版&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;教育语法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更注重学习的入门和语言的应用。优点是上手难度低，快学快用，但学成后语法基础不够扎实，部分活用混乱（遇到ます形的例子到底是サ变动词还是连用形），大量的语法细节被当做习惯用法教（别管为什么这么表达，遇到这种情况就是这么表达的），导致学员学了之后知道怎么用，但不知道为什么是这么用。且在工具书（特别是字典，字典一般都给终止形/原形/辞书形，不会给ます形/て形）使用上，相对学校语法，支持不够好。适合初学者入门学习（要深入学习后面还是得切换学校语法）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;特征：活用分为一类动词、二类动词、三类动词&lt;/li&gt;
&lt;li&gt;经典教材：标准日本语（培训学校广泛使用）、大家的日本语（出口仁老师）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;22-出口日语--大家的日本语&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E5%87%BA%E5%8F%A3%E6%97%A5%E8%AF%AD--%E5%A4%A7%E5%AE%B6%E7%9A%84%E6%97%A5%E6%9C%AC%E8%AF%AD&quot; aria-label=&quot;22 出口日语  大家的日本语 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 出口日语 / 大家的日本语&lt;/h3&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对新人友好，教程循序渐进&lt;/li&gt;
&lt;li&gt;教程构思优秀，整体面向应用，非生硬的纯语法教学，跟着课程可以很快上手使用日语&lt;/li&gt;
&lt;li&gt;youtube上有完全免费的教程视频，良心无比（推荐购买一个手机端教程应用，然后看视频即可，或者直接看视频也可以）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用的是教育语法，对于想深入的学生来说后续相对不利&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;未学习过日语的新手&lt;/li&gt;
&lt;li&gt;想快速使用日语的学生&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;已入学校语法门派的学生&lt;/li&gt;
&lt;li&gt;想深入纯语法知识点的学生&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app/%E5%A4%A7%E5%AE%B6%E5%AD%B8%E6%A8%99%E6%BA%96%E6%97%A5%E6%9C%AC%E8%AA%9E-%E5%88%9D%E7%B4%9A%E6%9C%AC/id919815747&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;大家學標準日本語：初級本 iOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app/%E5%A4%A7%E5%AE%B6%E5%AD%B8%E6%A8%99%E6%BA%96%E6%97%A5%E6%9C%AC%E8%AA%9E-%E4%B8%AD%E7%B4%9A%E6%9C%AC/id950606030&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;大家學標準日本語：中級本 iOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app/%E5%A4%A7%E5%AE%B6%E5%AD%B8%E6%A8%99%E6%BA%96%E6%97%A5%E6%9C%AC%E8%AA%9E-%E9%AB%98%E7%B4%9A%E6%9C%AC/id960608058&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;大家學標準日本語：高級本 iOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app-bundle/%E5%A4%A7%E5%AE%B6%E5%AD%B8%E6%A8%99%E6%BA%96%E6%97%A5%E6%9C%AC%E8%AA%9E%E5%85%A8%E7%B3%BB%E5%88%97/id975800813&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;大家學標準日本語全系列 iOS套装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCDqWakN_owifqIBqyNjg6kg&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;出口日语 youtube&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wJLu_-bJDAw&amp;#x26;list=PLynCeSdpMqxBipKl9EHnBzZFzBnGuB108&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日本語入門&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=SNZYXdt_5p0&amp;#x26;list=PLynCeSdpMqxCfeGRZJk-RdNZqZ3ENCEbI&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日語結構解密&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=U8wniu_c_zc&amp;#x26;list=PLynCeSdpMqxCW-AfMtmIlASAMUVq8wX6k&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;【改訂版】大家的日本語文法解說&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=riUjVcsPbqo&amp;#x26;list=PLynCeSdpMqxCBtZzRikWkdbRGS9csjDYT&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ｎ１文法一覧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=0TbPGbvdOnk&amp;#x26;list=PLynCeSdpMqxD6LeS82vp39kQP8mw_JxlY&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ｎ２文法一覧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=eGxvduVsfJo&amp;#x26;list=PLynCeSdpMqxDS6EC0L7vXYUAVCstRHcQR&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ｎ３文法一覧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=tq7OQec7Dnc&amp;#x26;list=PLynCeSdpMqxD8N-l7AC_aFocINA2CKQKi&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ｎ４文法一覧&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3zRXvtDnev8&amp;#x26;list=PLynCeSdpMqxD4OJHjNB3QkmfzfD7B_s67&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ｎ５文法一覧&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;23-时雨日语&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-%E6%97%B6%E9%9B%A8%E6%97%A5%E8%AF%AD&quot; aria-label=&quot;23 时雨日语 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 时雨日语&lt;/h3&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学校语法&lt;/li&gt;
&lt;li&gt;教学资源的细节非常优秀，学习之后能够掌握得很扎实&lt;/li&gt;
&lt;li&gt;网站上学习资料丰富&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有系统的教程&lt;/li&gt;
&lt;li&gt;没有系统的教学视频&lt;/li&gt;
&lt;li&gt;教学视频很少&lt;/li&gt;
&lt;li&gt;网站上的学习资料只到N3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有一定基础想要把一些细节知识点打磨扎实的学生&lt;/li&gt;
&lt;li&gt;语法速查&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有基础的新手&lt;/li&gt;
&lt;li&gt;教育语法的学生&lt;/li&gt;
&lt;li&gt;希望获得系统教学的学生&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sigure.tw/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨の町&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sigure.tw/learn-japanese/intro/accent/135-boon&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;認識「母音無聲化」&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sigure.tw/learn-japanese/intro/accent/134-accent&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;認識「重音」日文發音&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sigure.tw/comprehensive-learning/knowledge/464&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;為什麼「頑張って」聽起來像「頑張っで」？PTK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/medium&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;中級文法-N3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/elementary&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;進階文法-N4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/basic&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;初級文法-N5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/channel/UCVNBkSt8-VCtPhSu-n7uOlQ&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;时雨日语 youtube&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=7PaH8nvg07A&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨陪你面對現實，日語五十音完整講解│時雨日文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=uXJZAABbBBw&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【如何學習日文發音】weblio重音字典、OJAD線上重音辭典、日劇跟讀示範&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=PnNQ9JfXy5E&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【關於清音聽成濁音這件事】頑張って？頑張っで？【PTK法則？】&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=bHUUyfegNA4&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【3分鐘學會日文動詞分類】五段動詞、上下一段、カ行サ行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=3_0r3nZL_MY&amp;#x26;t=17s&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【五段動詞變化】五段動詞、上下一段、カ行サ行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=xADV9ygZmk0&amp;#x26;t=14s&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【上下一段動詞變化】五段動詞、上下一段、カ行サ行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=0Nn95Uhqt0I&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【サ行カ行動詞變化】五段動詞、上下一段、カ行サ行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=JH03auAJdAc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【動詞的音便】從原形直接記！快速省時間~~五段動詞音便法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=d0pBTsCHsgc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【自動詞、他動詞的用法】自他同形？純自動詞？純他動詞？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;24-japanese-grammar-guide--日语语法指南&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#24-japanese-grammar-guide--%E6%97%A5%E8%AF%AD%E8%AF%AD%E6%B3%95%E6%8C%87%E5%8D%97&quot; aria-label=&quot;24 japanese grammar guide  日语语法指南 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4 Japanese Grammar Guide / 日语语法指南&lt;/h3&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;非常容易入门&lt;/li&gt;
&lt;li&gt;省略了大量细节，只求能够快速理解基本的日语&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;深度不够&lt;/li&gt;
&lt;li&gt;语法讲解不够&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初步理解日语&lt;/li&gt;
&lt;li&gt;学个大概的学生&lt;/li&gt;
&lt;li&gt;学习目标是简单听、读的学生&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要认真学习的学生&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://res.wokanxing.info/jpgramma/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日语语法指南 翻译版&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.guidetojapanese.org/learn/grammar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Japanese Grammar Guide 原版&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;25-标准日语语法顾明耀版&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#25-%E6%A0%87%E5%87%86%E6%97%A5%E8%AF%AD%E8%AF%AD%E6%B3%95%E9%A1%BE%E6%98%8E%E8%80%80%E7%89%88&quot; aria-label=&quot;25 标准日语语法顾明耀版 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.5 标准日语语法顾明耀版&lt;/h3&gt;
&lt;p&gt;大杀器。&lt;/p&gt;
&lt;p&gt;优点是真的认真看完且融会贯通领会了，日语语法就没有你看不懂的地方了。缺点是与其说是教材，不如说是一本科研书，对于读者来说过于艰涩，不适合没有基础的学生。而且由于其编撰完全是按照对日语语言的分解而做的，所以不适合用来做以日语应用为目标的学生的教材（不能一边看一边实践，和大家的日本语是正相反的思路）。&lt;/p&gt;
&lt;p&gt;资源就不放了，网上可以直接购买实体书，PDF全网也不是说下不到，但比较难找。由于阅读便利性的问题（实体书实在是不方便携带和检索），我买了书之后还是下了个PDF，然后用OCR软件做了带索引的文字版本PDF，遇到疑难点可以直接索引跳转方便阅读。&lt;/p&gt;
&lt;h3 id=&quot;26-其他&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#26-%E5%85%B6%E4%BB%96&quot; aria-label=&quot;26 其他 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.6 其他&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zh.wikibooks.org/wiki/%E6%97%A5%E8%AF%AD&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日语教科书 ・日本語にほんごのテキストブック&lt;/a&gt;：一个wiki，只有最基础的语法，但整理的不错&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%B4%BB%E7%94%A8_(%E6%97%A5%E8%AA%9E)&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;活用 (日语)&lt;/a&gt;：动词活用的wiki&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://magiclen.org/jp-lang-verb/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日文動詞變化筆記(3套公式、7個型態、音變與常用18種變化)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://magiclen.org/jp-lang-adjn/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日文形容動詞(な形容詞)變化筆記(1套公式、5種型態與常用16種變化)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://magiclen.org/jp-lang-adj/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日文形容詞(い形容詞)變化筆記(1套公式、5種型態與常用16種變化)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;27-软件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#27-%E8%BD%AF%E4%BB%B6&quot; aria-label=&quot;27 软件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.7 软件&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/jp/app/mazec/id943711253&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;iOS JP mazec&lt;/a&gt;：手写输入软件，方便初学者只识汉字不知读音&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app/moji%E8%BE%9E%E6%9B%B8-%E6%97%A5%E8%AF%AD%E5%AE%9E%E7%94%A8%E8%AF%8D%E5%85%B8/id1021094295&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;iOS CN MOJi辞書: 日语实用词典&lt;/a&gt;：中日词典推荐这个，还可以建立个人词库，把不认的录入进去，后面还可以制作背词计划&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app/mojitest-%E5%AE%9E%E7%94%A8%E8%8B%B1%E8%AF%AD%E6%97%A5%E8%AF%AD%E8%83%8C%E5%8D%95%E8%AF%8D/id1258480187&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;iOS CN MOJiTest: 实用英语日语背单词&lt;/a&gt;：背词库推荐这个，N1、N2之类的；当然后续慢慢就会只需要上面那个了，毕竟背自己录入的单词比较有意义也更有效率&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/jp/app/%E5%A4%A7%E8%BE%9E%E6%B3%89/id632428156&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;iOS JP 大辞泉&lt;/a&gt;：日语词典也需要备一个，中日词典有的时候并不是十分完美&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://apps.apple.com/cn/app/%E5%BD%A9%E4%BA%91%E5%B0%8F%E8%AF%91-%E8%AF%AD%E9%9F%B3%E7%BD%91%E9%A1%B5%E6%96%87%E6%A1%A3%E5%9B%BE%E7%89%87%E5%85%A8%E8%83%BD%E7%BF%BB%E8%AF%91/id1187138321&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;iOS CN 彩云小译 - 语音网页文档图片全能翻译&lt;/a&gt;：类似Google翻译，效果还行，有的时候能看个大概&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;3-基础&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%9F%BA%E7%A1%80&quot; aria-label=&quot;3 基础 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 基础&lt;/h2&gt;
&lt;h3 id=&quot;31-五十音&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E4%BA%94%E5%8D%81%E9%9F%B3&quot; aria-label=&quot;31 五十音 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 五十音&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID31000&quot;&gt;&lt;/span&gt;
&lt;strong&gt;五十音&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;あ ア a&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い イ i&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;う ウ u&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;え エ e&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;お オ o&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;か カ ka&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;き キ ki&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;く ク ku&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;け ケ ke&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;こ コ ko&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;さ サ sa&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;し シ shi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;す ス su&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;せ セ se&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;そ ソ so&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;た タ ta&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ち チ chi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;つ ツ tsu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;て テ te&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;と ト to&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;な ナ na&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;に ニ ni&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぬ ヌ nu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ね ネ ne&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;の ノ no&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;は ハ ha&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ひ ヒ hi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ふ フ fu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;へ ヘ he&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ほ ホ ho&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ま マ ma&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み ミ mi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;む ム mu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;め メ me&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;も モ mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;や ヤ ya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ゆ ユ yu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よ ヨ yo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ら ラ ra&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;り リ ri&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;る ル ru&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;れ レ re&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろ ロ ro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;わ ワ wa&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;を ヲ o(wo)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;きゃ キャ kya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きゅ キュ kyu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きょ キョ kyo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;しゃ シャ sha&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しゅ シュ shu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しょ ショ sho&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ちゃ チャ cha&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ちゅ チュ chu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ちょ チョ cho&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;にゃ ニャ nya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にゅ ニュ nyu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にょ ニョ nyo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ひゃ ヒャ hya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ひゅ ヒュ hyu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ひょ ヒョ hyo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;みゃ ミャ mya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みゅ ミュ myu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みょ ミョ myo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;りゃ リョ rya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;りゅ リュ ryu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;りょ リョ ryo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;が ガ ga&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぎ ギ gi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぐ グ gu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;げ ゲ ge&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ご ゴ go&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ざ ザ za&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じ ジ ji&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ず ズ zu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぜ ゼ ze&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぞ ゾ zo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;だ ダ da&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぢ ヂ ji(di)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;づ ヅ zu(du)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;で デ de&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ど ド do&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ば バ ba&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;び ビ bi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぶ ブ bu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べ ベ be&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぼ ボ bo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ぱ パ pa&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぴ ピ pi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぷ プ pu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぺ ペ pe&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぽ ポ po&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ぎゃ ギャ gya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぎゅ ギュ gyu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぎょ ギョ gyo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;じゃ ジャ ja&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅ ジュ ju&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じょ ジョ jo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;びゃ ビャ bya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;びゅ ビュ byu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;びょ ビョ byo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ぴゃ ピャ pya&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぴゅ ピュ pyu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぴょ ピョ pyo&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;元音&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;あ a　い i　う u　え e　お o&lt;br&gt;
元音连读：あい 愛，发音长短轻重基本相同&lt;br&gt;
元音的清化：い　う，容易出现清化，下例当中，前面未清化，后面为清化&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;かた 模型 kata 　きた 北方 kita&lt;/li&gt;
&lt;li&gt;かち 胜利 kachi　きち 基地 kichi&lt;/li&gt;
&lt;li&gt;ほし 星星 hoshi　ふし 节 fushi&lt;/li&gt;
&lt;li&gt;せき 座位 seki 　すき 喜欢 suki&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;辅音&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;清音：か　さ　た　な　は　ま　や　ら　わ　ぱ，这些行&lt;br&gt;
浊音：が　ざ　だ　ば，这些行&lt;br&gt;
拗音：きゃ　きゅ　きょ，等类似的&lt;br&gt;
拨音：ん&lt;br&gt;
促音：おと 声音 -＞ おっと otto 丈夫&lt;br&gt;
长音：とり 鸟 -＞ とおり 大街&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;なぁ&lt;/code&gt;之类的打字方法：na&lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt;a&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;外来语专用音节&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;.&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ツァ　tsa&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ファ　fa&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ウィ　wi uli&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ティ　thi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;フィ　fi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ディ　dhi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;トゥ　twu tolu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ドゥ　dwu dolu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;デュ　delyu&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ウェ　we ule&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;シェ　she sle&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;チェ　che&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ツェ　tse&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;フェ　fe&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ジェ　je&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ウィ　wi&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ウォ　ulo&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ツォ　tso&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;フォ　fo&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;英文字母&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | -&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:--- | :--- | :---
A　エー　e | B　ビー　bi | C　シー　shi
D　ディー　dhi | E　イー　i | F　エフ　efu
G　ジー　ji | H　エッチ　ecchi | I　アイ　ai
J　ジェー　je | K　ケー　ke | L　エル　eru
M　エム　emu | N　エヌ　enu | O　オー　o
P　ピー　pi | Q　キュー　kyu | R　アール　aru
S　エス　esu | T　ティー　thi | U　ユー　yu
V　ブイ　bui | W　ダブリュー　daburyu | X　エックス　ekkusu
Y　ワイ　wai | Z　ゼット　zetto／ズィー　zuli&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;汉字&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;音読 おんどく：汉语发音日化&lt;br&gt;
訓読 くんどく：日语发音与汉字含义相结合&lt;/p&gt;
&lt;h3 id=&quot;32-基本发音&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E5%9F%BA%E6%9C%AC%E5%8F%91%E9%9F%B3&quot; aria-label=&quot;32 基本发音 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 基本发音&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID32000&quot;&gt;&lt;/span&gt;
发音这块时雨有一篇讲得很清楚：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/intro/accent/134-accent&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;認識「重音」日文發音&lt;/a&gt;。自学这块容易搞错，所以需要针对性搞清楚。&lt;/p&gt;
&lt;p&gt;单词查询：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.weblio.jp&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;weblio.jp&lt;/a&gt;：有数字注音无发音&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.gavo.t.u-tokyo.ac.jp/ojad/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OJAD&lt;/a&gt;：有划线注音和发音，且有长句和篇章的整体发音注解功能&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;4-动词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E5%8A%A8%E8%AF%8D&quot; aria-label=&quot;4 动词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 动词&lt;/h2&gt;
&lt;h3 id=&quot;41-活用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E6%B4%BB%E7%94%A8&quot; aria-label=&quot;41 活用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 活用&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID41000&quot;&gt;&lt;/span&gt;
讲到动词肯定就要提到动词的&lt;code class=&quot;language-text&quot;&gt;活用&lt;/code&gt;，所谓的活用，可以简单理解为因应使用的场景不同，动词本身发生的形变。这里贴下&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%B4%BB%E7%94%A8_(%E6%97%A5%E8%AA%9E)&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;活用WIKI&lt;/a&gt;的描述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;活用（日语：活用 Katsuyō）指的是日语中，用言（动词、形容词、形容动词）和助动词等的词形变化（变位）。在进行变化时，这些词语的语尾（也就是送假名），甚至是整个词语都会发生变化。在日语中，能够活用的词包括了动词、形容词、形容动词及助动词。这些词可以接续某些词语来表示时态变化、词类变化、语态等文法上的功能。在连接不同的助词时，有时也需要将词语活用变化。几乎所有的活用都是规律的。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;42-活用形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-%E6%B4%BB%E7%94%A8%E5%BD%A2&quot; aria-label=&quot;42 活用形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 活用形&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID42000&quot;&gt;&lt;/span&gt;
用言在活用后所产生的各种不同型态就被称作&lt;code class=&quot;language-text&quot;&gt;活用形&lt;/code&gt;。这里的理解很重要，因为学习语言的最终目的是为了使用，而活用形则是最贴近使用场景的一种概念。下面分几种活用形，进行举例描述。&lt;/p&gt;
&lt;h4 id=&quot;421-未然形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#421-%E6%9C%AA%E7%84%B6%E5%BD%A2&quot; aria-label=&quot;421 未然形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.1 未然形&lt;/h4&gt;
&lt;p&gt;主要用来接续表示否定的助动词“-ない”，被动、可能助动词“-れる‧られる”，使役助动词“せる‧させる”，意志、推量助动词“う”等等。&lt;/p&gt;
&lt;p&gt;场景：否定（ない）、使役（させる、せる）、被动（られる、れる）、可能（られる、れる）、尊敬（られる、れる）、意志和推测（う、よう、まい）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;否定&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“ない“、“ぬ“。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;雨が&lt;code class=&quot;language-text&quot;&gt;降らない&lt;/code&gt;。/ 不下雨。&lt;/li&gt;
&lt;li&gt;親からの手紙がなかなか&lt;code class=&quot;language-text&quot;&gt;来ない&lt;/code&gt;。/ 家里的信怎么等也不来。&lt;/li&gt;
&lt;li&gt;一ヶ月も&lt;code class=&quot;language-text&quot;&gt;せぬ&lt;/code&gt;うちに治った。/ 还没到一个月就治好了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使役&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“させる (せる）”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;弟を買い物に&lt;code class=&quot;language-text&quot;&gt;行かせ&lt;/code&gt;た。/ 让弟弟去买东西。&lt;/li&gt;
&lt;li&gt;母は妹を買い物に&lt;code class=&quot;language-text&quot;&gt;行かせる&lt;/code&gt;。／母亲让妹妹去买东西。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;被动&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“られる (れる）”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;雨に&lt;code class=&quot;language-text&quot;&gt;降られ&lt;/code&gt;た。/ 被雨淋了。&lt;/li&gt;
&lt;li&gt;彼は父に&lt;code class=&quot;language-text&quot;&gt;叱られ&lt;/code&gt;た。／他受到了父亲的训斥。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;可能&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“られる (れる）”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;五年後には家が&lt;code class=&quot;language-text&quot;&gt;建てられる&lt;/code&gt;。/ 五年后,房子可以建造起来。&lt;/li&gt;
&lt;li&gt;それは&lt;code class=&quot;language-text&quot;&gt;食べられる&lt;/code&gt;。／那个能吃。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;尊敬&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“られる (れる）”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先生が&lt;code class=&quot;language-text&quot;&gt;帰られ&lt;/code&gt;た。／老师回來了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;意志和推测&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“う(よう)“。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;テレピの音を小さく&lt;code class=&quot;language-text&quot;&gt;しよう&lt;/code&gt;。/ 把电视的声音关小点吧。&lt;/li&gt;
&lt;li&gt;粘土で人形を&lt;code class=&quot;language-text&quot;&gt;作ろう&lt;/code&gt;。/ 用粘土捏个娃娃吧&lt;/li&gt;
&lt;li&gt;これには論理上の欠陥はほとんどないと&lt;code class=&quot;language-text&quot;&gt;言えよう&lt;/code&gt;。/ 大概可以说这里面几乎没有逻辑方面的问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一段动词和サ变动词则需要后接助动词“まい”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;あんなばかなことは二度と&lt;code class=&quot;language-text&quot;&gt;しまい&lt;/code&gt;。/ 那种使事,绝不再做了&lt;/li&gt;
&lt;li&gt;君にはこの役はとても&lt;code class=&quot;language-text&quot;&gt;やれまい&lt;/code&gt;。/ 对你来说,这个角色大概干不了&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;422-连用形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#422-%E8%BF%9E%E7%94%A8%E5%BD%A2&quot; aria-label=&quot;422 连用形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.2 连用形&lt;/h4&gt;
&lt;p&gt;用来接续其他&lt;code class=&quot;language-text&quot;&gt;用言&lt;/code&gt;，以及表示过去・完了的助动词“た”等。也有不接续其他词语，而直接拿来作为名词的用法，例如“休み”（由动词休む的连用形而来，作为名词“休息”）。&lt;/p&gt;
&lt;p&gt;场景：构词用法、中顿、后接助动词（ます、た、たい、そうだ）、后接助词（に；て、ながら、つつ、ても、たって、ては；たり；は、も、でも、さえ；な）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构词用法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;可充当名词或与其他词素构成复合词。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接转成名词：&lt;code class=&quot;language-text&quot;&gt;動き&lt;/code&gt;が激しい、&lt;code class=&quot;language-text&quot;&gt;行き&lt;/code&gt;はよいよい、&lt;code class=&quot;language-text&quot;&gt;帰り&lt;/code&gt;はこわい&lt;/li&gt;
&lt;li&gt;合成词的上位词构成名词：&lt;code class=&quot;language-text&quot;&gt;使い&lt;/code&gt;道、&lt;code class=&quot;language-text&quot;&gt;泣き&lt;/code&gt;虫、&lt;code class=&quot;language-text&quot;&gt;出&lt;/code&gt;ロ&lt;/li&gt;
&lt;li&gt;合成词的上位词构成动词：&lt;code class=&quot;language-text&quot;&gt;流れ&lt;/code&gt;込む、&lt;code class=&quot;language-text&quot;&gt;取り&lt;/code&gt;入れる、&lt;code class=&quot;language-text&quot;&gt;ふり&lt;/code&gt;かける&lt;/li&gt;
&lt;li&gt;合成词的上位词构成形容词：&lt;code class=&quot;language-text&quot;&gt;蒸し&lt;/code&gt;暑い、&lt;code class=&quot;language-text&quot;&gt;聞き&lt;/code&gt;辛い、&lt;code class=&quot;language-text&quot;&gt;焦げ&lt;/code&gt;臭い&lt;/li&gt;
&lt;li&gt;合成词的下位词构成名词：魔法&lt;code class=&quot;language-text&quot;&gt;使い&lt;/code&gt;、湯&lt;code class=&quot;language-text&quot;&gt;吞み&lt;/code&gt;、月&lt;code class=&quot;language-text&quot;&gt;見&lt;/code&gt;、高&lt;code class=&quot;language-text&quot;&gt;飛び&lt;/code&gt;、早&lt;code class=&quot;language-text&quot;&gt;起き&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;中顿&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表示并列，有时隐含有顺接（因果等）、逆接（转折等）等语法意义。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;流れは山を&lt;code class=&quot;language-text&quot;&gt;下り&lt;/code&gt;、谷を&lt;code class=&quot;language-text&quot;&gt;走り&lt;/code&gt;、野をよこぎる。/河流冲下山岗,流过山谷，穿过田野。&lt;/li&gt;
&lt;li&gt;兄は町へ&lt;code class=&quot;language-text&quot;&gt;行き&lt;/code&gt;、僕は留守番をする。/哥哥去上街，我看家。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;后接助动词&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;与助动词一起，构成种种语法意义。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ます&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“ます”，构成敬体。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;僕は君の幸せを&lt;code class=&quot;language-text&quot;&gt;望みます&lt;/code&gt;。/我希望你幸福。&lt;/li&gt;
&lt;li&gt;ご自由にご利用&lt;code class=&quot;language-text&quot;&gt;くださいませ&lt;/code&gt;。/请随便使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;た&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“た”，表示过去、完了、状态以及某些特殊意义。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;真ーはアジア大会で新記録を&lt;code class=&quot;language-text&quot;&gt;立てた&lt;/code&gt;。/真一在亚运会上创造了新纪录。&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;読ん&lt;/code&gt;だ本をすぐに返してください。读完了的书请立即还回。&lt;/li&gt;
&lt;li&gt;やっぱり、かぎはここに&lt;code class=&quot;language-text&quot;&gt;あった&lt;/code&gt;。/钥匙到底还是在这儿。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;たい、たがる&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“たい”、“たがる”，表示愿望。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;今度は立派な論文を&lt;code class=&quot;language-text&quot;&gt;書きたい&lt;/code&gt;。/下次想要写出一篇出色的论文。&lt;/li&gt;
&lt;li&gt;彼は彼女と&lt;code class=&quot;language-text&quot;&gt;結婚したがっ&lt;/code&gt;ている。/他想和她结婚。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;そうだ&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接助动词“そうだ“，表示即将发生某动作或有可能性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不景気で会社が&lt;code class=&quot;language-text&quot;&gt;つぶれそうだ&lt;/code&gt;。/由于不景气,公司即将倒闭。&lt;/li&gt;
&lt;li&gt;簡単に&lt;code class=&quot;language-text&quot;&gt;できそうな&lt;/code&gt;仕事だが、なかなか終わらない。/看似很简单的工作，却怎么也做不完。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;连用+そうだ：与说话者密切相关，说话者参与。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;后接助词&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;动词连用形后还可以接助词，增添某些特殊的意义，实现语法功能。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;格助词 に&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接格助词“に”，表示来去等移动动词的目的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;朝早く鮭を&lt;code class=&quot;language-text&quot;&gt;釣りに&lt;/code&gt;行った。/ー大早就出去钓鮭鱼了。&lt;/li&gt;
&lt;li&gt;いい仕事を&lt;code class=&quot;language-text&quot;&gt;さがしに&lt;/code&gt;東京へ戻った。/回到东京寻求好工作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;接续助词&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接接续助词“て”、“ながら”、“つつ“、“ても”、“たって“、“ては”等。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;春が&lt;code class=&quot;language-text&quot;&gt;来て&lt;/code&gt;、雪が溶けた。/春天来了,冰雪融化了。&lt;/li&gt;
&lt;li&gt;友と&lt;code class=&quot;language-text&quot;&gt;語りつつ&lt;/code&gt;酒を飲む。/与朋友边聊天边饮酒。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;并列助词 たり&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接并列助词“たり“，表示并列或举例。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ー日中&lt;code class=&quot;language-text&quot;&gt;踊ったり&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;歌ったり&lt;/code&gt;した。/一整天又跳舞又唱歌。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;提示助词&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接提示助词“は”、“も“、“でも“、“さえ”等，再后接形式动词“する”，表示对比、强调、例示等含义。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;御恩は決して&lt;code class=&quot;language-text&quot;&gt;忘れは&lt;/code&gt;しない。/决不忘您的思德&lt;/li&gt;
&lt;li&gt;駅の案内を人々はほとんど&lt;code class=&quot;language-text&quot;&gt;聞きも&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;見も&lt;/code&gt;しません。/对于车站内的介绍，人们几乎听也不听，看也不看。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;语气助词 な&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后接语气助词“な”，表示命令或要求。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;危ないから、気を&lt;code class=&quot;language-text&quot;&gt;つけな&lt;/code&gt;。/危险，留神！&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;453-终止形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#453-%E7%BB%88%E6%AD%A2%E5%BD%A2&quot; aria-label=&quot;453 终止形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.3 终止形&lt;/h4&gt;
&lt;p&gt;不接续其他助词，或著接续终助词而置于句末的型态。也是用言尚未活用前的基本型态。（基本形也称辞书形或字典形）&lt;/p&gt;
&lt;p&gt;场景：结句、后接助动词（そうだ、らしい、だろう、でしょう；まい限五段サ变）、后接助词（か；な、ね、よ、なぁ、さ；が、けれども、と、から）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;位于句末，用以结句&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;この花はいい匂いが&lt;code class=&quot;language-text&quot;&gt;する&lt;/code&gt;。/这花发出香味。&lt;/li&gt;
&lt;li&gt;難しい言い回しをやさしく&lt;code class=&quot;language-text&quot;&gt;直す&lt;/code&gt;。/把难懂的话改得易懂些&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;后接助动词，助动词为其增添某种语法意义&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;そうだ、らしい 及 だろう (でしょう）
&lt;ul&gt;
&lt;li&gt;彼は留学の許可を得るため両親を&lt;code class=&quot;language-text&quot;&gt;説得するそうだ&lt;/code&gt;。/据说他为了获得留学的许可要去说服他的父母。&lt;/li&gt;
&lt;li&gt;新人を入れてチームの若返しを&lt;code class=&quot;language-text&quot;&gt;図るらしい&lt;/code&gt;。/好像是吸收新成员,以求队伍的年轻化。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;まい
&lt;ul&gt;
&lt;li&gt;和未然形一样，后接助动词“まい”，表示否定的意志与否定的推测两种意义。只限于五段动词和サ变动词。&lt;/li&gt;
&lt;li&gt;わざわざ嵐の中で登山をするものは&lt;code class=&quot;language-text&quot;&gt;あるまい&lt;/code&gt;。/恐怕没有人特地在暴风雨中登山吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;终止+そうだ：说话者听说的事情，与说话者完全不相关。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;后接助词&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;并列助词 か
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;行くか&lt;/code&gt;行かないか迷っている。/不知该去不该去。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;语气助词
&lt;ul&gt;
&lt;li&gt;后接语气助词“か”、“な”、“ね“、“よ”、“なぁ”、“さ”等，表示各种语气。&lt;/li&gt;
&lt;li&gt;転んだくらいで泣く奴が&lt;code class=&quot;language-text&quot;&gt;あるか&lt;/code&gt;。/有你这样摔了一下就哭的人吗?&lt;/li&gt;
&lt;li&gt;急ぐから、僕はもう&lt;code class=&quot;language-text&quot;&gt;帰るよ&lt;/code&gt;。/我有急事,这就回去。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;接续助词 が、けれども、と、から
&lt;ul&gt;
&lt;li&gt;私は車の連転が&lt;code class=&quot;language-text&quot;&gt;できるが&lt;/code&gt;、兄はできない。/我会开车,可我哥不会。&lt;/li&gt;
&lt;li&gt;会社は今危機に&lt;code class=&quot;language-text&quot;&gt;あるけれども&lt;/code&gt;、つぶれないと思う。/我认为公司虽然处于危机当中，但不会破产。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;454-连体形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#454-%E8%BF%9E%E4%BD%93%E5%BD%A2&quot; aria-label=&quot;454 连体形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.4 连体形&lt;/h4&gt;
&lt;p&gt;用来接续其他的&lt;code class=&quot;language-text&quot;&gt;体言&lt;/code&gt;。几乎与终止形相同，除了形容动词（な形容词）。&lt;/p&gt;
&lt;p&gt;场景：后接体言、后接助动词（ようだ、みたいだ）、后接接续助词（ので、のに；だけ、くらい、ほど、ばかり；しか；の；こと、もの、はず、わけ、ため）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;后接体言，构成该体言的定语&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;流れる水&lt;/code&gt;と&lt;code class=&quot;language-text&quot;&gt;噴き上げる水&lt;/code&gt;。/流満的水和喷涌的水。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;后接助动词 ようだ、みたいだ&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;彼も最近新しい機械を工夫して&lt;code class=&quot;language-text&quot;&gt;いるみたいだ&lt;/code&gt;。/他似乎最近也在琢磨新的机器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;后接接续助词&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;接续助词 ので、のに
&lt;ul&gt;
&lt;li&gt;日本語だけで十分に&lt;code class=&quot;language-text&quot;&gt;表せるのに&lt;/code&gt;、なぜ外国語を取り入れなければならないのでしょう。/只要用日语就足以表达了,可为什么非要吸收外语呢。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;副助词 だけ、くらい、ほど、ばかり
&lt;ul&gt;
&lt;li&gt;人生には、&lt;code class=&quot;language-text&quot;&gt;遭難するぐらい&lt;/code&gt;惨めなことはない。/人生中没有比遇难更悲惨的&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;眺めるだけ&lt;/code&gt;なら、お金は要らない。/如果只是看,那么不要钱。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;提示助词 しか
&lt;ul&gt;
&lt;li&gt;后接提示助词“しか”，再后接否定意义的词语，表示除此之外别无他法&lt;/li&gt;
&lt;li&gt;ここまで来たら、&lt;code class=&quot;language-text&quot;&gt;やるしか&lt;/code&gt;ありません。/到了这一步也只有干了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;后接语气助词 の
&lt;ul&gt;
&lt;li&gt;くずぐずしないで、さっさと&lt;code class=&quot;language-text&quot;&gt;するの&lt;/code&gt;。/别磨贈，快点做!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;后接形式名词
&lt;ul&gt;
&lt;li&gt;后接“こと”、“もの“、“の”、“はず“、“わけ“、“ため”等，将动词名词化，增添意义，或接续由形式名词构成的惯用型。&lt;/li&gt;
&lt;li&gt;ここまで来て登山を&lt;code class=&quot;language-text&quot;&gt;中止するわけ&lt;/code&gt;にはいかない。/已经到了这儿了,不可能停止登山。&lt;/li&gt;
&lt;li&gt;たいていのことは日本語で十分&lt;code class=&quot;language-text&quot;&gt;表せるはず&lt;/code&gt;だ。/大多数事情应该是能用日语表达的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;455-假定形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#455-%E5%81%87%E5%AE%9A%E5%BD%A2&quot; aria-label=&quot;455 假定形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.5 假定形&lt;/h4&gt;
&lt;p&gt;接续在现代日文中表示可能‧条件、古典日文中表示原因‧理由的助词“-ば”。而在文言文中的假定表现要使用未然形来接续“-ば”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;障子は破ろうと&lt;code class=&quot;language-text&quot;&gt;思えば&lt;/code&gt;すぐ破れる。/要想让拉门破,马上就能破。&lt;/li&gt;
&lt;li&gt;ちりも&lt;code class=&quot;language-text&quot;&gt;積もれば&lt;/code&gt;山となる。/积砂成塔。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;456-命令形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#456-%E5%91%BD%E4%BB%A4%E5%BD%A2&quot; aria-label=&quot;456 命令形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.6 命令形&lt;/h4&gt;
&lt;p&gt;位于句末，表示命令。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;手を&lt;code class=&quot;language-text&quot;&gt;あげろ&lt;/code&gt;!/举起手!&lt;/li&gt;
&lt;li&gt;僕の話を&lt;code class=&quot;language-text&quot;&gt;聞け&lt;/code&gt;！/听我的话！&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;43-动词分类&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E5%8A%A8%E8%AF%8D%E5%88%86%E7%B1%BB&quot; aria-label=&quot;43 动词分类 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 动词分类&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID43000&quot;&gt;&lt;/span&gt;
理解了&lt;code class=&quot;language-text&quot;&gt;活用形&lt;/code&gt;之后，就知道在想要表达某种意思（或某种句式）的时候应该使用哪种活用形。比如说在表述否定的时候，应该使用未然形。接下来就需要知道未然形应该怎么做形变，这时候，就有好几种情况。&lt;/p&gt;
&lt;p&gt;并不是所有的动词都按一个规则进行未然形形变，根据不同的情况，形变的方式各不相同，而这里提到的&lt;code class=&quot;language-text&quot;&gt;不同情况&lt;/code&gt;是有范式的，这个范式，可以归结为动词的分类。&lt;/p&gt;
&lt;p&gt;动词可以分为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;五段动词&lt;/li&gt;
&lt;li&gt;一段动词&lt;/li&gt;
&lt;li&gt;サ变动词&lt;/li&gt;
&lt;li&gt;カ变动词&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接下来介绍如何将一个动词进行分类。知乎上有一篇很不错的方法：&lt;a href=&quot;https://www.zhihu.com/question/21584672/answer/71895818&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不是「る」结尾的动词都是&lt;code class=&quot;language-text&quot;&gt;五段动词&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;編む／選ぶ／歌う／抱く&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;是&lt;code class=&quot;language-text&quot;&gt;「る」&lt;/code&gt;结尾的动词，分以下情形
&lt;ul&gt;
&lt;li&gt;如果是「～する」，即&lt;code class=&quot;language-text&quot;&gt;サ变动词&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;する／参加する／散歩する／説明する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果是「来る（くる）」，即&lt;code class=&quot;language-text&quot;&gt;カ变动词&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;来る&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;如果倒数第二个假名落在「い」段或者「え」段的，即&lt;code class=&quot;language-text&quot;&gt;一段动词&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;「い」段的，称为上一段&lt;/li&gt;
&lt;li&gt;「え」段的，称为下一段&lt;/li&gt;
&lt;li&gt;覚える／抱える／生きる／離れる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;其他的仍然是&lt;code class=&quot;language-text&quot;&gt;五段动词&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;破る／掘る／去る／撮る&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然了还有我们不断在强调的特殊的26个五段动词，它们貌似一段动词符合一段动词的定义，但实为五段动词。这些都需要个别记忆。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | - | - | -&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:--- | :--- | :--- | :--- | :---
嘲（あざけ）る | 焦（あせ）る | 要（い）る | 煎（い）る | 返（かえ）る
帰（かえ）る | 限（かぎ）る | 切（き）る | 覆（くつがえ）る | 蹴（け）る
遮（さえぎ）る | 茂（しげ）る | 湿（しめ）る | 知（し）る | 滑（すべ）る
散（ち）る | 照（て）る | 握（にぎ）る | 练（ね）る | 骂（ののし）る
入（はい）る | 走（はし）る | 减（へ）る | 参（まい）る | 混（ま）じる
涨（みなぎ）る |&lt;/p&gt;
&lt;p&gt;【补充】
有的教材将动词按照词形变化规律分为1类动词、2类动词以及3类动词，其实质与五段动词、一段动词、サ变动词以及カ变动词并没有不同。两种称呼的对应关系是：　&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1类动词	→	五段动词　　
2类动词	→	一段动词　　
3类动词	→	サ变／カ变&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;44-活用的规律&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%A7%84%E5%BE%8B&quot; aria-label=&quot;44 活用的规律 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 活用的规律&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID44000&quot;&gt;&lt;/span&gt;
了解完了活用的分类，以及活用形的应用场景，随后又学习了下动词应该如何分类。接下来就要将两者组合起来了，通过活用形以及动词分类的组合，来学习活用的形变规律。&lt;/p&gt;
&lt;p&gt;这里有两种思路，一种是根据动词分类的方式从五段动词、一段动词等的视角，来看五段动词、一段动词的未然形是怎么变化的、连用形是怎么变化的，等。&lt;/p&gt;
&lt;p&gt;另一种思路是，从活用形的视角，来看未然形、连用形的五段动词、一段动词是怎么变化的。&lt;/p&gt;
&lt;p&gt;这里选择使用第一种，因为首先造句的时候，先确定的是动词，然后根据动词可以知道其分类，然后根据表述的句子能决定到底是什么活用形。所以从动词分类的视角来学习如何变化是最符合实际使用情况的。&lt;/p&gt;
&lt;h4 id=&quot;441-五段动词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#441-%E4%BA%94%E6%AE%B5%E5%8A%A8%E8%AF%8D&quot; aria-label=&quot;441 五段动词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4.1 五段动词&lt;/h4&gt;
&lt;p&gt;五段动词的变化虽然有规则可寻，但因其变化在&lt;code class=&quot;language-text&quot;&gt;あ、い、う、え、お&lt;/code&gt;这五段音上，所以常被认为是最复杂的类型。&lt;/p&gt;
&lt;p&gt;五段动词在变化的时候，会保留语尾最后一个假名的子音，只变化母音。举例来说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;「く」(ku)若在「あ」(a)段上变化，就变成「か」(ka)&lt;/li&gt;
&lt;li&gt;「く」(ku)若在「い」(i)段上变化，就变成「き」(ki)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;依此类推。但如果语尾最后一个假名是没有子音的「う」，若在「あ」(a)段上变化，会加上w音，变成「わ」(wa)，至于其他段就直接变化即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;未然形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;否定时变化规律：转&lt;code class=&quot;language-text&quot;&gt;あ&lt;/code&gt;段假名
推量时变化规律：转&lt;code class=&quot;language-text&quot;&gt;お&lt;/code&gt;段假名&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;く&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;か&lt;/code&gt;・ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不去&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | い&lt;code class=&quot;language-text&quot;&gt;こ&lt;/code&gt;・う | 想要去&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;泳ぐ | およ&lt;code class=&quot;language-text&quot;&gt;ぐ&lt;/code&gt; | → | およ&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;・ない | 不游泳&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | およ&lt;code class=&quot;language-text&quot;&gt;ご&lt;/code&gt;・う | 想要游泳&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;聞く | き&lt;code class=&quot;language-text&quot;&gt;く&lt;/code&gt; | → | き&lt;code class=&quot;language-text&quot;&gt;か&lt;/code&gt;・ない | 不听&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | き&lt;code class=&quot;language-text&quot;&gt;こ&lt;/code&gt;・う | 想要听&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;休む | やす&lt;code class=&quot;language-text&quot;&gt;む&lt;/code&gt; | → | やす&lt;code class=&quot;language-text&quot;&gt;ま&lt;/code&gt;・ない | 不休息&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | やす&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;・う | 想要休息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特例：唯一与上述规律有违的是“ある／有、在”。“ある”的否定形式不是“あら・ない”，而是“ない／没有、不在”。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;连用形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：转&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;段假名&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;く&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;き&lt;/code&gt;・ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;呼ぶ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よ&lt;code class=&quot;language-text&quot;&gt;ぶ&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よ&lt;code class=&quot;language-text&quot;&gt;び&lt;/code&gt;・ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;呼唤&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;终止形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;同动词辞书形（原形）&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;行く&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连体形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;动词辞书形（原形）不转换，后加 ひと、こと、とき 等&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;行くこと&lt;/li&gt;
&lt;li&gt;呼ぶこと&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;假定形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：转&lt;code class=&quot;language-text&quot;&gt;え&lt;/code&gt;段假名&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;く&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;け&lt;/code&gt;・ば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去了就…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;呼ぶ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よ&lt;code class=&quot;language-text&quot;&gt;ぶ&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よ&lt;code class=&quot;language-text&quot;&gt;べ&lt;/code&gt;・ば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;呼唤了就…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;命令形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：转&lt;code class=&quot;language-text&quot;&gt;え&lt;/code&gt;段假名&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;く&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;い&lt;code class=&quot;language-text&quot;&gt;け&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;やる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;や&lt;code class=&quot;language-text&quot;&gt;る&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;や&lt;code class=&quot;language-text&quot;&gt;れ&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;做！&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;442-一段动词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#442-%E4%B8%80%E6%AE%B5%E5%8A%A8%E8%AF%8D&quot; aria-label=&quot;442 一段动词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4.2 一段动词&lt;/h4&gt;
&lt;p&gt;上一段动词和下一段动词的变化最为简单，只要去掉语尾最后的「る」，再加上五段动词公式一变化时需要加的字即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;未然形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;起きる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おきる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おき・ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不起床&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不看&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;食べる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;たべる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;たべ・よう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;吃吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;寝る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ねる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ね・よう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;睡吧&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;连用形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;起きる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おきる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おき・ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;起床&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;看&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;食べる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;たべる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;たべ・ましょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;吃吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;寝る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ねる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ね・ましょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;睡吧&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;终止形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;同动词辞书形（原形）&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;起きる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连体形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;动词辞书形（原形）不转换，后加 ひと、こと、とき 等&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;起きるとき&lt;/li&gt;
&lt;li&gt;食べること&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;假定形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后加&lt;code class=&quot;language-text&quot;&gt;れば&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;起きる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おきる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おき・れば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;起床的话，就…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・れば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;看了的话，就…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;食べる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;たべる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;たべ・れば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;吃了的话，就…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;寝る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ねる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ね・れば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;睡的话，就…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;命令形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后加 ろ(口语)、よ(文书)&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;起きる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おきる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おき・ろ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;起来！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・よ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;看吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;443-サ变动词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#443-%E3%82%B5%E5%8F%98%E5%8A%A8%E8%AF%8D&quot; aria-label=&quot;443 サ变动词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4.3 サ变动词&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;未然形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;词干加“し”，然后：否定加助动词“ない”，推量加助动词“よう”&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;し・ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不做&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうする&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうし・ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不学习&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;し・よう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;做吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうする&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうし・よう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;学习吧&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;连用形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;词干加“し”&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;し・ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;做&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうする&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうし・ましょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;学习吧&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;终止形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;同动词辞书形（原形）&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;勉強する&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连体形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;动词辞书形（原形）不转换，后加 ひと、こと、とき 等&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;するとき&lt;/li&gt;
&lt;li&gt;勉強すること&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;假定形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;词干加&lt;code class=&quot;language-text&quot;&gt;すれば&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;すれば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;做的话，就…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうする&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょう・すれば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;学习了的话，就…&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;命令形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;词干加 しろ(口语)、せよ(文书)&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解释&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しろ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;快做！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょうする&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;べんきょう・しろ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;快学习！&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;444-カ变动词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#444-%E3%82%AB%E5%8F%98%E5%8A%A8%E8%AF%8D&quot; aria-label=&quot;444 カ变动词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4.4 カ变动词&lt;/h4&gt;
&lt;p&gt;因为只有一个&lt;code class=&quot;language-text&quot;&gt;来る（くる）&lt;/code&gt;就直接上例子了&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;未然形&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;くる → こ・ない&lt;/li&gt;
&lt;li&gt;くる → こ・よう&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连用形&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;くる → き・ます&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;终止形&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;くる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连体形&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;くる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;假定形&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;くる → くれば&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;命令形&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;くる → こい&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;446-音便&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#446-%E9%9F%B3%E4%BE%BF&quot; aria-label=&quot;446 音便 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4.6 音便&lt;/h4&gt;
&lt;p&gt;只有非さ(sa)行(语尾最后一个假名为す)的&lt;code class=&quot;language-text&quot;&gt;五段动词&lt;/code&gt;才会有音便，当这类的五段动词连用形后接过去式助动词&lt;code class=&quot;language-text&quot;&gt;た&lt;/code&gt;或是接续助词&lt;code class=&quot;language-text&quot;&gt;て、ては、たも、たん、たって&lt;/code&gt;时，习惯上会自然省略连用形带i母音的假名，而形成促音便、拨音便或是イ(i)音便。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;促音便&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;发生条件及变化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原形动词语尾最后一个假名是&lt;code class=&quot;language-text&quot;&gt;う&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;つ&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;る&lt;/code&gt;时：使う、待つ、乗る&lt;/li&gt;
&lt;li&gt;只限&lt;code class=&quot;language-text&quot;&gt;连用形&lt;/code&gt;：う → い、つ → ち、る → り&lt;/li&gt;
&lt;li&gt;后续为&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;た&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;活用会被转成&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;：い → っ、ち → っ、り → っ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;连用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;接续&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用/音便&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;使う&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;つかう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;つかい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;つか&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;・ます&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | つかい | て | つか&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;・て&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;待つ | まつ | → | まち | ます | ま&lt;code class=&quot;language-text&quot;&gt;ち&lt;/code&gt;・ます&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | まち | た | ま&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;・た&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;乗る | のる | → | のり | ます | の&lt;code class=&quot;language-text&quot;&gt;り&lt;/code&gt;・ます&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | のり | て | の&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;・て&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;拨音便&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;发生条件及变化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原形动词语尾最后一个假名是&lt;code class=&quot;language-text&quot;&gt;ぬ&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;ぶ&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;む&lt;/code&gt;时：死ぬ、呼ぶ、飲む&lt;/li&gt;
&lt;li&gt;只限&lt;code class=&quot;language-text&quot;&gt;连用形&lt;/code&gt;：ぬ → に、ぶ → び、む → み&lt;/li&gt;
&lt;li&gt;后续为&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;た&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;活用会被转成&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;：に → ん、び → ん、み → ん&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ん后面&lt;/code&gt;的假名会&lt;code class=&quot;language-text&quot;&gt;浊化&lt;/code&gt;：て → で、た → だ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;连用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;接续&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用/音便&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;死ぬ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しぬ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しに&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;し&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;・ます&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | しに | て | し&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;呼ぶ | よぶ | → | よび | ます | よ&lt;code class=&quot;language-text&quot;&gt;び&lt;/code&gt;・ます&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | よび | た | よ&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;だ&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;飲む | のむ | → | のみ | ます | の&lt;code class=&quot;language-text&quot;&gt;み&lt;/code&gt;・ます&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | のみ | て | の&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;イ音便&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;发生条件及变化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原形动词语尾最后一个假名是&lt;code class=&quot;language-text&quot;&gt;く&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;ぐ&lt;/code&gt;时：書く、聞く&lt;/li&gt;
&lt;li&gt;只限&lt;code class=&quot;language-text&quot;&gt;连用形&lt;/code&gt;：く → き、ぐ → ぎ&lt;/li&gt;
&lt;li&gt;后续为&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;た&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;活用会被转成&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;：き → い、ぎ → い&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ぎ&lt;/code&gt;的情况&lt;code class=&quot;language-text&quot;&gt;い后面&lt;/code&gt;的假名会&lt;code class=&quot;language-text&quot;&gt;浊化&lt;/code&gt;：て → で、た → だ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;单词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;-&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;连用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;接续&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用/音便&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;書く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;かく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;→&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;かき&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;か&lt;code class=&quot;language-text&quot;&gt;き&lt;/code&gt;・ます&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | かき | て | か&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;・て&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;聞く | きく | → | きき | ます | き&lt;code class=&quot;language-text&quot;&gt;き&lt;/code&gt;・ます&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | きき | た | き&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;・た&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;嗅ぐ | かぐ | → | かぎ | ます | か&lt;code class=&quot;language-text&quot;&gt;ぎ&lt;/code&gt;・ます&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | → | かぎ | て | か&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;例外&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;行く（いく）&lt;/code&gt;在后接&lt;code class=&quot;language-text&quot;&gt;て、た&lt;/code&gt;时，不发生イ音便，而是发生促音便。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;行く+て → 行って&lt;/li&gt;
&lt;li&gt;行く+た → 行った&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;45-活用的范式&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#45-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%8C%83%E5%BC%8F&quot; aria-label=&quot;45 活用的范式 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5 活用的范式&lt;/h3&gt;
&lt;p&gt;日本的动词在不同时式(现在、过去、意志邀约、无意志未来(推测过去、推测未来))、语态(常体、敬体)、语气(肯定、否定)，可有5*2*2=20种组合，但意志邀约并没有否定语气，所以只剩下18种组合，称为「动词十八式」。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语态&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;辞书形（原形）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;br&gt;去&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ます&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行きます&lt;br&gt;要去&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（否定）+ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行かない&lt;br&gt;不去&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ません&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行きません&lt;br&gt;不要去&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+过去式助动词た&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行った&lt;br&gt;去了&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ました&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行きました&lt;br&gt;去过了&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（否定）+なっかた（ない去い加かった）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行かなかった&lt;br&gt;没有去&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ませんでした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行きませんでした&lt;br&gt;没有去过&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;意志邀约&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（意志）+う&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行こう&lt;br&gt;去吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;意志邀约&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ましょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行きましょう&lt;br&gt;一起去吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;辞书形+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行くだろう&lt;br&gt;要去吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;辞书形+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行くでしょう&lt;br&gt;要去吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（否定）+ない+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行かないだろう&lt;br&gt;不去吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（否定）+ない+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行かないでしょう&lt;br&gt;不要去吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+过去式助动词た+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行っただろう&lt;br&gt;去过了吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+过去式助动词た+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行ったでしょう&lt;br&gt;有去过了吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（否定）+なかった（ない去い加かった）+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行かなかっただろう&lt;br&gt;没去过吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;无意志未来&lt;br&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（否定）+なかった（ない去い加かった）+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行かなかったでしょう&lt;br&gt;没有去过吧！&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;5-形容词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E5%BD%A2%E5%AE%B9%E8%AF%8D&quot; aria-label=&quot;5 形容词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 形容词&lt;/h2&gt;
&lt;p&gt;&lt;span id=&quot;ID50000&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;51-活用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-%E6%B4%BB%E7%94%A8&quot; aria-label=&quot;51 活用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 活用&lt;/h3&gt;
&lt;p&gt;一个形容词必定由い结尾，这即是其原形（终止形）。&lt;/p&gt;
&lt;h3 id=&quot;52-活用的规律&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%A7%84%E5%BE%8B&quot; aria-label=&quot;52 活用的规律 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 活用的规律&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;未然形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：去い + かろ + 推量助动词う / かった（过去式）&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;京都の桜は美し&lt;code class=&quot;language-text&quot;&gt;かろう&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;昨日はとっても楽し&lt;code class=&quot;language-text&quot;&gt;かった&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连用形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：去い + く +&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;名词/副词&lt;/li&gt;
&lt;li&gt;て（中止接续）&lt;/li&gt;
&lt;li&gt;ない（否定）&lt;/li&gt;
&lt;li&gt;なる（表变化）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;美味し&lt;code class=&quot;language-text&quot;&gt;くて&lt;/code&gt;たまらない。&lt;/li&gt;
&lt;li&gt;彼女は全然美し&lt;code class=&quot;language-text&quot;&gt;くない&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;だんだん暑&lt;code class=&quot;language-text&quot;&gt;くなる&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;终止形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;原形，无变化&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;美味しい&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连体形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：无变化，原形 + ひと、こと、とき、ところ、もの或其他名词&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;美味しいご飯&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;假定形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：去い + ければ + ···&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;楽し&lt;code class=&quot;language-text&quot;&gt;ければ&lt;/code&gt;···&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;53-活用的范式&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#53-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%8C%83%E5%BC%8F&quot; aria-label=&quot;53 活用的范式 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3 活用的范式&lt;/h3&gt;
&lt;p&gt;日本的形容词在不同时式(现在、过去、推测过去、推测未来)、语态(常体、敬体)、语气(肯定、否定)，可有4*2*2=16种组合，称为「形容词十六式」。&lt;/p&gt;
&lt;p&gt;以「美味しい」(おいしい)举例，变化方式如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语态&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;翻译&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;好吃的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）+です&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しいです&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不好吃的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くない+です&lt;br&gt;连用形+く+ありません&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくない&lt;br&gt;美味しくありません&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不美味的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+かった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;好吃的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+かった+です&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しかったです&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不好吃的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くなかった+です&lt;br&gt;连用形+く+ありません+でした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくなっかたです&lt;br&gt;美味しくありませんでした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不美味的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しいだろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;好吃吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しいでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くない+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくないだろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不好吃吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くない+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくないでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不美味吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+かった+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しかっただろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;好吃吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+かった+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しかったでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くなかった+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくなかっただろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不好吃吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+くなかった+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しくなかったでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不美味吧&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;6-形容动词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-%E5%BD%A2%E5%AE%B9%E5%8A%A8%E8%AF%8D&quot; aria-label=&quot;6 形容动词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. 形容动词&lt;/h2&gt;
&lt;p&gt;&lt;span id=&quot;ID60000&quot;&gt;&lt;/span&gt;
形容动词和形容词的差别其实不用想太多，只要把它当作是活用方式不同的形容词即可。&lt;/p&gt;
&lt;h3 id=&quot;61-活用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-%E6%B4%BB%E7%94%A8&quot; aria-label=&quot;61 活用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 活用&lt;/h3&gt;
&lt;p&gt;一个形容动词必定由だ(da)结尾，这即是其原形（终止形）。&lt;/p&gt;
&lt;h3 id=&quot;62-活用的规律&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%A7%84%E5%BE%8B&quot; aria-label=&quot;62 活用的规律 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 活用的规律&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;未然形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：原形 + ろう(推测)&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;綺麗だ&lt;code class=&quot;language-text&quot;&gt;ろう&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连用形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：去だ +&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;だった(过去)&lt;/li&gt;
&lt;li&gt;ではない(否定)&lt;/li&gt;
&lt;li&gt;に(副词)&lt;/li&gt;
&lt;li&gt;に成る(になる, 表变化)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;綺麗&lt;code class=&quot;language-text&quot;&gt;ではない&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;终止形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;原形，无变化&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;綺麗だ。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连体形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：去だ + な + ひと、こと、とき、ところ、もの(人、事、时、地、物)或其他名词&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;綺麗な&lt;code class=&quot;language-text&quot;&gt;もの&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;假定形&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;变化规律：去だ + なら + ···&lt;/p&gt;
&lt;p&gt;例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;綺麗&lt;code class=&quot;language-text&quot;&gt;なら&lt;/code&gt;···&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;63-活用的范式&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#63-%E6%B4%BB%E7%94%A8%E7%9A%84%E8%8C%83%E5%BC%8F&quot; aria-label=&quot;63 活用的范式 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3 活用的范式&lt;/h3&gt;
&lt;p&gt;日本的形容动词在不同时式(现在、过去、推测过去、推测未来)、语态(常体、敬体)、语气(肯定、否定)，可有4*2*2=16种组合，称为「形容动词十六式」。&lt;/p&gt;
&lt;p&gt;以「静かだ」(しずかだ)举例，变化方式如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语态&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;翻译&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かだ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）去だ+です&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かです&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ではない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;现在式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+では+ありません&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではありません&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+だった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かだった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）去だ+でした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かでした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ではなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去式&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+では+ありません+でした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではありませんでした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静的&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形（即原形+ろう）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かだろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形（原形）去だ+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ではない+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではないだろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测未来&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ではない+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではないでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+だった+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かだっただろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+だった+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かだったでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;常体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ではなっかた+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではなっかただろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;推测过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;敬体&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ではなっかた+でしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;静かではなっかたでしょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不安静吧&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;7-动词的体时态&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-%E5%8A%A8%E8%AF%8D%E7%9A%84%E4%BD%93%E6%97%B6%E6%80%81&quot; aria-label=&quot;7 动词的体时态 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. 动词的体、时、态&lt;/h2&gt;
&lt;h3 id=&quot;71-理解动词的体时态&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#71-%E7%90%86%E8%A7%A3%E5%8A%A8%E8%AF%8D%E7%9A%84%E4%BD%93%E6%97%B6%E6%80%81&quot; aria-label=&quot;71 理解动词的体时态 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.1 理解动词的体、时、态&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID71000&quot;&gt;&lt;/span&gt;
在英语的学习中，都会教：一般现在时、一般过去时、现在进行时、过去进行时、现在完成时、过去完成时等，被动态，等，这种被称为时态。在进行表达的时候，需要根据实际的意思进行时态的选用，才不会表达出错误的意思。英语在这方面是比较简单的，每一个时态都有固定的范式：现在进行时&lt;code class=&quot;language-text&quot;&gt;ing&lt;/code&gt;，被动态&lt;code class=&quot;language-text&quot;&gt;ed&lt;/code&gt;，等。&lt;/p&gt;
&lt;p&gt;日语中也有类似的需求和语法规则，但在这方面，日语要复杂得多得多，日语分为三重概念：体、时、态，而且每个概念里都有诸多细节，并不能像英语一样简单罗列成几个范式。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;日语中的体、时、态&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;体：动词所表现的动作、作用有的可以是一个过程，即存在着动作作用的开始、进行和结束等阶段。动词的“体（アスペクト）”就是记述动作、作用等处于何种进行情况的语法范畴。
&lt;ul&gt;
&lt;li&gt;持续体：持续体表示动作、行为在某一时间内持续进行或正在进行、反复进行。&lt;/li&gt;
&lt;li&gt;存续体：存续体表示动作、行为所造成的状态、所形成的結果还在保留着。&lt;/li&gt;
&lt;li&gt;完成体：完成体指的是动作、行为的完成、结束。&lt;/li&gt;
&lt;li&gt;准备体：准备体表示该动作是为下一步做准备而做的。&lt;/li&gt;
&lt;li&gt;即将体：即将体表示动作、行为、作用等就要发生。&lt;/li&gt;
&lt;li&gt;起始体：起始体表示动作、行为、作用的开始。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;时：时（テンス）是一个语法范畴，指通过一定的语法形式表示动作、作用、状态的发生时间与某一基准时间（通常是说话的时间）之间的关系。
&lt;ul&gt;
&lt;li&gt;非过去时：非过去时由动词（包括体的补助动词、构成态的助动词以及敬语助动词ます）的终止形直接构成。&lt;/li&gt;
&lt;li&gt;过去时：过去时由“动词连用形+た”构成。这里说的动词，也包括补助动词及动词型活用的助动词。&lt;/li&gt;
&lt;li&gt;分句中的时：参考&lt;code class=&quot;language-text&quot;&gt;8.5&lt;/code&gt;的整理。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;态：基于着眼点的不同，描述同样一件事情时，既可以从动作的施事者出发，也可以从动作的受事者出发，还可以从指使者出发，如此等等。由于动词所指动作与主语的关系所形成的谓语动词的形态变化，叫作动词的“态（ヴォイス）”。
&lt;ul&gt;
&lt;li&gt;被动态：当描述某一动作、行为时，不是以施事者为主角，而是以承受者为主角进行描述，该动词所表现的形态，就是被动态。&lt;/li&gt;
&lt;li&gt;使动态：在描述某一动作、行为时，不是以施事者为主角，而是以指使者、容许者或者促成者为主角描迷，该动词所表现的形态就是使动态。&lt;/li&gt;
&lt;li&gt;可能态：当叙述焦点不在动作本身，而转移到实现动作的能力或可能性时，动作所发生的形态变化，称为可能态。&lt;/li&gt;
&lt;li&gt;自然发生态：描述的焦点在于动作行为是自然而然地发生、自然而然地产生某种结果时，动词的形态变化，就是自然发生态，可简称“自发态”。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;72-体时态详解&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#72-%E4%BD%93%E6%97%B6%E6%80%81%E8%AF%A6%E8%A7%A3&quot; aria-label=&quot;72 体时态详解 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2 体时态详解&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID72000&quot;&gt;&lt;/span&gt;
因为学习语言的目的是为了使用，所以将可以复合组合的体时态拆开一个个单独讲解和理解其实并没有意义，重要的是如何将表达一个个意思的一组组体时态的组合理解并学会，这样才能拿来实际运用。这也是为什么你看出口仁老师的视频教程有N5语法一览这样的视频集合，里面每一个视频每一课其实就是一个体时态组合起来的表达运用，学会了就可以直接使用；这也是为什么顾明耀的语法书学了之后你不能直接拿来用的原因，因为那本书把所有的概念都拆散了拿来详细分析，只有各部分的细节，没有组合运用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;补助动词速查&lt;/strong&gt; &lt;span id=&quot;ID72001&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;下述语法涉及到了大量补助动词，且部分补助动词有一词多用的特点，导致语法点散落在多个体时态章节中，因此将其统一整理成表格：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;补助动词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语法点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ている&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72020&quot;&gt;持续体&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72030&quot;&gt;存续体&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72032&quot;&gt;ている和てある的区别&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72033&quot;&gt;瞬间动词+た&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72035&quot;&gt;表经历、记录&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72036&quot;&gt;形容性动词&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72037&quot;&gt;瞬间动词+ている的否定形式&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;てくる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72021&quot;&gt;持续体、空间由远及近、起始体、状态变化、显现过程&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ていく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72022&quot;&gt;持续体、空间由近及远、状态变化、消失过程&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;てある&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72031&quot;&gt;存续体&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72032&quot;&gt;ている和てある的区别&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72034&quot;&gt;ておく和てある的区别&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;てしまう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72040&quot;&gt;完成态、消极态度、情不自禁、约音用法&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;ておく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72050&quot;&gt;将来打算、放任态度、约音用法&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72034&quot;&gt;ておく和てある的区别、事先准备&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;れる/られる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72060&quot;&gt;被动态&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72080&quot;&gt;可能态：能力、可能性、许可&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72090&quot;&gt;自然发生态&lt;/a&gt;&lt;br&gt;&lt;a href=&quot;#ID72091&quot;&gt;表尊敬&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;せる/させる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID72070&quot;&gt;使动态：命令、放任&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;721-一般时态&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#721-%E4%B8%80%E8%88%AC%E6%97%B6%E6%80%81&quot; aria-label=&quot;721 一般时态 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.1 一般时态&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表示一般现在或一般过去的动作和行为。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ます&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;常体&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;敬体&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;辞书形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+た&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+なっかた&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4 id=&quot;722-进行时态持续体&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#722-%E8%BF%9B%E8%A1%8C%E6%97%B6%E6%80%81%E6%8C%81%E7%BB%AD%E4%BD%93&quot; aria-label=&quot;722 进行时态持续体 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.2 进行时态（持续体）&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt; &lt;span id=&quot;ID72020&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;表示持续进行中的或反复进行的动作和行为。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ている：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/basic/251-n5-37&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N5文法37【表現篇】「ている／てある」&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;てくる：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/elementary/281-n4-17&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N4文法17「てくる」補助動詞&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;ていく：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/elementary/280-n4-16&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N4文法16「ていく」補助動詞&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;常体&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;敬体&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ている&lt;br&gt;连用形+てくる&lt;br&gt;连用形+ていく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ています&lt;br&gt;连用形+てきます&lt;br&gt;连用形+ていきます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ていない&lt;br&gt;连用形+てこない&lt;br&gt;连用形+ていかない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ていません&lt;br&gt;连用形+てきません&lt;br&gt;连用形+ていきません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ていた&lt;br&gt;连用形+てきた&lt;br&gt;连用形+ていった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ていました&lt;br&gt;连用形+てきました&lt;br&gt;连用形+ていきました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ていなかった&lt;br&gt;连用形+てこなかった&lt;br&gt;连用形+ていかなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;继续动词&lt;/code&gt;连用形+ていませんでした&lt;br&gt;连用形+てきませんでした&lt;br&gt;连用形+ていきませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;关于时态&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;用多了就会发现，日语里ている等持续体的用法，和英语中的进行时还不能完全对等。日语中的持续体，更多的是表示动作的持续，可以理解为，什么时候用持续体什么时候用存续体，更多取决于执行的动词（动作）是继续动词（持续性动作）还是瞬间动词（瞬间动作），而并非取决于语义理解上的&lt;code class=&quot;language-text&quot;&gt;正在（进行时）&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;已经（完成时）&lt;/code&gt;。进行时只能说是持续体可能表达的其中一种情况。&lt;/p&gt;
&lt;p&gt;举个例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;それは我々もずっと前から懸念&lt;code class=&quot;language-text&quot;&gt;していました&lt;/code&gt;。/这件事情我们之前也一直很担心。&lt;/li&gt;
&lt;li&gt;可以看下两种翻译的差别：之前一直很担心/之前正在担心，这里显然是前者&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ている&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ている其本身转&lt;code class=&quot;language-text&quot;&gt;て形&lt;/code&gt;的时候，会变成&lt;code class=&quot;language-text&quot;&gt;ていて&lt;/code&gt;，在口语中有时会转为&lt;code class=&quot;language-text&quot;&gt;てて&lt;/code&gt;，方便发音：
&lt;ul&gt;
&lt;li&gt;彼らを見張っ&lt;code class=&quot;language-text&quot;&gt;ていて&lt;/code&gt;欲しい。&lt;/li&gt;
&lt;li&gt;彼らを見張っ&lt;code class=&quot;language-text&quot;&gt;てて&lt;/code&gt;欲しい。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;てくる&lt;/strong&gt; &lt;span id=&quot;ID72021&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;てくる&lt;/code&gt;除了进行时态之外，还有多种语法意义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;时间由过去向现在发展，同时动作持续进行或重复进行；这是当前章节所描述的&lt;code class=&quot;language-text&quot;&gt;进行时态&lt;/code&gt;，多用于过去时
&lt;ul&gt;
&lt;li&gt;三時から、雨が&lt;code class=&quot;language-text&quot;&gt;降ってきました&lt;/code&gt;。/3点开始一直都在下雨。&lt;/li&gt;
&lt;li&gt;この事件をずっと&lt;code class=&quot;language-text&quot;&gt;調べてきた&lt;/code&gt;のです。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;空间由远及近
&lt;ul&gt;
&lt;li&gt;子供が&lt;code class=&quot;language-text&quot;&gt;走ってきました&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;体时态中，体的&lt;code class=&quot;language-text&quot;&gt;起始体&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;雨が&lt;code class=&quot;language-text&quot;&gt;降ってきた&lt;/code&gt;。/（刚刚）开始下起雨来。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示状态变化、显现过程
&lt;ul&gt;
&lt;li&gt;だんだん暑く&lt;code class=&quot;language-text&quot;&gt;なってきました&lt;/code&gt;。/（从前一阵开始）慢慢变热了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ていく&lt;/strong&gt; &lt;span id=&quot;ID72022&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ていく&lt;/code&gt;除了进行时态之外，还有多种语法意义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;时间由现在向将来发展，同时动作持续进行或重复进行；这是当前章节所描述的&lt;code class=&quot;language-text&quot;&gt;进行时态&lt;/code&gt;，多用于非过去时
&lt;ul&gt;
&lt;li&gt;これからも&lt;code class=&quot;language-text&quot;&gt;頑張っていきましょう&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;二人で&lt;code class=&quot;language-text&quot;&gt;生きていきます&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;空间由近及远
&lt;ul&gt;
&lt;li&gt;バスが&lt;code class=&quot;language-text&quot;&gt;やっていきました&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示状态变化、消失过程
&lt;ul&gt;
&lt;li&gt;だんだん暑く&lt;code class=&quot;language-text&quot;&gt;なっていきます&lt;/code&gt;。/（最近开始）慢慢变热了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;723-行为结果状态存续体-完成时态&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#723-%E8%A1%8C%E4%B8%BA%E7%BB%93%E6%9E%9C%E7%8A%B6%E6%80%81%E5%AD%98%E7%BB%AD%E4%BD%93-%E5%AE%8C%E6%88%90%E6%97%B6%E6%80%81&quot; aria-label=&quot;723 行为结果状态存续体 完成时态 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.3 行为结果、状态（存续体）/ 完成时态△&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表示动作、行为所造成的状态、所形成的結果还在保留着。同时，ている也可以表示经历、记录。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ている：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/basic/251-n5-37&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N5文法37【表現篇】「ている／てある」&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;てある：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/basic/251-n5-37&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N5文法37【表現篇】「ている／てある」&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;常体&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;敬体&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ている&lt;br&gt;连用形+てある&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ています&lt;br&gt;连用形+てあります&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ていない&lt;br&gt;てない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ていません&lt;br&gt;连用形+てありません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ていた&lt;br&gt;连用形+てあった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ていました&lt;br&gt;连用形+てありました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ていなかった&lt;br&gt;连用形+てなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;连用形+ていませんでした&lt;br&gt;连用形+てありませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;存续体是日语中很特殊的用法（其他语言的时态中，并没有这样非常针对性的构成），表示动作行为所造成的状态、结果仍旧存在着。这个语法点在理解上的主要问题是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;存续体中的重要组成部分补助动词&lt;code class=&quot;language-text&quot;&gt;ている&lt;/code&gt;在&lt;code class=&quot;language-text&quot;&gt;进行时态&lt;/code&gt;中也存在，这就导致了实际运用时的理解困难：
&lt;ul&gt;
&lt;li&gt;存续体：井上先生はいま中国に&lt;code class=&quot;language-text&quot;&gt;行っている&lt;/code&gt;。/井上老师现在到中国去了。（不是过去这个行为，而是已经在那边的状态）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;存续体的&lt;code class=&quot;language-text&quot;&gt;状态、结果&lt;/code&gt;的含义在某些场景和句意下很容易和&lt;code class=&quot;language-text&quot;&gt;完成体&lt;/code&gt;的翻译以及&lt;code class=&quot;language-text&quot;&gt;准备体的ておく&lt;/code&gt;混淆：
&lt;ul&gt;
&lt;li&gt;存续体：このご飯はもう&lt;code class=&quot;language-text&quot;&gt;腐っている&lt;/code&gt;。/这米饭已经馊了。&lt;/li&gt;
&lt;li&gt;存续体：教授には、もう受賞のお祝いの電報を&lt;code class=&quot;language-text&quot;&gt;打ってある&lt;/code&gt;。/已经给教授发去了获奖的祝贺电报。&lt;/li&gt;
&lt;li&gt;存续体：新しいバットを&lt;code class=&quot;language-text&quot;&gt;注文してある&lt;/code&gt;。/已经定好了新球棒。&lt;/li&gt;
&lt;li&gt;准备体：自転車はもう&lt;code class=&quot;language-text&quot;&gt;買っておい&lt;/code&gt;た。/自行车已经买好了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面详细讲解下语法点和区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;存续体：
&lt;ul&gt;
&lt;li&gt;ている：&lt;span id=&quot;ID72030&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;存续体的ている必须和&lt;code class=&quot;language-text&quot;&gt;瞬间动词&lt;/code&gt;组合使用，而进行时态的ている（持续体）则是和继续动词组合使用&lt;/li&gt;
&lt;li&gt;正因为是瞬间动词，所以虽然中文翻译都是&lt;code class=&quot;language-text&quot;&gt;已经...&lt;/code&gt;但和完成体不同，着重点在于动作结束后留下的结果和状态，而不是动作本身
&lt;ul&gt;
&lt;li&gt;桜の木が&lt;code class=&quot;language-text&quot;&gt;枯れている&lt;/code&gt;。/櫻树已经枯死了。&lt;/li&gt;
&lt;li&gt;このご飯はもう&lt;code class=&quot;language-text&quot;&gt;腐っている&lt;/code&gt;。/这米饭已经馊了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;てある：&lt;span id=&quot;ID72031&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;てある必须搭配&lt;code class=&quot;language-text&quot;&gt;他动词&lt;/code&gt;使用，强调的是人为的结果&lt;/li&gt;
&lt;li&gt;同样的，翻译虽然是&lt;code class=&quot;language-text&quot;&gt;已经...&lt;/code&gt;，但强调的是结果和状态&lt;/li&gt;
&lt;li&gt;自动词
&lt;ul&gt;
&lt;li&gt;並ぶ+&lt;code class=&quot;language-text&quot;&gt;ている&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;お皿が並んでいる。&lt;/li&gt;
&lt;li&gt;盘子已经排好了。（强调盘子排好的状态）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;他动词
&lt;ul&gt;
&lt;li&gt;並べる+&lt;code class=&quot;language-text&quot;&gt;てある&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;お皿が並べてある。&lt;/li&gt;
&lt;li&gt;盘子已经（被某人）排好了。（强调某人排好了盘子）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ている和てある的区别：&lt;span id=&quot;ID72032&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;ている着重于结果和状态
&lt;ul&gt;
&lt;li&gt;ドアが開いている。&lt;/li&gt;
&lt;li&gt;门开着。（强调状态）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;てある着重于人为的结果
&lt;ul&gt;
&lt;li&gt;ドアが開けてある。&lt;/li&gt;
&lt;li&gt;（我把）门（打开）开着。（人为结果）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;助词使用上
&lt;ul&gt;
&lt;li&gt;持续体：对象+を+他动词+ている：お皿&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;並べている。(正在排盘子)&lt;/li&gt;
&lt;li&gt;存续体：对象+が+他动词+てある：お皿&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;並べてある。(某人排好盘子)&lt;/li&gt;
&lt;li&gt;存续体：对象+が+自动词+ている：お皿&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;並んでいる。(盘子排好着)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ている：在作定语从句中的谓语时，可以变化为&lt;code class=&quot;language-text&quot;&gt;瞬间动词+た&lt;/code&gt;的形式：&lt;span id=&quot;ID72033&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;メガネを&lt;code class=&quot;language-text&quot;&gt;かけている&lt;/code&gt;人は王さんだ。&lt;/li&gt;
&lt;li&gt;メガネを&lt;code class=&quot;language-text&quot;&gt;かけた&lt;/code&gt;人は王さんだ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;准备体：&lt;span id=&quot;ID72034&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ておく&lt;/code&gt;（准备体）和&lt;code class=&quot;language-text&quot;&gt;てある&lt;/code&gt;（存续体）在&lt;code class=&quot;language-text&quot;&gt;为了某事做好准备...（已经...）&lt;/code&gt;这个用法上的语义是一致的，但有区别
&lt;ul&gt;
&lt;li&gt;ておく必须搭配&lt;code class=&quot;language-text&quot;&gt;意志动词&lt;/code&gt;使用，可以表达请求、命令、愿望、劝诱等意思&lt;/li&gt;
&lt;li&gt;ておく着眼点在于人为结果，行为的人；而てある则只关注结果和状态&lt;/li&gt;
&lt;li&gt;ておく更多地含有事先准备的意思，因此多用过去时，而てある则无所谓时的问题，过去非过去都可
&lt;ul&gt;
&lt;li&gt;自転車はもう&lt;code class=&quot;language-text&quot;&gt;買っておい&lt;/code&gt;た。/自行车已经买好了。&lt;/li&gt;
&lt;li&gt;新しいバットを&lt;code class=&quot;language-text&quot;&gt;注文してある&lt;/code&gt;。/已经定好了新球棒。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ている&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;此外，关于&lt;code class=&quot;language-text&quot;&gt;ている&lt;/code&gt;还有几点补充：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;持续体的ている还可以表示&lt;code class=&quot;language-text&quot;&gt;经历、记录&lt;/code&gt; &lt;span id=&quot;ID72035&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;这个用法和表示行为的结果和状态类似，但实际上意思还是有点不同的&lt;/li&gt;
&lt;li&gt;这个不同更多的不是从语法上，而是从释义上来理解（也就是说不需要想太多）
&lt;ul&gt;
&lt;li&gt;存续体表状态：井上先生はいま中国に&lt;code class=&quot;language-text&quot;&gt;行っている&lt;/code&gt;。/井上老师现在到中国去了。&lt;/li&gt;
&lt;li&gt;存续体表经历：井上先生は中国に何回も&lt;code class=&quot;language-text&quot;&gt;行っている&lt;/code&gt;。/井上老师去过好多次中国。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;形容性动词 &lt;span id=&quot;ID72036&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;形容性动词+ている&lt;/code&gt;可以表示动作的性质，这种用法更类似于形容词&lt;/li&gt;
&lt;li&gt;因为这种用法仍旧还是ている，所以要和&lt;code class=&quot;language-text&quot;&gt;继续动词的持续体&lt;/code&gt;分清楚
&lt;ul&gt;
&lt;li&gt;あの人は&lt;code class=&quot;language-text&quot;&gt;太っています&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;彼の作品は&lt;code class=&quot;language-text&quot;&gt;優れています&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;瞬间动词+ている的否定形式 &lt;span id=&quot;ID72037&quot;&gt;&lt;/span&gt;
&lt;ul&gt;
&lt;li&gt;虽然在上面的构成表（一般规律）中有写否定形式是
&lt;ul&gt;
&lt;li&gt;非过去：常体：连用形+ていない；敬体：连用形+ていません&lt;/li&gt;
&lt;li&gt;过去时：常体：连用形+ていなかった；敬体：连用形+ていませんでした&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;但实际使用的时候则是去掉ている的&lt;code class=&quot;language-text&quot;&gt;一般时态的否定形式&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;构成：
&lt;ul&gt;
&lt;li&gt;非过去：常体：未然形+ない；敬体：连用形+ません&lt;/li&gt;
&lt;li&gt;过去时：常体：未然形+なかった；敬体：连用形+ませんでした&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;举个例子&lt;code class=&quot;language-text&quot;&gt;知る&lt;/code&gt;，一般对话都是：
&lt;ul&gt;
&lt;li&gt;知っていますか。/你知道吗？&lt;/li&gt;
&lt;li&gt;知らない。/知りません。/我不知道。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;724-完成时态完成体&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#724-%E5%AE%8C%E6%88%90%E6%97%B6%E6%80%81%E5%AE%8C%E6%88%90%E4%BD%93&quot; aria-label=&quot;724 完成时态完成体 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.4 完成时态（完成体）&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表示动作、行为的完成、结束。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;てしまう：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/elementary/283-n4-19&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N4文法19「てしまう」補助動詞&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;常体&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;敬体&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまいます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまわない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまいません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまいました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまわなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+てしまいませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;てしまう&lt;/strong&gt; &lt;span id=&quot;ID72040&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完成时态：与存续体的区别（更完整的细节可以查看章节&lt;a href=&quot;#ID72030&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;7.2.3&lt;/code&gt;&lt;/a&gt;）
&lt;ul&gt;
&lt;li&gt;完成体&lt;code class=&quot;language-text&quot;&gt;てしまう&lt;/code&gt;着重的是行为的完成，动作做完这件事
&lt;ul&gt;
&lt;li&gt;果物を全部&lt;code class=&quot;language-text&quot;&gt;食べてしまった&lt;/code&gt;。/把水果全吃完了。&lt;/li&gt;
&lt;li&gt;句子的重点在吃完这件事，而不是吃完之后的状态（空盘子、还要再去弄点等）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;存续体&lt;code class=&quot;language-text&quot;&gt;ている、てある&lt;/code&gt;注重的是行为完成后造成的结果或状态，之前在存续体的篇幅里也说过了，存续体的句子翻译过来个个都是&lt;code class=&quot;language-text&quot;&gt;已经...&lt;/code&gt;，从这点上来看，存续体其实都是完成时态，但着重点在于结果和状态而已
&lt;ul&gt;
&lt;li&gt;お皿が&lt;code class=&quot;language-text&quot;&gt;並んでいる&lt;/code&gt;。/盘子已经排好了。&lt;/li&gt;
&lt;li&gt;句子的重点在排好这个状态，而不是排的动作的完成（后面可以很自然接吃饭之类的后续，因为吃饭的准备动作做完了）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;完成时之外的其他用法
&lt;ul&gt;
&lt;li&gt;表示遗憾、惋惜、悔恨等消极态度
&lt;ul&gt;
&lt;li&gt;電車の中にスマホを&lt;code class=&quot;language-text&quot;&gt;忘れてきてしまった&lt;/code&gt;。（后悔）&lt;/li&gt;
&lt;li&gt;亀が死んでしまいました。（遗憾）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;情不自禁的行为
&lt;ul&gt;
&lt;li&gt;笑い事ではないのに&lt;code class=&quot;language-text&quot;&gt;笑ってしまった&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;思わず&lt;code class=&quot;language-text&quot;&gt;泣いてしまった&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;てしまう可以约音成&lt;code class=&quot;language-text&quot;&gt;ちゃう&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;ちまう&lt;/code&gt;的形式
&lt;ul&gt;
&lt;li&gt;あなたを待っている間に手紙を&lt;code class=&quot;language-text&quot;&gt;書いちゃった&lt;/code&gt;。/等你的时候,写完了信。&lt;/li&gt;
&lt;li&gt;きれいに財産を&lt;code class=&quot;language-text&quot;&gt;使っちゃう&lt;/code&gt;。/把财产花个一干二净。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;725-完成准备准备体-完成时态--将来打算&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#725-%E5%AE%8C%E6%88%90%E5%87%86%E5%A4%87%E5%87%86%E5%A4%87%E4%BD%93-%E5%AE%8C%E6%88%90%E6%97%B6%E6%80%81--%E5%B0%86%E6%9D%A5%E6%89%93%E7%AE%97&quot; aria-label=&quot;725 完成准备准备体 完成时态  将来打算 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.5 完成准备（准备体）/ 完成时态△ / 将来打算&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表示后续动作的准备工作的完成（过去时），或表示将来的打算（非过去时）。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ておく：&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/elementary/284-n4-20&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N4文法20「ておく」補助動詞&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;常体&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;敬体&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ておく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ておきます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ておかない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ておきません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ておいた&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ておきました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+て置かなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形+ておきませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ておく&lt;/strong&gt; &lt;span id=&quot;ID72050&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;关于&lt;code class=&quot;language-text&quot;&gt;ておく&lt;/code&gt;与&lt;code class=&quot;language-text&quot;&gt;てある&lt;/code&gt;的区别，以及完成时态的更完整的细节可以查看章节&lt;a href=&quot;#ID72034&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;7.2.3&lt;/code&gt;&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;补充语法点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;时的问题：
&lt;ul&gt;
&lt;li&gt;虽然在章节&lt;a href=&quot;#ID72034&quot;&gt;7.2.3&lt;/a&gt;的时候说了，ておく有很多情况是使用过去时，这种情况一般是表示&lt;code class=&quot;language-text&quot;&gt;已经完成的准备&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;自転車はもう&lt;code class=&quot;language-text&quot;&gt;買っておい&lt;/code&gt;た。/自行车已经买好了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;但也有很多情况是使用非过去时，这种情况一般是表示&lt;code class=&quot;language-text&quot;&gt;将来的打算&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;旅行の前に、切符を&lt;code class=&quot;language-text&quot;&gt;買っておく&lt;/code&gt;。（尚未去买车票，准备去买）&lt;/li&gt;
&lt;li&gt;試験までに、単語を&lt;code class=&quot;language-text&quot;&gt;覚えておきます&lt;/code&gt;。（尚未开始准备考试，接下去准备背单词）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示放任：
&lt;ul&gt;
&lt;li&gt;这种使用情况下，ておく表示的不是准备工作或将来打算，而是完成之后的放任态度，这里的时也是过去时非过去时皆可
&lt;ul&gt;
&lt;li&gt;看板をいつまでも&lt;code class=&quot;language-text&quot;&gt;出しておく&lt;/code&gt;。/让招牌一直放在外面。&lt;/li&gt;
&lt;li&gt;とりあえず押し入れに&lt;code class=&quot;language-text&quot;&gt;入れておけ&lt;/code&gt;。/先放到壁橱里再说。&lt;/li&gt;
&lt;li&gt;もうすぐアニメの時間だから、テレビを&lt;code class=&quot;language-text&quot;&gt;つけておいて&lt;/code&gt;よ。/马上就要播动画了，电视就让它开着吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ておく可以约音成&lt;code class=&quot;language-text&quot;&gt;とく&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;言っとく&lt;/code&gt;よ。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;726-被动态&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#726-%E8%A2%AB%E5%8A%A8%E6%80%81&quot; aria-label=&quot;726 被动态 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.6 被动态&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt; &lt;span id=&quot;ID72060&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;表示动作行为的主语并非实施者，主语为承受者的情况。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;分类&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;构成&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;变化&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;五段动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+れる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;言う&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;言われる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;一段动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+られる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;食べる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;食べられる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;サ变动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词根+される(约音)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強される&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;カ变动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+られる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来(こ)られる&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;が/は&lt;/code&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;に/から/によって...&lt;/code&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;&lt;strong&gt;D&lt;/strong&gt;（ら）れる。
&lt;ul&gt;
&lt;li&gt;太郎が犬に&lt;code class=&quot;language-text&quot;&gt;かまれ&lt;/code&gt;た。/太郎被狗咬了。&lt;/li&gt;
&lt;li&gt;太郎は先生からよく&lt;code class=&quot;language-text&quot;&gt;ほめられる&lt;/code&gt;。/太郎常受到老师表扬。&lt;/li&gt;
&lt;li&gt;次郎が太郎に英語を&lt;code class=&quot;language-text&quot;&gt;教えられる&lt;/code&gt;。/次郎由太郎教(他)英语&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A：动作承受方，主语&lt;/li&gt;
&lt;li&gt;B：动作实施方，人物宾语&lt;/li&gt;
&lt;li&gt;C：传递物，事物宾语&lt;/li&gt;
&lt;li&gt;D：动作&lt;/li&gt;
&lt;li&gt;C的这一部分并不是必须的，有的表述需要有的则不需要；如果存在的话，则必须在A和B两者之间有物质的或精神的东西传递（即C）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接被动句：
&lt;ul&gt;
&lt;li&gt;直接被动句的动词都是&lt;code class=&quot;language-text&quot;&gt;他动词&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;直接被动句&lt;code class=&quot;language-text&quot;&gt;可以还原&lt;/code&gt;为&lt;code class=&quot;language-text&quot;&gt;主动句&lt;/code&gt;进行叙述&lt;/li&gt;
&lt;li&gt;直接被动句就是最常见的被动句表述方式
&lt;ul&gt;
&lt;li&gt;李さんが王さんから辞書を&lt;code class=&quot;language-text&quot;&gt;渡され&lt;/code&gt;た。/小李从小王手里接过递过来的辞典。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;间接被动句：
&lt;ul&gt;
&lt;li&gt;间接被动句的动词可以是&lt;code class=&quot;language-text&quot;&gt;自动词&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;他动词&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;自动词&lt;/code&gt;的间接被动句一般&lt;code class=&quot;language-text&quot;&gt;无法直接还原&lt;/code&gt;成主动句&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;他动词&lt;/code&gt;的间接被动句&lt;code class=&quot;language-text&quot;&gt;可以还原&lt;/code&gt;为主动句&lt;/li&gt;
&lt;li&gt;间接被动句中，动词（无论是自动词还是他动词）并没有直接作用于叙述的焦点，而是句中的主语从动作施事者那里遭受到不利的影响
&lt;ul&gt;
&lt;li&gt;叙述的焦点与动作的施事者或承受者有必然的联系
&lt;ul&gt;
&lt;li&gt;混んだ電車の中で足を&lt;code class=&quot;language-text&quot;&gt;踏まれ&lt;/code&gt;た。/在拥挤的电车里被人把脚踩了。&lt;/li&gt;
&lt;li&gt;幼い時に、父に&lt;code class=&quot;language-text&quot;&gt;死なれ&lt;/code&gt;た。/很小的时候父亲就死了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;二者没有必然联系，而是在叙述客观事实时偶然建立起了关系
&lt;ul&gt;
&lt;li&gt;私は帰る途中、雨に&lt;code class=&quot;language-text&quot;&gt;降られ&lt;/code&gt;た。/我回来的路上被雨淋了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;727-使动态命令放任&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#727-%E4%BD%BF%E5%8A%A8%E6%80%81%E5%91%BD%E4%BB%A4%E6%94%BE%E4%BB%BB&quot; aria-label=&quot;727 使动态命令放任 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.7 使动态：命令、放任&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt; &lt;span id=&quot;ID72070&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;表示动作行为的主角并非行为的实际实施者，而是行为的要求者、指使者的情况。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;分类&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;构成&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;变化&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;五段动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+せる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;書く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;書かせる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;一段动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+させる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;食べる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;食べさせる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;サ变动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词根+させる(约音)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強させる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;カ变动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形+させる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来(こ)させる&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;が/は&lt;/code&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;に/を&lt;/code&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;&lt;strong&gt;D&lt;/strong&gt;（さ）せる。
&lt;ul&gt;
&lt;li&gt;先生が彼に論文を&lt;code class=&quot;language-text&quot;&gt;書かせる&lt;/code&gt;。/老师让他写论文了&lt;/li&gt;
&lt;li&gt;先生が太郎を廊下に&lt;code class=&quot;language-text&quot;&gt;立たせる&lt;/code&gt;。/老师叫太郎站在走廊里。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A：动作指使者，主语&lt;/li&gt;
&lt;li&gt;B：动作实施方，使动对象，人物宾语&lt;/li&gt;
&lt;li&gt;C：执行对象，事物宾语&lt;/li&gt;
&lt;li&gt;D：动作&lt;/li&gt;
&lt;li&gt;C的这一部分并不是必须的，有的表述需要有的则不需要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里的B应该使用&lt;code class=&quot;language-text&quot;&gt;に/を&lt;/code&gt;中的哪一个需要按情况操作，具体可以查看下面。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;格助词&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;他动词：
&lt;ul&gt;
&lt;li&gt;使动对象都用&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;先生が&lt;code class=&quot;language-text&quot;&gt;彼に&lt;/code&gt;論文を書かせる。/老师让他写论文了&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;彼に&lt;/code&gt;かってに言わせておこう。/让他随便说吧。（放任）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;具有他动词倾向的自动词也用&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;彼は&lt;code class=&quot;language-text&quot;&gt;人々に&lt;/code&gt;その提案に反対させた。/他让人们反对这项提议。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;自动词：
&lt;ul&gt;
&lt;li&gt;强制性
&lt;ul&gt;
&lt;li&gt;强制、命令等，使动对象都用&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;遊びたかったが、父は&lt;code class=&quot;language-text&quot;&gt;私たちを&lt;/code&gt;買いものに行かせた。/我们很想玩,可是爸爸却叫我们去买东西。&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;子どもを&lt;/code&gt;9時までに寝させる。/让孩子在9点以前睡觉。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示引发某种结果、间接责任导致某种结果等，使动对象也使用&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;謝まるつもりだが、かえって&lt;code class=&quot;language-text&quot;&gt;彼女を&lt;/code&gt;怒らせた。/我是要向她道歉的,没想到却使她发了火。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;非强制性
&lt;ul&gt;
&lt;li&gt;放任、允许等，使动对象用&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;父はやっと&lt;code class=&quot;language-text&quot;&gt;私たちに&lt;/code&gt;買い物に行かせるようになった。/爸爸终于(肯)让我们去买东西了。&lt;/li&gt;
&lt;li&gt;小さい&lt;code class=&quot;language-text&quot;&gt;子どもに&lt;/code&gt;一人で大通りを渡らせるのは危ない。/让小孩子单独过马路很危险&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;放任、允许&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;使动态有一点一定要注意的是，它很多时候用在&lt;code class=&quot;language-text&quot;&gt;放任、允许&lt;/code&gt;的表述上，这其实是相当反直觉的，和&lt;code class=&quot;language-text&quot;&gt;命令、强制&lt;/code&gt;完全相反，所以一定要小心阅读：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;母は子供を&lt;code class=&quot;language-text&quot;&gt;遊ばせています&lt;/code&gt;。/妈妈放任孩子玩。&lt;/li&gt;
&lt;li&gt;母は弟をアメリカへ&lt;code class=&quot;language-text&quot;&gt;留学させました&lt;/code&gt;。/妈妈允许弟弟去美国留学。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;使动态的被动态&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这种表述方法有很强的强迫、被迫的意思，如果是精神性的词汇，则表示非自发而是由其他东西触发的状态
&lt;ul&gt;
&lt;li&gt;先生が太郎を廊下に&lt;code class=&quot;language-text&quot;&gt;立たせ&lt;/code&gt;た。/老师叫太郎站在走廊上。（使动主动）&lt;/li&gt;
&lt;li&gt;太郎が先生に廊下に&lt;code class=&quot;language-text&quot;&gt;立たせられ&lt;/code&gt;た。/太郎披老师要求站在走廊上。（使动被动）&lt;/li&gt;
&lt;li&gt;就職活動で自分自身について真剣に深く&lt;code class=&quot;language-text&quot;&gt;考えさせられ&lt;/code&gt;た。/由于找工作，迫使我对自己进行了认真深入的思考。（精神性）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;被使动态的约音
&lt;ul&gt;
&lt;li&gt;五段动词被使动态常常发生如下的约音现象：
&lt;ul&gt;
&lt;li&gt;書く (せる)→ 書かせる (られる)→ 書かせられる (约音)→ 書かされる&lt;/li&gt;
&lt;li&gt;歌う (せる)→ 歌わせる (られる)→ 歌わせられる (约音)→ 歌わされる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;728-可能态能力可能性许可&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#728-%E5%8F%AF%E8%83%BD%E6%80%81%E8%83%BD%E5%8A%9B%E5%8F%AF%E8%83%BD%E6%80%A7%E8%AE%B8%E5%8F%AF&quot; aria-label=&quot;728 可能态能力可能性许可 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.8 可能态：能力、可能性、许可&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt; &lt;span id=&quot;ID72080&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;表示动作行为的能力或可能性。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;基本构成和被动态&lt;a href=&quot;#ID72060&quot;&gt;7.2.6&lt;/a&gt;一致。&lt;/p&gt;
&lt;p&gt;此外，五段动词可以转&lt;code class=&quot;language-text&quot;&gt;え&lt;/code&gt;段之后+&lt;code class=&quot;language-text&quot;&gt;る&lt;/code&gt;，转为下一段动词，来表示可能态：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;五段动词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;れる&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;可能态&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;買う&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;買われる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;買える&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;書く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;書かれる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;書ける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行かれる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行ける&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;読む&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;読まれる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;読める&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;实际上五段动词的可能态用的更多的是这种构成，也方便和被动态区别开来。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;が/は&lt;/code&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;&lt;strong&gt;C&lt;/strong&gt;（さ）れる。
&lt;ul&gt;
&lt;li&gt;あの子は自分で&lt;code class=&quot;language-text&quot;&gt;来られます&lt;/code&gt;。/那孩子自己能过来。&lt;/li&gt;
&lt;li&gt;（私は）ピアノが&lt;code class=&quot;language-text&quot;&gt;弾ける&lt;/code&gt;ようになった。/（我）能弹钢琴了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A：动作实施者，主语&lt;/li&gt;
&lt;li&gt;B：执行对象/可能性，事物宾语&lt;/li&gt;
&lt;li&gt;C：动作&lt;/li&gt;
&lt;li&gt;B的这一部分并不是必须的，有的表述需要有的则不需要&lt;/li&gt;
&lt;li&gt;B的格助词是&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;，发生了格转换&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;语义&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;和其他一些用法一样，可能态也能表示多种语义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;表示能力
&lt;ul&gt;
&lt;li&gt;この魚は飛ぶことが&lt;code class=&quot;language-text&quot;&gt;できる&lt;/code&gt;。/这种鱼会飞。&lt;/li&gt;
&lt;li&gt;ピアノが&lt;code class=&quot;language-text&quot;&gt;弾ける&lt;/code&gt;ようになった。/能弹钢琴了。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示可能性
&lt;ul&gt;
&lt;li&gt;用事があって&lt;code class=&quot;language-text&quot;&gt;出席でき&lt;/code&gt;ません。/有事不能出席。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示许可
&lt;ul&gt;
&lt;li&gt;授業中は、大声で&lt;code class=&quot;language-text&quot;&gt;話すことができない&lt;/code&gt;。/上课时不许太声说话。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;729-自然发生态&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#729-%E8%87%AA%E7%84%B6%E5%8F%91%E7%94%9F%E6%80%81&quot; aria-label=&quot;729 自然发生态 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2.9 自然发生态&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;使用场景&lt;/strong&gt; &lt;span id=&quot;ID72090&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;表示动作行为是自然而然地发生、自然而然地产生某种结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;构成&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;基本构成和被动态&lt;a href=&quot;#ID72060&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;7.2.6&lt;/code&gt;&lt;/a&gt;一致。&lt;/p&gt;
&lt;p&gt;且也有和可能态&lt;a href=&quot;#ID72080&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;7.2.8&lt;/code&gt;&lt;/a&gt;一样的五段动词下一段构成法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;（さ）れる。
&lt;ul&gt;
&lt;li&gt;雪が降ると、故郷のことが&lt;code class=&quot;language-text&quot;&gt;思い出される&lt;/code&gt;。/ー下雪就不由得想起故乡。（执行对象存在，使用格助词&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;あの映画を見ると&lt;code class=&quot;language-text&quot;&gt;泣け&lt;/code&gt;てしかたがない。/看那部电影让人哭泣不已。（五段动词的下一段转换）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A：执行对象，不是必须的，可能存在也可能不存在&lt;/li&gt;
&lt;li&gt;A的格助词是&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;语法补充&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;意义&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;表示不由自主地产生某种行为或结果，与人为动作不同。着重点在于行为发生顺乎自然，不关注行为的执行者本身。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;れる/られる的额外用法：表尊敬&lt;/strong&gt; &lt;span id=&quot;ID72091&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;对话题中的人物动作添加敬意。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先生の&lt;code class=&quot;language-text&quot;&gt;考えられた&lt;/code&gt;とうりです。/正如老师您所想的那样。&lt;/li&gt;
&lt;li&gt;課長はいつ富士山に登られたのですか。/科长您是什么时候去登的富士山？&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;8-疑难--总结&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-%E7%96%91%E9%9A%BE--%E6%80%BB%E7%BB%93&quot; aria-label=&quot;8 疑难  总结 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. 疑难 / 总结&lt;/h2&gt;
&lt;h3 id=&quot;81-发音单词的促音长音&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#81-%E5%8F%91%E9%9F%B3%E5%8D%95%E8%AF%8D%E7%9A%84%E4%BF%83%E9%9F%B3%E9%95%BF%E9%9F%B3&quot; aria-label=&quot;81 发音单词的促音长音 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1 发音：单词的促音/长音&lt;/h3&gt;
&lt;p&gt;单词中的促音和长音估计是最让人头痛的了。说实在的，基本上没什么很好的办法能解决。唯一的办法就是提升熟练度，也就是反复练习。一般最容易搞错促音和长音的时候是初见，经常不容易从听音中发现音节的延长，但只要是真的学习和背诵过的单词，一般不太会错。&lt;/p&gt;
&lt;p&gt;促音就是将前面的发音中断一瞬之后，继续后面的发音；长音则是将前面的发音延长一瞬。说起来是一瞬，但实际发音的时候还是很明显的，多练就很清楚。&lt;/p&gt;
&lt;p&gt;举个比较恶心的例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;実習 じ&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;しゅ&lt;code class=&quot;language-text&quot;&gt;う&lt;/code&gt;０&lt;/li&gt;
&lt;li&gt;自習 じしゅ&lt;code class=&quot;language-text&quot;&gt;う&lt;/code&gt;０&lt;/li&gt;
&lt;li&gt;自主 じしゅ０&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;82-发音清音浊音区分&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#82-%E5%8F%91%E9%9F%B3%E6%B8%85%E9%9F%B3%E6%B5%8A%E9%9F%B3%E5%8C%BA%E5%88%86&quot; aria-label=&quot;82 发音清音浊音区分 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2 发音：清音浊音区分&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=PnNQ9JfXy5E&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【關於清音聽成濁音這件事】頑張って？頑張っで？【PTK法則？】&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://www.sigure.tw/comprehensive-learning/knowledge/464&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;為什麼「頑張って」聽起來像「頑張っで」？PTK&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;规则：&lt;/p&gt;
&lt;p&gt;单词之中如果出现「P、T、K」的日文，通常听起来就会接近「B、D、G」。&lt;/p&gt;
&lt;p&gt;举例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;頑張っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;ね（gan ba t&lt;code class=&quot;language-text&quot;&gt;te&lt;/code&gt; ne）→ T
&lt;ul&gt;
&lt;li&gt;听起来有点接近「頑張っ&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;ね」→ D&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;待っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;ください（ma t&lt;code class=&quot;language-text&quot;&gt;te&lt;/code&gt; ku da sai）→ T 
&lt;ul&gt;
&lt;li&gt;听起来有点接近「待っ&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;ください」→ D&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;いっ&lt;code class=&quot;language-text&quot;&gt;ぱ&lt;/code&gt;い飲んでね（i p&lt;code class=&quot;language-text&quot;&gt;pa&lt;/code&gt; i non de ne）→ P 
&lt;ul&gt;
&lt;li&gt;听起来有点接近「いっ&lt;code class=&quot;language-text&quot;&gt;ば&lt;/code&gt;いのんでね」→ D&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;そっ&lt;code class=&quot;language-text&quot;&gt;か&lt;/code&gt;（so k&lt;code class=&quot;language-text&quot;&gt;ka&lt;/code&gt;）→ K 
&lt;ul&gt;
&lt;li&gt;听起来有点接近「そっ&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;」→ G&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但事实上，这仅只是&lt;code class=&quot;language-text&quot;&gt;可能&lt;/code&gt;的问题，一个单词里听上去像浊音的发音实际上真的有可能是浊音，如：袖 そ&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;。说到底其实没有什么好的区分方法，还是只能靠自己熟悉，多读多背。&lt;/p&gt;
&lt;h3 id=&quot;83-动词自动词他动词区分&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#83-%E5%8A%A8%E8%AF%8D%E8%87%AA%E5%8A%A8%E8%AF%8D%E4%BB%96%E5%8A%A8%E8%AF%8D%E5%8C%BA%E5%88%86&quot; aria-label=&quot;83 动词自动词他动词区分 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.3 动词：自动词他动词区分&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=d0pBTsCHsgc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;時雨日文【自動詞、他動詞的用法】自他同形？純自動詞？純他動詞？&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看到一个动词，要区分其是自动词还是他动词没有完美的规律可循，虽然有一定规律可以借鉴。所以真正的区分方法还是和之前的促音长音一样，要靠练习，增加熟练度。&lt;/p&gt;
&lt;p&gt;自动词：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自然现象或自发的事项，一般没有动作执行者；有些情况下，虽然存在着动作执行者，但事情的发生并不以其意志为转移，或者执行者不是叙述焦点&lt;/li&gt;
&lt;li&gt;財布&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;落ちる。/钱包掉落 视角在掉落这件事情上&lt;/li&gt;
&lt;li&gt;温度&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;上がる。/温度上升&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;他动词：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;他动词常常涉及动作执行者，虽然在使用时动作执行者未必都出现，但是动作执行者是隐含在动词的词义之中的&lt;/li&gt;
&lt;li&gt;財布&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;落とす。 /弄丢了钱包 视角在某人弄丢钱包这件事情上&lt;/li&gt;
&lt;li&gt;温度&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;上げる。 /升高温度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一些组合范例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;自动词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;他动词&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;集まる 集合&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;集める 收集&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;受かる 考上&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;受ける 赴考&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;植わる 栽植&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;植える 种植&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;終わる 结束&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;終える 做完&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;区分规律：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自动词
&lt;ul&gt;
&lt;li&gt;发音为 a段 + る e.g 集まる&lt;/li&gt;
&lt;li&gt;末尾为 れる e.g 現れる&lt;/li&gt;
&lt;li&gt;助词为 が&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;他动词
&lt;ul&gt;
&lt;li&gt;发音为 e段 + る e.g 集める&lt;/li&gt;
&lt;li&gt;末尾为 す e.g 現す&lt;/li&gt;
&lt;li&gt;末尾为 a段 + せる e.g 合わせる&lt;/li&gt;
&lt;li&gt;助词为 を&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;84-动词分类继续瞬间状态形容性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#84-%E5%8A%A8%E8%AF%8D%E5%88%86%E7%B1%BB%E7%BB%A7%E7%BB%AD%E7%9E%AC%E9%97%B4%E7%8A%B6%E6%80%81%E5%BD%A2%E5%AE%B9%E6%80%A7&quot; aria-label=&quot;84 动词分类继续瞬间状态形容性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.4 动词分类：继续、瞬间、状态、形容性&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;ている&lt;/code&gt;在日语中也是一个比较特殊的表达，根据动词的不同，ている表达的意思会相差很多，因此根据这个特性可以将动词分为4个子类：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;动词属性&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;说明&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;继续动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表示动词所指的动作或作用正在进行过程中&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;泣く、書く、渡る、飛ぶ、食べる、勉強する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;瞬间动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表示动词所指的动作成作用已经结束但其还保留着&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;始まる、死め、来る、汚れる、起きる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;状态动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;这类动词本身就表示状态，其意义多表示存在、能力等&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ある、いる、できる（会、能够）、見える、読める&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;形容词性动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;形容词性动总是要以“ている”的形式使用，且以这种形式表示状态、性质等&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;優れる、そびえる、治う、似る&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;85-动词分句中的时&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#85-%E5%8A%A8%E8%AF%8D%E5%88%86%E5%8F%A5%E4%B8%AD%E7%9A%84%E6%97%B6&quot; aria-label=&quot;85 动词分句中的时 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.5 动词：分句中的时&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;定语、宾语、补语等成分中的时&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;定语等成分中的时大多是&lt;code class=&quot;language-text&quot;&gt;相对时&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;タバコを&lt;code class=&quot;language-text&quot;&gt;吸っている&lt;/code&gt;人に道を尋ねた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;也有&lt;code class=&quot;language-text&quot;&gt;绝对时&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;わたしの前に&lt;code class=&quot;language-text&quot;&gt;立っていた&lt;/code&gt;人は、じっと壁の上の絵を見つめている。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;状语成分中的时&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当接续助词为“し”、“が”、“けれども“，即表示并列、对比时，或状语从句中的动词为状态动词时，分句动词用&lt;code class=&quot;language-text&quot;&gt;绝对时&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;洋服の生地も&lt;code class=&quot;language-text&quot;&gt;決めた&lt;/code&gt;し、靴も注文した。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;当状语从句中的动词为动作性动词时，用&lt;code class=&quot;language-text&quot;&gt;相对时&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;彼女が急に&lt;code class=&quot;language-text&quot;&gt;帰国した&lt;/code&gt;ので、みんな驚いた。/她突然回国了,大家都很惊话。&lt;/li&gt;
&lt;li&gt;彼女が&lt;code class=&quot;language-text&quot;&gt;帰国する&lt;/code&gt;ので、お別れ会をしてあげた。/她要回国了,所以给她开了个送别会。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;当状语是假定的关系，如条件、让步等逻辑关系时，状语从句中的时多为&lt;code class=&quot;language-text&quot;&gt;相对时&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;たとえ&lt;code class=&quot;language-text&quot;&gt;諦める&lt;/code&gt;にしても、もう少し努カしてみるべきだった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;引用成分中的时&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;引用成分（包括引语、思考内容等）多保持原话的时，也就是说在句中呈现&lt;code class=&quot;language-text&quot;&gt;相对时&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;彼は必ず&lt;code class=&quot;language-text&quot;&gt;行く&lt;/code&gt;と言ったのに、来なかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;86-动词补助动词的时态变化&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#86-%E5%8A%A8%E8%AF%8D%E8%A1%A5%E5%8A%A9%E5%8A%A8%E8%AF%8D%E7%9A%84%E6%97%B6%E6%80%81%E5%8F%98%E5%8C%96&quot; aria-label=&quot;86 动词补助动词的时态变化 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.6 动词：补助动词的时态变化&lt;/h3&gt;
&lt;p&gt;一般在看语法书的时候，语法书只会讲补助动词的基本形/辞书形：ている、てある、てしまう等。实际使用的时候，因为&lt;code class=&quot;language-text&quot;&gt;肯定/否定&lt;/code&gt;，&lt;code class=&quot;language-text&quot;&gt;非过去时/过去时&lt;/code&gt;，&lt;code class=&quot;language-text&quot;&gt;常体/敬体&lt;/code&gt;会导致补助动词产生形态变化。这些变化一般都不会记在语法书中，所以初学者看到都会不知所谓，不知道这个新玩意儿到底是什么意思。比如说：&lt;code class=&quot;language-text&quot;&gt;てしまいました&lt;/code&gt;，这个是&lt;code class=&quot;language-text&quot;&gt;てしまう&lt;/code&gt;这个补助动词的&lt;code class=&quot;language-text&quot;&gt;过去肯定敬体&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;所以在自学的时候，需要将补助动词的&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;去掉，然后将剩下部分的作为一个动词，来掌握其变化，最后补回て即可。&lt;/p&gt;
&lt;p&gt;更多的例子可以去上面&lt;code class=&quot;language-text&quot;&gt;7.2.x&lt;/code&gt;，都有构成表。举个例子：持续体&lt;a href=&quot;#ID72020&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;7.2.2&lt;/code&gt;&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;87-动词授受表现&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#87-%E5%8A%A8%E8%AF%8D%E6%8E%88%E5%8F%97%E8%A1%A8%E7%8E%B0&quot; aria-label=&quot;87 动词授受表现 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.7 动词：授受表现&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/elementary/292-n4-28&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N4文法28「授受動詞」あげる、くれる、もらう&lt;/a&gt;&lt;br&gt;
&lt;a href=&quot;https://www.sigure.tw/learn-japanese/grammar/elementary/293-n4-29&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;N4文法29「て形+授受動詞」てあげる、てくれる、てもらう&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8.7.1 授受动词&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语气&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;常体&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;敬体&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;あげる/やる&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;给予&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげる/やる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげます/やります&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげない/やらない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげません/やりません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげた/やった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげました/やりました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげなかった/やらなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげませんでした/やりませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;さしあげる&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;给予&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;あげる/やる的尊敬形式&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげた&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;くれる&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;给予&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれた&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;くださる&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;给予&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;くれる的尊敬形式&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださります&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださらない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださりません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださりました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださらなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くださりませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;もらう&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;获得&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらいます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらわない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらいません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらいました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらわなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もらいませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;いただく&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;获得&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;もらう的尊敬形式&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただきます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;非过去&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただかない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただません&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;肯定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただいた&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただきました&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;过去时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただかなかった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いただきませんでした&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;8.7.2 内外/上下关系（方向性）&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;给予&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;关系&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;方向&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;动词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;例句&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;内外关系&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;由内而外：我方给外方&lt;br&gt;由外而内：外方给我方&lt;br&gt;无内外：双方都为外方&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あげる&lt;br&gt;くれる&lt;br&gt;あげる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;弟は佐藤さんに本を&lt;code class=&quot;language-text&quot;&gt;あげる&lt;/code&gt;。&lt;br&gt;佐藤さんは私に本を&lt;code class=&quot;language-text&quot;&gt;くれる&lt;/code&gt;。&lt;br&gt;佐藤さんは鈴木さんに本を&lt;code class=&quot;language-text&quot;&gt;あげる&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;上下关系&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;由下而上：地位低对地位高&lt;br&gt;由上而下：地位高对地位低&lt;br&gt;无上下：双方平辈&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さしあげる&lt;br&gt;くださる&lt;br&gt;遵循内外关系&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;私は先生に本を&lt;code class=&quot;language-text&quot;&gt;さしあげます&lt;/code&gt;。&lt;br&gt;先生は私に本を&lt;code class=&quot;language-text&quot;&gt;くださりました&lt;/code&gt;。&lt;br&gt;私は後輩に本を&lt;code class=&quot;language-text&quot;&gt;あげる&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;我方：我自己或和我有直接关系的人：自己、我的亲属、我的同事、我的朋友等&lt;/li&gt;
&lt;li&gt;外方：对方或和对方有直接关系的人：对方、对方亲属、对方同事、对方朋友等&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;やる&lt;/code&gt;是我方给予外方（限定地位较低或晚辈）的意思，作用同&lt;code class=&quot;language-text&quot;&gt;あげる&lt;/code&gt;，但较为粗俗，一般不使用。&lt;/p&gt;
&lt;p&gt;此外，当接收方为自己的时候，给予方永远是&lt;code class=&quot;language-text&quot;&gt;外方&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;父さんは私に本を&lt;code class=&quot;language-text&quot;&gt;くれる&lt;/code&gt;。（这里不是あげる）&lt;/li&gt;
&lt;li&gt;私は父さんに本をあげる。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;获得&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;もらう/いただく&lt;/code&gt;没有方向性，全部都是：A从B处得到某物。从高位者处获得东西的场景下，需要使用&lt;code class=&quot;language-text&quot;&gt;いただく&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8.7.3 句式：给予&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;は/が&lt;/code&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;あげる/くれる。
&lt;ul&gt;
&lt;li&gt;（私は）友達に辞書を&lt;code class=&quot;language-text&quot;&gt;もらっ&lt;/code&gt;た。/从朋友那儿得到了本辞典。&lt;/li&gt;
&lt;li&gt;友達が（私に）辞書を&lt;code class=&quot;language-text&quot;&gt;くれ&lt;/code&gt;た。/朋友送给我了本辞典。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A是物品的送出方&lt;/li&gt;
&lt;li&gt;B是物品的接收方，助词用&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;C是物品&lt;/li&gt;
&lt;li&gt;あげる/くれる的使用差别参照上一节&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;8.7.4 句式：获得&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;は/が&lt;/code&gt;&lt;strong&gt;B&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;に/から&lt;/code&gt;&lt;strong&gt;C&lt;/strong&gt;&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;もらう。
&lt;ul&gt;
&lt;li&gt;弟が兄に五千円&lt;code class=&quot;language-text&quot;&gt;もらっ&lt;/code&gt;た。/弟弟要了哥哥5000日元&lt;/li&gt;
&lt;li&gt;（私の）弟が社長にネクタイを&lt;code class=&quot;language-text&quot;&gt;いただい&lt;/code&gt;た。/（我）弟弟得到经理送的领带。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;A是物品的接收方&lt;/li&gt;
&lt;li&gt;B是物品的送出方，助词用&lt;code class=&quot;language-text&quot;&gt;に/から&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;C是物品&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;助词：に/から&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主动性与被动性
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;获得&lt;/code&gt;的句式只讲固定的获得行为，不讲究这个获得的&lt;code class=&quot;language-text&quot;&gt;主动性和被动性&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;看一对中文示例
&lt;ul&gt;
&lt;li&gt;奶奶&lt;code class=&quot;language-text&quot;&gt;让&lt;/code&gt;太郎给她读报纸。&lt;/li&gt;
&lt;li&gt;奶奶&lt;code class=&quot;language-text&quot;&gt;听&lt;/code&gt;太郎给她读报纸。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;虽然句子讲的都是获得，句式也都是同一句式，但实际意思还是有点不同的&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;格助词に和から可以对主动性作出大致的区分
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;に``可以&lt;/code&gt;（不是一定）表示&lt;code class=&quot;language-text&quot;&gt;要&lt;/code&gt;（主动）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;只表示（一定）&lt;code class=&quot;language-text&quot;&gt;收&lt;/code&gt;（被动）
&lt;ul&gt;
&lt;li&gt;（私の）弟が社長&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;ネクタイを&lt;code class=&quot;language-text&quot;&gt;いただい&lt;/code&gt;た。/（我）弟弟得到经理送的领带。（这里に表被动，因为句意只可能是被动）&lt;/li&gt;
&lt;li&gt;おばあさんは太郎&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;新聞を&lt;code class=&quot;language-text&quot;&gt;読んでもらっ&lt;/code&gt;た。/奶奶让太郎给她读报纸。（主动）&lt;/li&gt;
&lt;li&gt;おばあさんは太郎&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;新聞を&lt;code class=&quot;language-text&quot;&gt;読んでもらっ&lt;/code&gt;た。/奶奶听太郎给她读报纸。（被动）&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;有无生命
&lt;ul&gt;
&lt;li&gt;无生命送出方只能用&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;私は会社&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;車を&lt;code class=&quot;language-text&quot;&gt;もらいました&lt;/code&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;8.7.5 作为补助动词的授受动词&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;授受动词不仅可以独立使用，还可以接在&lt;code class=&quot;language-text&quot;&gt;动词连用形+て&lt;/code&gt;的后面，充当补助动词，借以表示人物之间行为的往来与恩惠关系。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;太郎がおばあさんに新聞を&lt;code class=&quot;language-text&quot;&gt;読んでやっ&lt;/code&gt;た。/太郎为奶奶读了报纸&lt;/li&gt;
&lt;li&gt;おばあさんは太郎に新聞を&lt;code class=&quot;language-text&quot;&gt;読んでもらっ&lt;/code&gt;た。/奶奶让太郎给她读了报纸。&lt;/li&gt;
&lt;li&gt;先生が資料を&lt;code class=&quot;language-text&quot;&gt;集めてくださっ&lt;/code&gt;た。/老师给(我)收集资料。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“~てさしあげる”、“~てあげる”、“&lt;del&gt;てやる”带有强烈的恩加于外的意味，因此必须谨慎使用。为他人做什么事，则常代之以表示自谦的“お&lt;/del&gt;する”等形式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;お荷物を&lt;code class=&quot;language-text&quot;&gt;おもちし&lt;/code&gt;ましょうか。/让我来给您拿行李吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;88-格助词常用整理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#88-%E6%A0%BC%E5%8A%A9%E8%AF%8D%E5%B8%B8%E7%94%A8%E6%95%B4%E7%90%86&quot; aria-label=&quot;88 格助词常用整理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.8 格助词：常用整理&lt;/h3&gt;
&lt;p&gt;完整的格助词语法清单可以查看&lt;a href=&quot;#IDX_IX&quot;&gt;速查表&lt;/a&gt;。时间相关的助词整理在：&lt;a href=&quot;#IDXI_time&quot;&gt;时间表达的助词及句式使用&lt;/a&gt;，地点相关的助词整理在：&lt;a href=&quot;#IDXI_place&quot;&gt;地点的表达&lt;/a&gt;。在当前章节中除了格助词之外，还会整理&lt;code class=&quot;language-text&quot;&gt;提示助词は&lt;/code&gt;，因为这个助词经常会顶替格助词的位置，所以需要弄清楚用法。&lt;/p&gt;
&lt;p&gt;此外，一些有用的资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/42925241&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日语格助词的固定用法（上篇）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/43038700&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日语格助词的固定用法（下篇）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://colanekojp.com.tw/blogs/0/24#&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日文9大格助詞，學日文必知的重要文法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.colanekojp.com.tw/blogs/0/4#&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;你所不知道的は與が的用法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;881-常用场景整理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#881-%E5%B8%B8%E7%94%A8%E5%9C%BA%E6%99%AF%E6%95%B4%E7%90%86&quot; aria-label=&quot;881 常用场景整理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.8.1 常用场景整理&lt;/h4&gt;
&lt;p&gt;&lt;span id=&quot;ID88010&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;应用场景&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;助词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;解说&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;主语、行为主体、称谓&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;表示主语&lt;/span&gt; | が | 表示判断、性质、状态、&lt;br&gt;存在、动作、作用等的&lt;code class=&quot;language-text&quot;&gt;主体&lt;/code&gt; | 斎藤さん&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;責任者です。(判断)&lt;br&gt;アルバイトの学生はみんな背&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;高い。(状态)&lt;br&gt;南美で大きい地震&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;起こった。(动作)
&lt;span style=&quot;color:#41E0F5&quot;&gt;表示主语&lt;/span&gt; | が | 表示好恶、巧拙、能力、&lt;br&gt;愿望、心理活动、需要等&lt;code class=&quot;language-text&quot;&gt;对象&lt;/code&gt; | 関西の人は納豆&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;嫌いだ。(好恶)&lt;br&gt;彼は英語&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;話せる。(能力)&lt;br&gt;スポーツ万能の友人&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;うらやましい。(心理活动)
&lt;span style=&quot;color:#41E0F5&quot;&gt;表示主体&lt;/span&gt; | に | 以下4种情况时，主体可以用“に”来表示&lt;br&gt;表示可能的动词“分かる”、“読める”、“見える”等&lt;br&gt;表示要求的动词、形容词、形容动词“欲しい“等&lt;br&gt;表示感情的形容词“嬉しい”、“悲しい”等&lt;br&gt;敬语动词 | 写真ぐらい私&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;も写せます。&lt;br&gt;わたし&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;はお金が必要だ。&lt;br&gt;親友の裏切りが私&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;は悲しい。&lt;br&gt;先生&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;はお変わりなく・・・
&lt;span style=&quot;color:#41E0F5&quot;&gt;表示主体&lt;/span&gt; | で | 表示动作的主体，大多是团体或组织等集合体 | これは当社&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;開発した新製品です。&lt;br&gt;警視庁&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;未成年者犯罪の取り締まりに・・
&lt;span style=&quot;color:#41E0F5&quot;&gt;表示主体&lt;/span&gt; | と | 表示行为、动作的共同者 | 私は母&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;デパートへ行きました。
&lt;span style=&quot;color:#41E0F5&quot;&gt;表示称谓&lt;/span&gt; | と | 表示称谓 | 私&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;張と申します。
&lt;span style=&quot;color:#41E0F5&quot;&gt;表示主体&lt;/span&gt; | から | 表示动作、作用的主体 | そのことは私&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;彼に話しておきます。
&lt;span style=&quot;color:#41E0F5&quot;&gt;提示主体&lt;/span&gt; | は | 可以顶替“が”、“を”提示主语、宾语&lt;br&gt;可以跟在补格助词的后面提示补语&lt;br&gt;(有时也可顶替“へ”和表示位置的“に“) | 桜の花&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;美しい。(提示主语)&lt;br&gt;この映画&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;先週見ました。(提示宾语)&lt;br&gt;バンダ&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;竹の葉をよく食べる。(提示叙述句主语)&lt;br&gt;ここで&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;話せない。(提示补语)&lt;br&gt;一週間に一度ぐらい&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;映画を見に行・・(提示状语)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;宾语、动作对象&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;表示宾语&lt;/span&gt; | を | 表示&lt;code class=&quot;language-text&quot;&gt;动作&lt;/code&gt;直接涉及的&lt;code class=&quot;language-text&quot;&gt;对象&lt;/code&gt; | 私は毎朝牛乳&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;飲みます。
&lt;span style=&quot;color:#F5B041&quot;&gt;表示宾语&lt;/span&gt; | を | 表示&lt;code class=&quot;language-text&quot;&gt;动作&lt;/code&gt;造成的直接&lt;code class=&quot;language-text&quot;&gt;结果&lt;/code&gt; | 積み木で城&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;つくる。
&lt;span style=&quot;color:#F5B041&quot;&gt;表示对象&lt;/span&gt; | に | 表示行为、动作所关联、涉及的对象 | 友達&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;パソコンを貨した。&lt;br&gt;この商品&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;手を触れてはいけません。
&lt;span style=&quot;color:#F5B041&quot;&gt;表示对象&lt;/span&gt; | へ | 表示动作、作用的对象 | これは母&lt;code class=&quot;language-text&quot;&gt;へ&lt;/code&gt;の手紙です。
&lt;span style=&quot;color:#F5B041&quot;&gt;表示对象&lt;/span&gt; | と | 表示行为、动作的对象 | 林さんは町角にある八百屋さんの娘&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;婚約したそうだ。
&lt;span style=&quot;color:#F5B041&quot;&gt;表示对象&lt;/span&gt; | と | 表示比较的对象 | 私の国&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;比べると、日本のほうが暑いです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;原因、理由、依据&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;表示原因&lt;/span&gt; | に | 表示理由、原因或依据 | あまりの嬉しさ&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;泣き出した。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;表示原因&lt;/span&gt; | で | 表示原因、理由 | 会社を風邪&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;休んでいます。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;表示原因&lt;/span&gt; | から | 表示原因、理由、依据等 | 小さなこと&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;けんかになった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;变化、演变的结果&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;表示结果&lt;/span&gt; | に | 表示事物或状态变化的结果 | 講堂が会場&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;変わりました。
&lt;span style=&quot;color:#BD00F9&quot;&gt;表示结果&lt;/span&gt; | と | 表示事物演变、转化的结果 | 長い努力がむだ&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;なった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;动作、行为的方式、状态、手段&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#74E302&quot;&gt;表示方式&lt;/span&gt; | に | 表示行为、动作进行的方式、状态 | 駅まで山沿い&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;歩いた。
&lt;span style=&quot;color:#74E302&quot;&gt;表示方式&lt;/span&gt; | で | 表示进行动作时所用的手段 | ラジオ講座&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;日本語を勉強します。
&lt;span style=&quot;color:#74E302&quot;&gt;表示状态&lt;/span&gt; | で | 表示动作进行时的状态 | 普通の速さ&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;歩いて5分ほどだ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;材料、原料、成分&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;表示材料&lt;/span&gt; | で | 表示进行动作时所用的材料 | あの洋服たんすは桐の木&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;作ったのです。
&lt;span style=&quot;color:#06CE9F&quot;&gt;表示材料&lt;/span&gt; | から | 表示原料、材料、成分等 | 酒は米&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;造る。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;比较、评价的基准&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#9A3702&quot;&gt;表示基准&lt;/span&gt; | に | 表示比较、评价、比例的基准 | ここは海&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;近いが、山&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;は遠い。
&lt;span style=&quot;color:#9A3702&quot;&gt;表示基准&lt;/span&gt; | と | 表示比较的基准 | ガラス糸は木綿や絹の糸&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;違って・・
&lt;span style=&quot;color:#9A3702&quot;&gt;表示基准&lt;/span&gt; | より | 表示比较的基准 | 今年は去年&lt;code class=&quot;language-text&quot;&gt;より&lt;/code&gt;ずっと暑いです。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;时间表达&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#659A02&quot;&gt;表示时间&lt;/span&gt; | に | 表示动作或作用的时间 | 3時&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;駅で待ち合わせる。
&lt;span style=&quot;color:#659A02&quot;&gt;表示时间&lt;/span&gt; | で | 表示期限或限度 | 新幹線は3時間&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;東京・大阪間を走る。
&lt;span style=&quot;color:#659A02&quot;&gt;表示时间&lt;/span&gt; | から | 表示时间上的起点 | 朝&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;彼を待っている。
&lt;span style=&quot;color:#659A02&quot;&gt;表示时间&lt;/span&gt; | まで | 表示时间上的终点 | 朝早くから夜遅く&lt;code class=&quot;language-text&quot;&gt;まで&lt;/code&gt;けんめいに働いている。
&lt;span style=&quot;color:#659A02&quot;&gt;表示时间&lt;/span&gt; | より | 表示起点 | 個展は明日&lt;code class=&quot;language-text&quot;&gt;より&lt;/code&gt;開催されます。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;地点表达&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#9A0257&quot;&gt;表示地点&lt;/span&gt; | に | 表示存在的场所 | 顔&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;笑いを浮かべた。
&lt;span style=&quot;color:#9A0257&quot;&gt;表示地点&lt;/span&gt; | に | 表示动作的目标、着落点 | 修学旅行で関西&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;行った。
&lt;span style=&quot;color:#9A0257&quot;&gt;表示地点&lt;/span&gt; | へ | 表示方向或到达点 | 裁判所&lt;code class=&quot;language-text&quot;&gt;へ&lt;/code&gt;訴えなければ解決策がない。
&lt;span style=&quot;color:#9A0257&quot;&gt;表示地点&lt;/span&gt; | で | 表示动作，行为发生的场所 | 解説欄&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;詳しく説明する。
&lt;span style=&quot;color:#9A0257&quot;&gt;表示地点&lt;/span&gt; | を | 表示动作经过的场所或动作离开的地点 | 電車道&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;歩いて来る。&lt;br&gt;東京駅&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;今晚の10時に立ちます。
&lt;span style=&quot;color:#9A0257&quot;&gt;表示地点&lt;/span&gt; | から | 表示空间上的起点 | 車&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;降りた男。
&lt;span style=&quot;color:#9A0257&quot;&gt;表示地点&lt;/span&gt; | まで | 表示空间上的终点 | 荷物をとなりの部屋&lt;code class=&quot;language-text&quot;&gt;まで&lt;/code&gt;運んでください。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| - | &lt;strong&gt;其他&lt;/strong&gt; |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;color:#0264CF&quot;&gt;表示目的&lt;/span&gt; | に | 表示动作的目的后续&lt;br&gt;“来る”、“行く”等表示趋向的动词&lt;br&gt;接在动词或形式名词“の”、“ため”后 | 遠くから泳ぎ&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;来た人も多い。&lt;br&gt;北京に行く&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;は、どの汽車に乗ったらいいでしよう。&lt;br&gt;この論文を書き終わるの&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;あと何日かかるだろう。
&lt;span style=&quot;color:#0264CF&quot;&gt;表示程度&lt;/span&gt; | に | 表示状态、程度，像副词一样使用 | 水を大量&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;飲むことです。&lt;br&gt;お気付きの点は遠慮なし&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;言ってください。
&lt;span style=&quot;color:#0264CF&quot;&gt;表示范围&lt;/span&gt; | で | 表示范围、范畴 | 外交の面&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;も一連の大きな成果を収めた。
&lt;span style=&quot;color:#0264CF&quot;&gt;表示内容&lt;/span&gt; | と | 表示思考、叙述的内容 | ー度富士山に登ってみたい&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;思います。
&lt;span style=&quot;color:#0264CF&quot;&gt;表示限定&lt;/span&gt; | より | 表示限定 | こうする&lt;code class=&quot;language-text&quot;&gt;より&lt;/code&gt;ほかに仕方がない。&lt;/p&gt;
&lt;h4 id=&quot;882-が-与-を&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#882-%E3%81%8C-%E4%B8%8E-%E3%82%92&quot; aria-label=&quot;882 が 与 を permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.8.2 が 与 を&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;表示对象的“が”可以被“を”来替换
&lt;ul&gt;
&lt;li&gt;子どもが水&lt;code class=&quot;language-text&quot;&gt;を(が)&lt;/code&gt;欲しいって言うんですが。/孩子说想喝水呢。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;谓语是表示愿望、可能的表现形式时，表示其对象的格助词可以用“を”或“が”
&lt;ul&gt;
&lt;li&gt;目&lt;code class=&quot;language-text&quot;&gt;を(が)&lt;/code&gt;あけられない。/睁不开眼。&lt;/li&gt;
&lt;li&gt;但其中着重点不同
&lt;ul&gt;
&lt;li&gt;着重对象：目が -&gt; あけられない(眼睛睁不开)&lt;/li&gt;
&lt;li&gt;着重动作：(目をあける) -&gt; られない(睁不开眼時)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;883-に-与-を&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#883-%E3%81%AB-%E4%B8%8E-%E3%82%92&quot; aria-label=&quot;883 に 与 を permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.8.3 に 与 を&lt;/h4&gt;
&lt;p&gt;这里主要讨论的是对象使用时的に与を的使用区别，作为地点时的使用相对来说区别比较清晰，不需要额外论述。&lt;/p&gt;
&lt;p&gt;参考：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/52284766&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;「を」vs「に」，两种表“对象”的格助词有什么区别？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.zhihu.com/question/60512166/answer/177335692&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日语中に和を在提示宾语的时候怎么区分？&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;に是补格助词
&lt;ul&gt;
&lt;li&gt;补格助词前面的一般是补语&lt;/li&gt;
&lt;li&gt;后面的谓语动词一般是自动词(不绝对)&lt;/li&gt;
&lt;li&gt;补语的对象在日语的思维中，都不是实物，或不是直接接触的对象&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;を是宾格助词
&lt;ul&gt;
&lt;li&gt;宾格助词前面的一般指宾语&lt;/li&gt;
&lt;li&gt;后面的谓语动词一般是他动词(不绝对)&lt;/li&gt;
&lt;li&gt;宾语一般指实物，能够真实触及到的
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;彼&lt;/code&gt;を倒した。&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ご飯&lt;/code&gt;を食べる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;思维差异
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;電車&lt;/code&gt;に乗る。
&lt;ul&gt;
&lt;li&gt;日本人认为，乘坐是没有宾语的，是人乘坐到车子里面，而不是车子被人乘坐。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;山&lt;/code&gt;に登る。
&lt;ul&gt;
&lt;li&gt;日本人认为，攀登这个词是没有宾语的，山并不是被爬，而是爬这个动作有一个方向，这个方向就是山上。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;感情动词的例子不太适用于上面的解说，可能需要硬性记忆
&lt;ul&gt;
&lt;li&gt;に：苦しむ、困る、疲れる、気づく、慣れる、酔う、驚く、飽きる、憧れる……&lt;/li&gt;
&lt;li&gt;を：楽しむ、愛する、悲しむ、嫌う、望む、恨む、惜しむ、憎む、好む、恐れる……&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;举例：更换动作的を和に
&lt;ul&gt;
&lt;li&gt;同一类的物品进行更换用を（实际物体，宾格）&lt;/li&gt;
&lt;li&gt;不同的物品之间的更换用に（概念，补格）
&lt;ul&gt;
&lt;li&gt;新年になったので、日記帳&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;換えた。新しいの&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;換えた。&lt;/li&gt;
&lt;li&gt;家に帰ると普段着&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;換える。&lt;/li&gt;
&lt;li&gt;大連まで飛行機で飛んで、そこから船&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;乗り換える。&lt;/li&gt;
&lt;li&gt;私は南門でバス&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;乗り換える、３番バスから１番バス&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;乗り換える。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;がにを的一些麻烦例子
&lt;ul&gt;
&lt;li&gt;好恶：
&lt;ul&gt;
&lt;li&gt;私は　先輩を　愛する。“爱上”&lt;/li&gt;
&lt;li&gt;私は　先輩に　憧れる。“迷恋”&lt;/li&gt;
&lt;li&gt;私は　先輩が　好きだ。“喜欢”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;看：
&lt;ul&gt;
&lt;li&gt;私は　富士山を　見る。“看”&lt;/li&gt;
&lt;li&gt;私は　富士山に　向ける。“面向”&lt;/li&gt;
&lt;li&gt;私は　富士山が　見える。“看得见”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;884-は-与-が&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#884-%E3%81%AF-%E4%B8%8E-%E3%81%8C&quot; aria-label=&quot;884 は 与 が permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.8.4 は 与 が&lt;/h4&gt;
&lt;p&gt;“は”与“が”是两种性质完全不同的助词。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“が”接在体言或相当于体言的词语后，表示该体言是断定、存在、性质、状态、行为、動作等的主体。&lt;/li&gt;
&lt;li&gt;“は”的作用是表示说话人突出地提出一个成分来，使之成为后面的谓语部分着重说明的对象。这个成分既可以是主语，也可以是宾语、状语、补语等。“は”既可以跟在体言后面，又可以跟在用言的活用形后。跟在体言后的“は”，可以表示主语（代替“が”）、也可以表示宾语（代替“を“）、表示补语（代替“へ”等）。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以像下面这样的句子，“は”代替的是“を”和“に“，就不能用“が”来替换。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O この本&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;父が買ってくれた。/这本书是父亲给我买的&lt;/li&gt;
&lt;li&gt;O ここ&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;植木を置いてください。/请在这几放个花盆。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，所谓“は”与“が”的区别，应该只是指表示谓语主体的“が”与代替“が”提示主题的“は”的区别。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“は”用于“已知”的事物，“が”用于“未知”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;当句子的着重点或疑问点在主体以外的部分时，主体后用“は”，当句子的着重点或疑问点在主体时，主体后用“が”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 先生&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;どなたですか。&lt;/li&gt;
&lt;li&gt;O どなた&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;先生ですか。&lt;/li&gt;
&lt;li&gt;O あなたの&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;どの傘ですか。&lt;/li&gt;
&lt;li&gt;O どの傘&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;あなたのですか。&lt;/li&gt;
&lt;li&gt;O 東&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;どちらですか。&lt;/li&gt;
&lt;li&gt;O どちら&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;東ですか。&lt;/li&gt;
&lt;li&gt;O 一陳さん&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;寮にいますか。一いいえ、陳さん&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;図書館にいます。（问句中主体后用“は”，答句中主体后也用“は”)&lt;/li&gt;
&lt;li&gt;O ーどの傘&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;あなたのですか。一赤いの&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;私のです。（问句中主体后用“が”，答句中主体后也用“が”)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;试比较“私&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;理事長です”和“私&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;理事長です”。前句中用“は”表示的“私”是已知概念，“理事長です”是对于前面部分所做的说明，是就“私はどういう人か”这一问题向对方传递新的信息“理事長”。而后句中“理事長”是已知信息，听话人要知道的是“謹が理事長か”这个问题的答案，说话人对此提供“私が”这个新的信息作为回答。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“は”用于主观判断来说明某一事物（包括真理、法则、习性等），或者表示人的意志、信念、能力、习慣等，“が”用于客观描述眼前具体情景&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 太陽&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;東から出る。/大阳是从东方升起的&lt;/li&gt;
&lt;li&gt;O 西安&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;古い都です。/西安是古都。&lt;/li&gt;
&lt;li&gt;O わたし&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;每朝庭の掃除をします。/我每天早上打扫院子&lt;/li&gt;
&lt;li&gt;O あ、雨&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;降ってきた。/啊,下起雨来了。&lt;/li&gt;
&lt;li&gt;O 桜の花&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;咲いている。/樱花开了。&lt;/li&gt;
&lt;li&gt;O 風&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;冷たいですね。/风真冷啊。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“タ焼けがきれいだ”和“タ焼けはきれいだ”这两句的不同在于，“タ焼けがきれいだ”是客观描写眼前具体情景，从这一句话可以想到它所存在的场景：仰望天空时看到彩霞，不禁脱口而出；“晚霞真美”。即指当时看到的晚霞美丽。“タ焼けはきれいだ”是对晚霞这一事物做出的一般性判断。说这句话时，不见得非要看到晚度。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;包孕句或主从句中主句主语一般用“は”，从句主语一般用“が”&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O あなた&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;こなかったの&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;いけなかった。/你没来，这可不好。&lt;/li&gt;
&lt;li&gt;O 母&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;私&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;国を出るとき泣きました。/在我要离开家乡的时候，母亲哭了。&lt;/li&gt;
&lt;li&gt;O 私&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;言うことをそのまま書きなさい。/把我说的话原样写下来。&lt;/li&gt;
&lt;li&gt;O このテレビ&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;デザイン&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;とてもいいです。/这台电视设计的真好。&lt;/li&gt;
&lt;li&gt;O 映画館&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;近ければ私も行きます。/要是电影院不远的话, 我也去。&lt;/li&gt;
&lt;li&gt;O 雨&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;降っているのに外で遊んでいます。/下着雨，还在外边玩几。&lt;/li&gt;
&lt;li&gt;O 私&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;うちへ帰るとすぐお風呂に入ります。/我回家后立刻洗澡。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从上面的例句可以看出：主体用“が”一般只关联到就近的谓语，主体用“は”关联到句末或全句，甚至关联到下面的句子。因此下面的句子是错误的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;X 雨&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;降れば行きません。/要是下雨，就不去了。&lt;/li&gt;
&lt;li&gt;X あなた&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;行けと言うなら行こう。/如果你非让去,那我就去吧。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;像“象は鼻が長い”这样的主谓谓语句，谓语从句主语（小主语）也有用“は”的情况，这时多表示对比或转折的语气。“象は鼻は長い”这句话就多见于“象は鼻は長い (が，目は小さい）”等表示对比的场合。&lt;/p&gt;
&lt;h4 id=&quot;885-と-的细节与-にを-的比较以及-って&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#885-%E3%81%A8-%E7%9A%84%E7%BB%86%E8%8A%82%E4%B8%8E-%E3%81%AB%E3%82%92-%E7%9A%84%E6%AF%94%E8%BE%83%E4%BB%A5%E5%8F%8A-%E3%81%A3%E3%81%A6&quot; aria-label=&quot;885 と 的细节与 にを 的比较以及 って permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.8.5 と 的细节，与 に/を 的比较，以及 って&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;って：可以理解成“って言って”省略了“言って”
&lt;ul&gt;
&lt;li&gt;ぼくは鈴木&lt;code class=&quot;language-text&quot;&gt;って&lt;/code&gt;います。/我叫铃木。&lt;/li&gt;
&lt;li&gt;あとで金を渡す&lt;code class=&quot;language-text&quot;&gt;って&lt;/code&gt;だましやがった。/欺骗说什么回头再给我钱。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;って：“という”、“って”有时可以表示同格
&lt;ul&gt;
&lt;li&gt;その会社の、会長&lt;code class=&quot;language-text&quot;&gt;という&lt;/code&gt;人。/那个公司做董事长的人&lt;/li&gt;
&lt;li&gt;10 年&lt;code class=&quot;language-text&quot;&gt;って&lt;/code&gt;年月がかかる。/要花 10 年的时间。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;って：像提示助词一样的用法，这时相当于“とは”、“というのは”
&lt;ul&gt;
&lt;li&gt;北海道&lt;code class=&quot;language-text&quot;&gt;って&lt;/code&gt;広いのね。/北海道可真是辽阔啊!&lt;/li&gt;
&lt;li&gt;日本&lt;code class=&quot;language-text&quot;&gt;って&lt;/code&gt;狭いんだな。/日本真是小啊&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;と 和 に
&lt;ul&gt;
&lt;li&gt;表示“行为、动作的共同者或对象”时，“と”和“に”都可以使用，“と”表示相互的动作，“に“表示単方向性的动作
&lt;ul&gt;
&lt;li&gt;昨日駅で田中さん&lt;code class=&quot;language-text&quot;&gt;に (と）&lt;/code&gt;会いました。/昨天在车站见到了田中&lt;/li&gt;
&lt;li&gt;来年の留学のことを父&lt;code class=&quot;language-text&quot;&gt;に (と）&lt;/code&gt;話しました。/和父亲谈了明年留学的事。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示“比较的基准”时，“と”和“に”也都可以使用，用“と”主要表示对等性，用“に”表示单方向性，重点在于逐渐接近对方
&lt;ul&gt;
&lt;li&gt;先生&lt;code class=&quot;language-text&quot;&gt;と (に)&lt;/code&gt;よく似た人。/和老师长得很相像的人。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;表示变化的结果
&lt;ul&gt;
&lt;li&gt;“AをBとする”表示将本来不是 B 的 A，一时作为 B 来用，是暂时的、表面性的变化
&lt;ul&gt;
&lt;li&gt;閲覧室を教室&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;して一週間勉強した。/把阅览室作为教室，学习了一个星期&lt;/li&gt;
&lt;li&gt;兄を先生&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;して少し英語を習った。/把哥哥当老师，跟他多少学了些英语&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;“AをBにする”表示把 A 改造成 B，是永久的、本质性的变化。
&lt;ul&gt;
&lt;li&gt;教室が足りないので、閲覧室をも教室&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;した。/因为教室不够、把阅览室也改造成为教室了。&lt;/li&gt;
&lt;li&gt;息子を学校の先生&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;した。/让儿子当了学校的老师&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;と 和 を
&lt;ul&gt;
&lt;li&gt;言う、思う、考える、話す、感じる、申す、存じる、書く、呼ぶ等都称作言表动词，它所表示的内容，有抽象的概念，也有具体的内容&lt;/li&gt;
&lt;li&gt;抽象的概念用を&lt;/li&gt;
&lt;li&gt;具体的内容用と
&lt;ul&gt;
&lt;li&gt;ここに電話番號&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;書いてください。&lt;/li&gt;
&lt;li&gt;部屋のドアに(部屋番號が)301&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;書いてあります。&lt;/li&gt;
&lt;li&gt;明日は良い天気になる&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;思います。&lt;/li&gt;
&lt;li&gt;明日の天気&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;心配します。&lt;/li&gt;
&lt;li&gt;先生が「王さん、王さん」&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;呼んでいます。&lt;/li&gt;
&lt;li&gt;先生が学生の名前&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;呼んでいます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;886-から-与-で原材料的区别&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#886-%E3%81%8B%E3%82%89-%E4%B8%8E-%E3%81%A7%E5%8E%9F%E6%9D%90%E6%96%99%E7%9A%84%E5%8C%BA%E5%88%AB&quot; aria-label=&quot;886 から 与 で原材料的区别 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.8.6 から 与 で，原材料的区别&lt;/h4&gt;
&lt;p&gt;“から”和“で”都可以表示原料材料，一般说来，从原料到成品变化较少（从成品能推测出原料）时用“で”，从原料到成品变化较大（从成品很难推测出原料）时用“から”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;その椅子は本&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;できている。/那把椅子是用木头做的。&lt;/li&gt;
&lt;li&gt;プラスチックは石油&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;造る。/塑料是以石油为原料制造的。&lt;/li&gt;
&lt;li&gt;あんな古着&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;こんなすてきな服をつくるとはさすがだ。/能用那样的旧衣服做出这么漂亮的衣服真了不起。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是，也有像“酒は米&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;つくる”和“酒は米&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;つくる”这种“から”和“で 都能用的情况。用“で”时着重强调米是做酒时所使用的东西，和“で”表示方法、手段是同一性质的用法，用“から”时着重强调米是生产酒的起点，在生产过程中发生变化，最后成为酒。&lt;/p&gt;
&lt;h3 id=&quot;89-其他助词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#89-%E5%85%B6%E4%BB%96%E5%8A%A9%E8%AF%8D&quot; aria-label=&quot;89 其他助词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.9 其他助词&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;ID89000&quot;&gt;&lt;/span&gt;
个人感觉比较重要和常用的非格助词的其他助词的语法清单可以查看&lt;a href=&quot;#IDX_X&quot;&gt;速查表&lt;/a&gt;。本章节接下来的内容会选择一些非格助词的差异点和难点进行解说。&lt;/p&gt;
&lt;h4 id=&quot;891-て-的细节中顿ないて&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#891-%E3%81%A6-%E7%9A%84%E7%BB%86%E8%8A%82%E4%B8%AD%E9%A1%BF%E3%81%AA%E3%81%84%E3%81%A6&quot; aria-label=&quot;891 て 的细节中顿ないて permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.9.1 て 的细节：中顿、ない+て&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;动词连用形+て 与 动词连用形 表示中顿用法的异同&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在表示&lt;code class=&quot;language-text&quot;&gt;一个动作主体&lt;/code&gt;的动作的&lt;code class=&quot;language-text&quot;&gt;先后关系&lt;/code&gt;时，“动词连用形+て”这种形式要求前后两个动作或者都是意志动作，或者都是无意志动作。而动词连用形表示中顿时则不受这些条件的限制，前后两项可以都是意志动作或都不是意志动作，也可以其中之是意志动作而另一个不是意志动作。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 彼女は家に帰り(O 帰っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;)、食事の用意にとりかかった。/她回到家，开始准备做饭，（前后两项都是意志动作)&lt;/li&gt;
&lt;li&gt;O 田中さんは飛行場に着さ(O 着い&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;)、荷物の検察をうけた。/田中到达了机场接受了行李检查。（前后两项都是无意志动作）&lt;/li&gt;
&lt;li&gt;O 田中さんは飛行場に着さ（？着い&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;）、家に電話をした。/田中到了机场，给家里挂了电话。（“着く”是无意志动作，“電話をする”是意志动作）&lt;/li&gt;
&lt;li&gt;O わたしは野村に偶然に会い（？会っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;）、その話をした。/我偶然遇见了野村，讲了那件事。（偶然に会う”是无意志动作，“その話をする”是意志动作）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在&lt;code class=&quot;language-text&quot;&gt;并列两个动作主体&lt;/code&gt;进行的两个动作时，“动词连用形+て”要求前后两个动作必须都是有意识进行的动作，动词连用形表示中顿时可以都是有意识进行的动作，也可以都是无意中出现的动作。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 太郎が東大にはいり（O はいっ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;）、次郎は早大にはいった。/太郎进了东京大学，次郎进了早稻田大学，(前后都是意志动作)&lt;/li&gt;
&lt;li&gt;O 太郎は帽子をとられ(? とられ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;）、次郎は服を破られた。/太郎帽子被拿走了，次郎衣服被撕破了。（前后都是无意志动作）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;表示同&lt;code class=&quot;language-text&quot;&gt;一个动作主体&lt;/code&gt;进行的两个动作，而这两个&lt;code class=&quot;language-text&quot;&gt;不是先后发生&lt;/code&gt;的动作时，可以用动词连用形表示中顿的形式。很少用“动词连用形+て“的形式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 弟はスケートもやり(X やっ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;)、スキーもやる。/弟弟既滑冰又滑雪&lt;/li&gt;
&lt;li&gt;O 李さんは日本語もでき(? でき&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;)、英語もわかる。/小李既会日语又懂英语&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;另外，“动词连用形+て”多用于口语中，动词连用形表示中顿多于书面语。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;“なくて”的主要用法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“なくて“连接的前后两项是相对立的事物。
&lt;ul&gt;
&lt;li&gt;O 雨が降ら&lt;code class=&quot;language-text&quot;&gt;なくて&lt;/code&gt;、雪が降った。/不下雨，下雪了&lt;/li&gt;
&lt;li&gt;O あの人は何もして&lt;code class=&quot;language-text&quot;&gt;なくて&lt;/code&gt;、みんなやったのは私です。/那个人什么也不千，都是我做的。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;“て“表示原因、理由或以“ては”的形式表示假定条件。
&lt;ul&gt;
&lt;li&gt;O うまく説明でき&lt;code class=&quot;language-text&quot;&gt;なくて&lt;/code&gt;、困った。/不能很好地说明，真为难。&lt;/li&gt;
&lt;li&gt;O 雨が降ら&lt;code class=&quot;language-text&quot;&gt;なくては&lt;/code&gt;田も植えられない。/不下雨的话，就种不了田（插不了秧）。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;“ないで”的主要用法&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后接补助用言
&lt;ul&gt;
&lt;li&gt;O 何も聞か&lt;code class=&quot;language-text&quot;&gt;ないで&lt;/code&gt;ください。/请什么都别问。&lt;/li&gt;
&lt;li&gt;O 何もし&lt;code class=&quot;language-text&quot;&gt;ないで&lt;/code&gt;いてみよう。/试一试什么都不做。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;前项修饰后项
&lt;ul&gt;
&lt;li&gt;O あの人は、人の言うことを聞か&lt;code class=&quot;language-text&quot;&gt;ないで&lt;/code&gt;出て行った。/那个人也不听别人说什么就出去了。&lt;/li&gt;
&lt;li&gt;O 雨が降っているのに傘も差さ&lt;code class=&quot;language-text&quot;&gt;ないで&lt;/code&gt;步いている。/下着雨，可是却没打伞走在雨中。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果既可以认为前项与后项是相对立的事物，又可以认为前项修饰后项的时候，则二者都可以用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 雨が降ら&lt;code class=&quot;language-text&quot;&gt;なくて&lt;/code&gt;、雪が降った。/不下雨，下雪了。&lt;/li&gt;
&lt;li&gt;O 雨が降ら&lt;code class=&quot;language-text&quot;&gt;ないで&lt;/code&gt;、雪が降った。/不下雨而下雪了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;892-ながら&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#892-%E3%81%AA%E3%81%8C%E3%82%89&quot; aria-label=&quot;892 ながら permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.9.2 ながら&lt;/h4&gt;
&lt;p&gt;在表示动作同时进行时，“ながら”要求同时进行或同时存在的两个动作的主体是&lt;code class=&quot;language-text&quot;&gt;同一个主体&lt;/code&gt;，并且表示两个动作的动词应是&lt;code class=&quot;language-text&quot;&gt;动作性动词&lt;/code&gt;而不是状态动词。在前后是同一主体，且前后动词都是动作性动词时，也要注意，瞬间动词一般是不后续“ながら”的。&lt;/p&gt;
&lt;p&gt;下面这几个例句是错误的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;X 雨が降ってい&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、風が吹いています。（不是同一主体）&lt;/li&gt;
&lt;li&gt;X 喫茶店から音楽が聞こえ&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、みんなコーヒーを飲んでいます。（“聞こえる”是状态词）&lt;/li&gt;
&lt;li&gt;X 電車に乗り&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;新聞を読む。（“（電車に）乗る”是瞬间动词）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同时进行或同时存在的两个动作，在有的句子中，前项和后项互换意思上也没有太大的差异，如&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 音楽を聞き&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、コーヒーを飲む。&lt;/li&gt;
&lt;li&gt;O コーヒーを飲み&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、音楽を聞く。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但是，一般地说，“ながら”句型的重点在后项，前项修饰、限定后项，从逻辑上说，前项从属于后项。因此打破了这种关系的句子就显得不自然。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;X バスを待ち&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、体が寒さにふるえてしまった。&lt;/li&gt;
&lt;li&gt;O 寒さにふるえ&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、バスを待つ。&lt;/li&gt;
&lt;li&gt;X 部屋へ帰って休み&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、コーヒーを飲む。&lt;/li&gt;
&lt;li&gt;O コーヒーを飲み&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;、休む。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;893-てもでも-连续助词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#893-%E3%81%A6%E3%82%82%E3%81%A7%E3%82%82-%E8%BF%9E%E7%BB%AD%E5%8A%A9%E8%AF%8D&quot; aria-label=&quot;893 てもでも 连续助词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.9.3 ても/でも 连续助词&lt;/h4&gt;
&lt;p&gt;在口语中，“ても”接在形容词或形容词型活用助动词后面时可以说成“っても”以表示强调&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 寒くっ&lt;code class=&quot;language-text&quot;&gt;ても&lt;/code&gt;平気です。/即使冷,也不要景。&lt;/li&gt;
&lt;li&gt;O 国へ帰りたくっ&lt;code class=&quot;language-text&quot;&gt;ても&lt;/code&gt;ニ年間は帰らないつもりです。/即使想回国，两年内也不准备回国。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;“っても”还可以接在用言或助动词终止形后面，但这是“~と言っても”的缩略形式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 帰るっ&lt;code class=&quot;language-text&quot;&gt;ても&lt;/code&gt;、今からではもう遅い。/即使说要回去,现在也晚了。&lt;/li&gt;
&lt;li&gt;O 暑いっ&lt;code class=&quot;language-text&quot;&gt;ても&lt;/code&gt;、私の国に比べれば、それほどではありません。/说这儿热，可和我们国家相比，就不算多热。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;894-でも-提示助词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#894-%E3%81%A7%E3%82%82-%E6%8F%90%E7%A4%BA%E5%8A%A9%E8%AF%8D&quot; aria-label=&quot;894 でも 提示助词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.9.4 でも 提示助词&lt;/h4&gt;
&lt;p&gt;提示助词“でも”与“格助词で+提示助词も”的区分有时并不十分明显。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A: デバート&lt;code class=&quot;language-text&quot;&gt;では&lt;/code&gt;売っていませんか。/在百货商店里没有卖的吗?&lt;/li&gt;
&lt;li&gt;B: デバート&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;売っていますよ。/在百货商店里也有卖的呀。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上句中的“でも”一般认为是“格助调で+提示助词も”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O これなら田舎&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;売っています。/如果是这个的话,乡下也有卖的。&lt;/li&gt;
&lt;li&gt;O このごろのラジオは感度がよくて、山の中&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;よく聞こえる。/现在的收音机接收信号好，即使在山里面也能听清楚。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两句中的“でも”就很难说清是提出极端事例的提示助词，还是“格助词で+提示助词も”。当然，如果上例中“でも”前有“で“，那么就很明确了，是“格助词で+提示助词でも”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O これなら田舎で&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;売っています。/如果是这个的话,乡下都有卖的。&lt;/li&gt;
&lt;li&gt;O このごろのラジオは感度がよくて、山の中で&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;よく聞こえる。/现在的收音机接收信号好，即使在山里面也能听清楚。&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;895-とか&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#895-%E3%81%A8%E3%81%8B&quot; aria-label=&quot;895 とか permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.9.5 とか&lt;/h4&gt;
&lt;p&gt;对并列助词“とか”和格助词“と”与副助词“か”叠用的“とか”需要加以区别。&lt;/p&gt;
&lt;p&gt;叠用起来的“とか”中的“と”是表示称谓、叙述的内容的，因此多和“言う”“話す”等词一起使用。下面的例子均是格助词“と“和副助词“か”叠用的“とか”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;O 木村さん&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;いう方から電話がありました。/有个好象叫木村的打来过电话。&lt;/li&gt;
&lt;li&gt;O ガラスのドアにひびが入っている&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;言っている。/说什么玻璃门上有了裂纹。&lt;/li&gt;
&lt;li&gt;O 行く&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;行かない&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;いって、ぐずぐずしているんですよ。/又说去又说不去的，在那儿犹豫着呢。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;810-补助形容词&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#810-%E8%A1%A5%E5%8A%A9%E5%BD%A2%E5%AE%B9%E8%AF%8D&quot; aria-label=&quot;810 补助形容词 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.10 补助形容词&lt;/h3&gt;
&lt;p&gt;在语法讲解中也较常出现：接在其它用言后起补助作用的形容词叫作补助形容词。补助形容词有“ない“、“ほしい”、“いい (よい)“。主要用法是接在&lt;code class=&quot;language-text&quot;&gt;て/で&lt;/code&gt;之后。&lt;/p&gt;
&lt;h2 id=&quot;x-速查表&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#x-%E9%80%9F%E6%9F%A5%E8%A1%A8&quot; aria-label=&quot;x 速查表 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X. 速查表&lt;/h2&gt;
&lt;h3 id=&quot;xi-体时态&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xi-%E4%BD%93%E6%97%B6%E6%80%81&quot; aria-label=&quot;xi 体时态 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.I 体时态&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_I&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| 分类 | 表达 | 例句 | 注解&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:--- | :--- | :--- | :--- | :---
体 | &lt;span style=&quot;color:#41E0F5&quot;&gt;持续体&lt;/span&gt; | ている | 今、市内の病院で&lt;code class=&quot;language-text&quot;&gt;働いている&lt;/code&gt; | 视点在动作持续或反复的过程中，无起始和终止
体 | &lt;span style=&quot;color:#41E0F5&quot;&gt;持续体&lt;/span&gt; | てくる | とにかく私は&lt;code class=&quot;language-text&quot;&gt;苦労してき&lt;/code&gt;た | 同ている，但明确了发话时间，常用过去时
体 | &lt;span style=&quot;color:#41E0F5&quot;&gt;持续体&lt;/span&gt; | ていく | この子は私ー人の力で&lt;code class=&quot;language-text&quot;&gt;育てていき&lt;/code&gt;ます | 同ている，但明确了发话时间，常用非过去时
体 | &lt;span style=&quot;color:#41E0F5&quot;&gt;持续体&lt;/span&gt; | つつある | 世界は変わりつつある(瞬间)&lt;br&gt;台風はゆっくり北上しつつある(继续) | 渐进性持续，多是瞬间动词&lt;br&gt;也可是继续动词，但不常见
体 | &lt;span style=&quot;color:#F5B041&quot;&gt;存续体&lt;/span&gt; | ている | 井上先生はいま中国に&lt;code class=&quot;language-text&quot;&gt;行っている&lt;/code&gt;&lt;br&gt;桜の木が&lt;code class=&quot;language-text&quot;&gt;枯れている&lt;/code&gt; | “瞬间动词+ている”构成状态存续意义的存续体&lt;br&gt;这种方式构成的存续体，表明动作行为已经发生，&lt;br&gt;但它所造成的状态仍然存在
体 | &lt;span style=&quot;color:#F5B041&quot;&gt;存续体&lt;/span&gt; | ている | 井上先生は中国に何回も&lt;code class=&quot;language-text&quot;&gt;行っている&lt;/code&gt; | “动词+ている”还可以表示人们的经历、事件的记录
体 | &lt;span style=&quot;color:#F5B041&quot;&gt;存续体&lt;/span&gt; | てある | 窸が&lt;code class=&quot;language-text&quot;&gt;開けてある&lt;/code&gt; | 他动词后，过去动作、行为的结果还保留着
体 | 完成体 | てしまう | この小説を今週中に&lt;code class=&quot;language-text&quot;&gt;読んでしまう&lt;/code&gt;&lt;br&gt;きれいに財産を&lt;code class=&quot;language-text&quot;&gt;使っちゃう&lt;/code&gt; | 连用形+てしまう&lt;br&gt;可约音成“ちゃう”或“ちまう”
体 | 准备体 | ておく | 自転車はもう&lt;code class=&quot;language-text&quot;&gt;買っておい&lt;/code&gt;た | 连用形+ておく&lt;br&gt;必须是意志动词
体 | 即将体 | - | 式は間もなく&lt;code class=&quot;language-text&quot;&gt;終わろうとしている&lt;/code&gt;&lt;br&gt;もう食べる&lt;code class=&quot;language-text&quot;&gt;ばかりになっている&lt;/code&gt;&lt;br&gt;出かけるところだ&lt;br&gt;彼女は今にも&lt;code class=&quot;language-text&quot;&gt;溺れそうだった&lt;/code&gt; | ~う (よう）とする&lt;br&gt;~するばかりだ&lt;br&gt;~するところだ&lt;br&gt;~そうだ
体 | 起始体 | - | 学生たちは解答を&lt;code class=&quot;language-text&quot;&gt;書き始めた&lt;/code&gt;&lt;br&gt;止まっていたバスが&lt;code class=&quot;language-text&quot;&gt;動き出し&lt;/code&gt;た&lt;br&gt;雨が&lt;code class=&quot;language-text&quot;&gt;降ってき&lt;/code&gt;た | 意志/非意志+始める&lt;br&gt;非意志+出す&lt;br&gt;~てくる：事态出现变化，即开始
时 | &lt;span style=&quot;color:#0C8FFF&quot;&gt;非过去&lt;/span&gt; | 确定将来 | 明日必ず&lt;code class=&quot;language-text&quot;&gt;行きます&lt;/code&gt; | 继续动词和瞬间动词的非过去时形态
时 | &lt;span style=&quot;color:#0C8FFF&quot;&gt;非过去&lt;/span&gt; | 反复行为&lt;br&gt;现在 | 毎日指を折って椅子の数を&lt;code class=&quot;language-text&quot;&gt;数える&lt;/code&gt;&lt;br&gt;夜、料理クラスへ&lt;code class=&quot;language-text&quot;&gt;通っている&lt;/code&gt; | 继续动词和动词持续体非过去时形式，&lt;br&gt;均可表示现在反复进行的或习惯性的动作、行为
时 | &lt;span style=&quot;color:#0C8FFF&quot;&gt;非过去&lt;/span&gt; | 现在状态 | 花子さんは飛行機の操縱が&lt;code class=&quot;language-text&quot;&gt;できる&lt;/code&gt;&lt;br&gt;池までの小径が&lt;code class=&quot;language-text&quot;&gt;曲がっている&lt;/code&gt;&lt;br&gt;隣の犬が&lt;code class=&quot;language-text&quot;&gt;死んでいる&lt;/code&gt; | 状态动词、动词存续体形容词性动词+ている&lt;br&gt;的非过去时形式，均表示现存的状态
时 | &lt;span style=&quot;color:#0C8FFF&quot;&gt;非过去&lt;/span&gt; | 概念真理 | 地球が&lt;code class=&quot;language-text&quot;&gt;回る&lt;/code&gt; | 表示超越时间观念的概念、规律、真理、说明等
时 | &lt;span style=&quot;color:#BD00F9&quot;&gt;过去时&lt;/span&gt; | 过去行为 | 昨日ここで交通事故が&lt;code class=&quot;language-text&quot;&gt;起った&lt;/code&gt; | 过去某个时刻的行为，用“动态动词连用形+た”表示
时 | &lt;span style=&quot;color:#BD00F9&quot;&gt;过去时&lt;/span&gt; | 反复行为&lt;br&gt;过去 | 昔はよくここで&lt;code class=&quot;language-text&quot;&gt;泳いだ&lt;/code&gt;&lt;br&gt;暇な時は山登りに&lt;code class=&quot;language-text&quot;&gt;行った&lt;/code&gt;ものだ | 用“动态动词连用形+た”或动词持续体的过去时表示，&lt;br&gt;有回忆的意味
时 | &lt;span style=&quot;color:#BD00F9&quot;&gt;过去时&lt;/span&gt; | 过去状态 | 三日前はこの窓ガラスが&lt;code class=&quot;language-text&quot;&gt;割れていた&lt;/code&gt;&lt;br&gt;昔、ここにはたくさんの湖が&lt;code class=&quot;language-text&quot;&gt;あった&lt;/code&gt;&lt;br&gt;以前太っていたが、最近&lt;code class=&quot;language-text&quot;&gt;やせてきた&lt;/code&gt; | 用“状态动词连用形+た”、瞬间动词的存续体过去时、&lt;br&gt;“形容词性动词+ていた”表示
态 | &lt;span style=&quot;color:#74E302&quot;&gt;被动态&lt;/span&gt; | 直接被动 | 太郎が次郎に英語を教える(主动)&lt;br&gt;次郎が太郎に英語を&lt;code class=&quot;language-text&quot;&gt;教えられる&lt;/code&gt;&lt;br&gt;王さんが李さんに辞書を渡す(主动)&lt;br&gt;李さんが王さんから辞書を&lt;code class=&quot;language-text&quot;&gt;渡され&lt;/code&gt;た | 可以还原为主动句来说明&lt;br&gt;构成直接被动态的动词&lt;code class=&quot;language-text&quot;&gt;都是``他动词&lt;/code&gt;&lt;br&gt;“~に”格成分看作人物宾语&lt;br&gt;“~を”格成分看作事物宾语
态 | &lt;span style=&quot;color:#74E302&quot;&gt;被动态&lt;/span&gt; | 间接被动 | 私は帰る途中、雨に&lt;code class=&quot;language-text&quot;&gt;降られ&lt;/code&gt;た(自动)&lt;br&gt;幼い時に、父に&lt;code class=&quot;language-text&quot;&gt;死なれ&lt;/code&gt;た(自动)&lt;br&gt;電車の中で足を&lt;code class=&quot;language-text&quot;&gt;踏まれ&lt;/code&gt;た(他动)&lt;br&gt;電車の中で(誰かが)足を&lt;code class=&quot;language-text&quot;&gt;踏んだ&lt;/code&gt;(主动句) | 间接被动句主语不是动作的直接承受者，&lt;br&gt;而是间接地受到与之没有直接关系的事情的影响&lt;br&gt;分为&lt;code class=&quot;language-text&quot;&gt;自动词&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;他动词&lt;/code&gt;的间接被动句&lt;br&gt;自动词的间接被动句&lt;code class=&quot;language-text&quot;&gt;无法&lt;/code&gt;还原成主动句
态 | &lt;span style=&quot;color:#06CE9F&quot;&gt;使动态&lt;/span&gt; | - | 先生が&lt;code class=&quot;language-text&quot;&gt;彼に&lt;/code&gt;論文を書かせる(他动命令)&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;彼に&lt;/code&gt;かってに言わせておこう(他动放任)&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;子どもを&lt;/code&gt;9時までに寝させる(自动强制)&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;子どもに&lt;/code&gt;一人で大通りを&lt;br&gt;渡らせるのは危ない(自动放任) | 他动词，使动对象都用“に”&lt;br&gt;自动词，强制性用“を”，非强制性用“に”
态 | &lt;span style=&quot;color:#06CE9F&quot;&gt;使动态&lt;/span&gt; | 被使动态 | (弟が借りた)借金を&lt;code class=&quot;language-text&quot;&gt;払わせられ&lt;/code&gt;た | 是使动态的被动态&lt;br&gt;行为不是自觉主动的，而是被迫的、不情愿的
态 | 可能态 | - | 日本語&lt;code class=&quot;language-text&quot;&gt;を話すことができる&lt;/code&gt;&lt;br&gt;日本語&lt;code class=&quot;language-text&quot;&gt;が話せる&lt;/code&gt;&lt;br&gt;調子が悪くて、私&lt;code class=&quot;language-text&quot;&gt;には&lt;/code&gt;大声で話せない | 惯用型“~ことができる”不发生对象的格的转换&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;可能对象&lt;/code&gt;用格助词“が”表示&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;能动主体&lt;/code&gt;有时用格助词“に”表示
态 | 自发态 | - | 雪が降ると、故郷のことが&lt;code class=&quot;language-text&quot;&gt;思い出される&lt;/code&gt;&lt;br&gt;故郷を&lt;code class=&quot;language-text&quot;&gt;思い出す&lt;/code&gt;と、勇気が出る | &lt;code class=&quot;language-text&quot;&gt;动作对象&lt;/code&gt;如果出现，也可以是“が”的形式&lt;br&gt;表示不由自主地产生某种行为或结果，与人为动作不同&lt;/p&gt;
&lt;h3 id=&quot;xii-动词活用形&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xii-%E5%8A%A8%E8%AF%8D%E6%B4%BB%E7%94%A8%E5%BD%A2&quot; aria-label=&quot;xii 动词活用形 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.II 动词活用形&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_II&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;活用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;用例&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范式&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;雨が&lt;code class=&quot;language-text&quot;&gt;降らない&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;使役&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;させる (せる）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;弟を買い物に&lt;code class=&quot;language-text&quot;&gt;行かせ&lt;/code&gt;た。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;被动&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;られる (れる）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;彼は父に&lt;code class=&quot;language-text&quot;&gt;叱られ&lt;/code&gt;た。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;可能&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;られる (れる）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;それは&lt;code class=&quot;language-text&quot;&gt;食べられる&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;尊敬&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;られる (れる）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;先生が&lt;code class=&quot;language-text&quot;&gt;帰られ&lt;/code&gt;た。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;意志和推测&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;う(よう)&lt;br&gt;一段动词和サ变动词+まい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;粘土で人形を&lt;code class=&quot;language-text&quot;&gt;作ろう&lt;/code&gt;。&lt;br&gt;あんなばかなことは二度と&lt;code class=&quot;language-text&quot;&gt;しまい&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;构词用法&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;動き&lt;/code&gt;が激しい&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;使い&lt;/code&gt;道&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;流れ&lt;/code&gt;込む&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;聞き&lt;/code&gt;辛い&lt;br&gt;魔法&lt;code class=&quot;language-text&quot;&gt;使い&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;中顿&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;流れは山を&lt;code class=&quot;language-text&quot;&gt;下り&lt;/code&gt;、谷を&lt;code class=&quot;language-text&quot;&gt;走り&lt;/code&gt;、野をよこぎる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接助动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ます 敬体&lt;br&gt;た 过去、完了、状态等&lt;br&gt;たい、たがる 愿望&lt;br&gt;そうだ 可能性&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;僕は君の幸せを&lt;code class=&quot;language-text&quot;&gt;望みます&lt;/code&gt;。&lt;br&gt;やっばり、かぎはここに&lt;code class=&quot;language-text&quot;&gt;あった&lt;/code&gt;。&lt;br&gt;今度は立派な論文を&lt;code class=&quot;language-text&quot;&gt;書きたい&lt;/code&gt;。&lt;br&gt;不景気で会社が&lt;code class=&quot;language-text&quot;&gt;つぶれそうだ&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接格助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;に 目的&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;朝早く鮭を&lt;code class=&quot;language-text&quot;&gt;釣りに&lt;/code&gt;行った。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接接续助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;て&lt;br&gt;ながら&lt;br&gt;つつ&lt;br&gt;ても&lt;br&gt;たって&lt;br&gt;ては&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;春が&lt;code class=&quot;language-text&quot;&gt;来て&lt;/code&gt;、雪が溶けた。&lt;br&gt;友と&lt;code class=&quot;language-text&quot;&gt;語りつつ&lt;/code&gt;酒を飲む。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接并列助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;たり&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ー日中&lt;code class=&quot;language-text&quot;&gt;踊ったり&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;歌ったり&lt;/code&gt;した。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接提示助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;は&lt;br&gt;も&lt;br&gt;でも&lt;br&gt;さえ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;御恩は決して&lt;code class=&quot;language-text&quot;&gt;忘れは&lt;/code&gt;しない。&lt;br&gt;駅の案内を人々はほとんど&lt;code class=&quot;language-text&quot;&gt;聞きも&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;見も&lt;/code&gt;しません。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接语气助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;な&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;危ないから、気を&lt;code class=&quot;language-text&quot;&gt;つけな&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;结句&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;この花はいい匂いが&lt;code class=&quot;language-text&quot;&gt;する&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接助动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;そうだ&lt;br&gt;らしい&lt;br&gt;だろう (でしょう）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;彼は留学の許可を得るため両親を&lt;code class=&quot;language-text&quot;&gt;説得するそうだ&lt;/code&gt;。&lt;br&gt;新人を入れてチームの若返しを&lt;code class=&quot;language-text&quot;&gt;図るらしい&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接助动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;五段动词和サ变动词+まい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;わざわざ嵐の中で登山をするものは&lt;code class=&quot;language-text&quot;&gt;あるまい&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接并列助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;か&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;行くか&lt;/code&gt;行かないか迷っている。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接语气助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;か&lt;br&gt;な&lt;br&gt;ね&lt;br&gt;よ&lt;br&gt;なぁ&lt;br&gt;さ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;転んだくらいで泣く奴が&lt;code class=&quot;language-text&quot;&gt;あるか&lt;/code&gt;。&lt;br&gt;急ぐから、僕はもう&lt;code class=&quot;language-text&quot;&gt;帰るよ&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接接续助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;が&lt;br&gt;けれども&lt;br&gt;と&lt;br&gt;から&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;私は車の連転が&lt;code class=&quot;language-text&quot;&gt;できるが&lt;/code&gt;、兄はできない。&lt;br&gt;会社は今危機に&lt;code class=&quot;language-text&quot;&gt;あるけれども&lt;/code&gt;、つぶれないと思う。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接体言&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;作为定语&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;流れる水&lt;/code&gt;と&lt;code class=&quot;language-text&quot;&gt;噴き上げる水&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接助动词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ようだ&lt;br&gt;みたいだ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;彼も最近新しい機械を工夫して&lt;code class=&quot;language-text&quot;&gt;いるみたいだ&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接接续助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ので&lt;br&gt;のに&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;日本語だけで十分に&lt;code class=&quot;language-text&quot;&gt;表せるのに&lt;/code&gt;、なぜ…&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接副助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;だけ&lt;br&gt;くらい&lt;br&gt;ほど&lt;br&gt;ばかり&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;人生には、&lt;code class=&quot;language-text&quot;&gt;遭難するぐらい&lt;/code&gt;惨めなことはない。&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;眺めるだけ&lt;/code&gt;なら、お金は要らない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接提示助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しか+否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ここまで来たら、&lt;code class=&quot;language-text&quot;&gt;やるしか&lt;/code&gt;ありません。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接语气助词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;の&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くずぐずしないで、さっさと&lt;code class=&quot;language-text&quot;&gt;するの&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后接形式名词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;こと&lt;br&gt;もの&lt;br&gt;の&lt;br&gt;はず&lt;br&gt;わけ&lt;br&gt;ため&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ここまで来て登山を&lt;code class=&quot;language-text&quot;&gt;中止するわけ&lt;/code&gt;にはいかない。&lt;br&gt;たいていのことは日本語で十分&lt;code class=&quot;language-text&quot;&gt;表せるはず&lt;/code&gt;だ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;假定形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;可能‧条件&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ば&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ちりも&lt;code class=&quot;language-text&quot;&gt;積もれば&lt;/code&gt;山となる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F9001A&quot;&gt;命令形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;命令&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;僕の話を&lt;code class=&quot;language-text&quot;&gt;聞け&lt;/code&gt;！&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;xiii-动词活用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xiii-%E5%8A%A8%E8%AF%8D%E6%B4%BB%E7%94%A8&quot; aria-label=&quot;xiii 动词活用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.III 动词活用&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_III&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;分类&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;活用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;规律&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;变形&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;五段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否定：转&lt;code class=&quot;language-text&quot;&gt;あ&lt;/code&gt;段&lt;br&gt;推量：转&lt;code class=&quot;language-text&quot;&gt;お&lt;/code&gt;段&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いか・ない&lt;br&gt;いこ・う&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;五段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;段&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いき・ます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;五段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;五段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连体形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行くこと&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;五段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;假定形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转&lt;code class=&quot;language-text&quot;&gt;え&lt;/code&gt;段&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いけ・ば&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;五段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;命令形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转&lt;code class=&quot;language-text&quot;&gt;え&lt;/code&gt;段&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;行く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いけ！&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;一段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去&lt;code class=&quot;language-text&quot;&gt;る&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・ない&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;一段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去&lt;code class=&quot;language-text&quot;&gt;る&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・ます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;一段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;一段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连体形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見ること&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;一段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;假定形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;る&lt;/code&gt;换&lt;code class=&quot;language-text&quot;&gt;れ&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・れば&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;一段&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;命令形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;る&lt;/code&gt;换&lt;code class=&quot;language-text&quot;&gt;ろ/よ&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;見る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み・ろ/よ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;サ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干加&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強し・ない/よう&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;サ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干加&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強し・ましょう&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;サ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;サ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连体形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強すること&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;サ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;假定形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干加&lt;code class=&quot;language-text&quot;&gt;すれば&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強・すれば&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;サ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;命令形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干加&lt;code class=&quot;language-text&quot;&gt;しろ/せよ&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強する&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強・しろ/せよ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;カ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;未然形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;こ・ない/よう&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;カ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连用形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;き・ます&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;カ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;终止形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;カ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;连体形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くること&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;カ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;假定形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くれば&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;カ变&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;命令形&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;来る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;こい&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;xiv-动词音便&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xiv-%E5%8A%A8%E8%AF%8D%E9%9F%B3%E4%BE%BF&quot; aria-label=&quot;xiv 动词音便 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.IV 动词音便&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_IV&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;只限：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;五段动词&lt;/li&gt;
&lt;li&gt;连用形
&lt;ul&gt;
&lt;li&gt;后接助动词&lt;code class=&quot;language-text&quot;&gt;た&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;或&lt;/li&gt;
&lt;li&gt;后接续助词&lt;code class=&quot;language-text&quot;&gt;て、ては、たも、たん、たって&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;分类&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;尾音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;规律&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;原形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;连用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;变形&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;促音便&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;う&lt;br&gt;つ&lt;br&gt;る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转促音&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;使う&lt;br&gt;待つ&lt;br&gt;乗る&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;使い&lt;br&gt;待ち&lt;br&gt;乗り&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;つか&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;・て&lt;br&gt;ま&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;・た&lt;br&gt;の&lt;code class=&quot;language-text&quot;&gt;っ&lt;/code&gt;・て&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;拨音便&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ぬ&lt;br&gt;ぶ&lt;br&gt;む&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;后假名&lt;code class=&quot;language-text&quot;&gt;浊化&lt;/code&gt;&lt;br&gt;て → で、た → だ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;死ぬ&lt;br&gt;呼ぶ&lt;br&gt;飲む&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;死に&lt;br&gt;呼び&lt;br&gt;飲み&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;し&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;&lt;br&gt;よ&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;だ&lt;/code&gt;&lt;br&gt;の&lt;code class=&quot;language-text&quot;&gt;ん&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;イ音便&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;く&lt;br&gt;ぐ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;ぎ&lt;/code&gt;的情况い后假名&lt;code class=&quot;language-text&quot;&gt;浊化&lt;/code&gt;&lt;br&gt;て → で、た → だ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;書く&lt;br&gt;嗅ぐ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;書き&lt;br&gt;嗅ぎ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;か&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;・て&lt;br&gt;か&lt;code class=&quot;language-text&quot;&gt;い&lt;/code&gt;・&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;xv-形容词活用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xv-%E5%BD%A2%E5%AE%B9%E8%AF%8D%E6%B4%BB%E7%94%A8&quot; aria-label=&quot;xv 形容词活用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.V 形容词活用&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_V&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;活用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;规律&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い +&lt;br&gt;かろ+推量助动词う&lt;br&gt;かった（过去式）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;京都の桜は美し&lt;code class=&quot;language-text&quot;&gt;かろう&lt;/code&gt;。&lt;br&gt;昨日はとっても楽し&lt;code class=&quot;language-text&quot;&gt;かった&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い + く +&lt;br&gt;名词/副词&lt;br&gt;て（中止接续）&lt;br&gt;ない（否定）&lt;br&gt;なる（表变化）&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味し&lt;code class=&quot;language-text&quot;&gt;くて&lt;/code&gt;たまらない。&lt;br&gt;彼女は全然美し&lt;code class=&quot;language-text&quot;&gt;くない&lt;/code&gt;。&lt;br&gt;だんだん暑&lt;code class=&quot;language-text&quot;&gt;くなる&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しい&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;美味しいご飯&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;假定形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い + ければ + ···&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;楽し&lt;code class=&quot;language-text&quot;&gt;ければ&lt;/code&gt;···&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;xvi-形容词语法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xvi-%E5%BD%A2%E5%AE%B9%E8%AF%8D%E8%AF%AD%E6%B3%95&quot; aria-label=&quot;xvi 形容词语法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.VI 形容词语法&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_VI&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;活用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;规则&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语法作用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+かろ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表示推测&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;奨学金だけでは生活が&lt;code class=&quot;language-text&quot;&gt;苦しかろ&lt;/code&gt;う。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;用言前作状语&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いつものように、&lt;code class=&quot;language-text&quot;&gt;つまらなく&lt;/code&gt;家に帰った。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+くなる&lt;br&gt;去い+くする&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表变化&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;なる类似自动词，表自然变化：&lt;br&gt;人口が増え、市場も&lt;code class=&quot;language-text&quot;&gt;大きく&lt;/code&gt;なった。&lt;br&gt;する类似他动词，表人为变化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+く&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;中顿&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;お父さんは、僕たちに&lt;code class=&quot;language-text&quot;&gt;きびしく&lt;/code&gt;やさしくて、とても心が広かった。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+くない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;日本料理は明るい所で白ちゃけた器で食べては&lt;code class=&quot;language-text&quot;&gt;うまく&lt;/code&gt;ない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+くて&lt;br&gt;去い+くても&lt;br&gt;去い+くては&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表并列&lt;br&gt;表原因&lt;br&gt;表转折&lt;br&gt;表条件&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;大きく&lt;/code&gt;て、&lt;code class=&quot;language-text&quot;&gt;薄く&lt;/code&gt;て楽しそうな絵がいっばい。&lt;br&gt;天気が&lt;code class=&quot;language-text&quot;&gt;悪く&lt;/code&gt;てほとんど泳げなかった。&lt;br&gt;どんなに&lt;code class=&quot;language-text&quot;&gt;寒く&lt;/code&gt;ても・・・&lt;br&gt;あんなに&lt;code class=&quot;language-text&quot;&gt;やかましく&lt;/code&gt;ては、話もよく聞きとれないだろう。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+くは&lt;br&gt;去い+くも&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;增添语法意义&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ここから見るとそんなに&lt;code class=&quot;language-text&quot;&gt;高く&lt;/code&gt;は感じられません。&lt;br&gt;僕は&lt;code class=&quot;language-text&quot;&gt;若く&lt;/code&gt;もなく、ハンサムでもない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+かった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表过去完了&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;高原に春の訪れは&lt;code class=&quot;language-text&quot;&gt;遅かっ&lt;/code&gt;た。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+かったり&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表并列&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;値段は&lt;code class=&quot;language-text&quot;&gt;高かっ&lt;/code&gt;たり、&lt;code class=&quot;language-text&quot;&gt;安かっ&lt;/code&gt;たりして、季節によって違います。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;作谓语结句&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;最近のたばこは昔のに比べるとずいぶん&lt;code class=&quot;language-text&quot;&gt;やわらかい&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+から&lt;br&gt;+けれども&lt;br&gt;+し&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表原因&lt;br&gt;表转折&lt;br&gt;中顿&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今度のお客さまは食べ物に&lt;code class=&quot;language-text&quot;&gt;うるさい&lt;/code&gt;から、よくよく注意しなさい。&lt;br&gt;咲いているあいだは&lt;code class=&quot;language-text&quot;&gt;美しい&lt;/code&gt;けれども、枯れると汚いね。&lt;br&gt;頭も&lt;code class=&quot;language-text&quot;&gt;痛い&lt;/code&gt;し、手足も&lt;code class=&quot;language-text&quot;&gt;だるい&lt;/code&gt;し、少し目まいもする。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+か&lt;br&gt;+よ/ね&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表疑问&lt;br&gt;表语气&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ひどく&lt;code class=&quot;language-text&quot;&gt;痛い&lt;/code&gt;か。&lt;br&gt;映画より小説のほうが&lt;code class=&quot;language-text&quot;&gt;面白い&lt;/code&gt;よ/ね。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+そうだ&lt;br&gt;+らしい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表传闻&lt;br&gt;表测助&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;日本の生徒は勉強時間が&lt;code class=&quot;language-text&quot;&gt;少ない&lt;/code&gt;そうだ。&lt;br&gt;ストレスは目に&lt;code class=&quot;language-text&quot;&gt;悪い&lt;/code&gt;らしい。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;体言前作定语&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;強い&lt;/code&gt;日差しが照り付けて、各地で軒並み気温が三十度を超えた。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+の/もの/こと等&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转体言、惯用型&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;語学というものは、とても&lt;code class=&quot;language-text&quot;&gt;楽しい&lt;/code&gt;ものです。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+ので&lt;br&gt;+のに&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表原因&lt;br&gt;表转折&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;山に&lt;code class=&quot;language-text&quot;&gt;近い&lt;/code&gt;ので、昼間はひどく暑い。&lt;br&gt;ふだんは無ロで&lt;code class=&quot;language-text&quot;&gt;おとなしい&lt;/code&gt;のに、・・・&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+だけ&lt;br&gt;+ほど&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表转折&lt;br&gt;表程度&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;勉強が&lt;code class=&quot;language-text&quot;&gt;忙しい&lt;/code&gt;だけに体をいっそう大切にしなければならない。&lt;br&gt;遠くから見ても&lt;code class=&quot;language-text&quot;&gt;眩しい&lt;/code&gt;ほど黄色に輝いているものばかりです。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+ようだ/みたいだ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表比喻&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;やはり本店の方が、&lt;code class=&quot;language-text&quot;&gt;おいしい&lt;/code&gt;ような気がします。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;假定形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去い+ければ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表假定条件&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;天気が&lt;code class=&quot;language-text&quot;&gt;よけれ&lt;/code&gt;ば、スケッチに出かける。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干+名词等&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;构词法&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;近道、大きさ、荒っぽい、真っ暗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;作谓语表感叹&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ああ、&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;。&lt;br&gt;おお、&lt;code class=&quot;language-text&quot;&gt;おそろし&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干+そうだ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表样态&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;苦し&lt;/code&gt;そうに顔をゆがめている。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;xvii-形容动词活用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xvii-%E5%BD%A2%E5%AE%B9%E5%8A%A8%E8%AF%8D%E6%B4%BB%E7%94%A8&quot; aria-label=&quot;xvii 形容动词活用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.VII 形容动词活用&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_VII&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;活用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;规律&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;原形 + ろう(推测)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;綺麗だ&lt;code class=&quot;language-text&quot;&gt;ろう&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ +&lt;br&gt;だった(过去)&lt;br&gt;ではない(否定)&lt;br&gt;に(副词)&lt;br&gt;に成る(になる, 表变化)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;綺麗&lt;code class=&quot;language-text&quot;&gt;ではない&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;不变&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;綺麗だ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ + な + ···&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;綺麗な&lt;code class=&quot;language-text&quot;&gt;もの&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;假定形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ + なら + ···&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;綺麗&lt;code class=&quot;language-text&quot;&gt;なら&lt;/code&gt;···&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;xviii-形容动词语法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xviii-%E5%BD%A2%E5%AE%B9%E5%8A%A8%E8%AF%8D%E8%AF%AD%E6%B3%95&quot; aria-label=&quot;xviii 形容动词语法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.VIII 形容动词语法&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_VIII&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;活用形&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;规则&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语法作用&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;未然形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+だろう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表推测&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みんなで話し合いをしないと&lt;code class=&quot;language-text&quot;&gt;駄目だろ&lt;/code&gt;う。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+で&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;中顿&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;便利で&lt;/code&gt;快適な生活の裏で、増え続けるエネルギー消費。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+で(は/も)ない&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表否定&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あまり&lt;code class=&quot;language-text&quot;&gt;好きで&lt;/code&gt;はないが、さほど&lt;code class=&quot;language-text&quot;&gt;嫌いで&lt;/code&gt;もない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+では&lt;br&gt;去だ+でも&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表假定条件&lt;br&gt;表让步条件&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;話があまり&lt;code class=&quot;language-text&quot;&gt;簡単で&lt;/code&gt;は分りにくいだろうから、少し長くやりましょう。&lt;br&gt;海は&lt;code class=&quot;language-text&quot;&gt;穏やかで&lt;/code&gt;も船で行くのはよそう。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+に&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接用言作状语&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;その内容を&lt;code class=&quot;language-text&quot;&gt;十分に&lt;/code&gt;審査して、業者を決定いたします。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+になる&lt;br&gt;去だ+にする&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表变化&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;なる类似自动词，表客观变化：&lt;br&gt;運動をすることによって、骨が&lt;code class=&quot;language-text&quot;&gt;丈夫に&lt;/code&gt;なった。&lt;br&gt;する类似他动词，表主观变化&lt;br&gt;科学の進歩が人間を&lt;code class=&quot;language-text&quot;&gt;幸福に&lt;/code&gt;することを疑わなかった。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+だった&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表过去完了&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あの山は&lt;code class=&quot;language-text&quot;&gt;有名だっ&lt;/code&gt;たかもしれませんが、今・・・&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;连用形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+だったり&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表并列&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;このへんは時間によって&lt;code class=&quot;language-text&quot;&gt;静かだっ&lt;/code&gt;たり、&lt;code class=&quot;language-text&quot;&gt;にぎやかだっ&lt;/code&gt;たりです。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;作谓语结句&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;詩を書いたり小説を読んだりするのも&lt;code class=&quot;language-text&quot;&gt;倫快だ&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+から&lt;br&gt;+けれども&lt;br&gt;+し&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表原因&lt;br&gt;表转折&lt;br&gt;中顿&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;・・・駅からも遠くて&lt;code class=&quot;language-text&quot;&gt;不便だ&lt;/code&gt;から、引越すことにした。&lt;br&gt;仕事は&lt;code class=&quot;language-text&quot;&gt;困難だ&lt;/code&gt;けれども最後までがんばらなければならない。&lt;br&gt;砂浜も軟らかいし、波も静かで、水も&lt;code class=&quot;language-text&quot;&gt;きれいだ&lt;/code&gt;し、海水浴・・・&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;终止形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;+そうだ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表传闻&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;日本語は全然&lt;code class=&quot;language-text&quot;&gt;だめだ&lt;/code&gt;そうですよ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+な&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接体言作定语&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;弟に、&lt;code class=&quot;language-text&quot;&gt;無邪気な&lt;/code&gt;笑顔が戻っていた。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+なの/こと/もの&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;转体言、惯用型&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;私が&lt;code class=&quot;language-text&quot;&gt;大好きな&lt;/code&gt;のは、自然の美しさです。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+なので&lt;br&gt;去だ+なのに&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表原因&lt;br&gt;表转折&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;和菓子が&lt;code class=&quot;language-text&quot;&gt;好きな&lt;/code&gt;ので、よく和菓子屋さんを探しに行きます。&lt;br&gt;日本語で修士論文を書くのも&lt;code class=&quot;language-text&quot;&gt;大変な&lt;/code&gt;のに、・・・&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+なだけ&lt;br&gt;去だ+なほど&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表转折&lt;br&gt;表程度&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;速やかな&lt;/code&gt;だけでなしに、携帯と操作もはなはだ便利である。&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;不思議な&lt;/code&gt;ほど鮮明に覚えている。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+なようだ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表比喻&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;人間は体に栄養が&lt;code class=&quot;language-text&quot;&gt;必要な&lt;/code&gt;ように心にも栄養がいるのです。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;连体形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+な&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;结句表感叹&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;そんな。&lt;code class=&quot;language-text&quot;&gt;ばかな&lt;/code&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;假定形&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去だ+なら&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表假定条件&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;天候が&lt;code class=&quot;language-text&quot;&gt;順調ならば&lt;/code&gt;航空ショーが行われる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干+名词等&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;构成复合词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;好き嫌い、得意顔、心静か、負けず嫌い&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干+前缀/后缀&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;构成派生词&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;お大事、無器用、もの静か、豊かさ、新鮮み、得意げ、不思議がる&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;作谓语表感叹&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あら、&lt;code class=&quot;language-text&quot;&gt;すてき&lt;/code&gt;!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词干+そうだ&lt;br&gt;词干+らしい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;表样态&lt;br&gt;表推测&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;切符が&lt;code class=&quot;language-text&quot;&gt;大事&lt;/code&gt;そうにしっかり握られていた。&lt;br&gt;日本人はむしろそれが&lt;code class=&quot;language-text&quot;&gt;好き&lt;/code&gt;らしいです。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;仅词干&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;-&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;作名词用&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;子供達に対してつねに&lt;code class=&quot;language-text&quot;&gt;親切&lt;/code&gt;を示すことは、一種の文明です。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;xix-格助词语法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xix-%E6%A0%BC%E5%8A%A9%E8%AF%8D%E8%AF%AD%E6%B3%95&quot; aria-label=&quot;xix 格助词语法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.IX 格助词语法&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_IX&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| 用法 | 范例&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:--- | :--- | :---
&lt;span style=&quot;color:#41E0F5&quot;&gt;が&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后&lt;br&gt;用言连体形后，作惯用：負ける&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;勝ちだ。
&lt;span style=&quot;color:#41E0F5&quot;&gt;が&lt;/span&gt; | 表主语：&lt;br&gt;表示判断、性质、状态、&lt;br&gt;存在、动作、作用等的主体 | 斎藤さん&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;責任者です。(判断)&lt;br&gt;アルバイトの学生はみんな背&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;高い。(状态)&lt;br&gt;南美で大きい地震&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;起こった。(动作)
&lt;span style=&quot;color:#41E0F5&quot;&gt;が&lt;/span&gt; | 表主语：&lt;br&gt;表示好恶、巧拙、能力、&lt;br&gt;愿望、心理活动、需要等对象 | 関西の人は納豆&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;嫌いだ。(好恶)&lt;br&gt;彼は英語&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;話せる。(能力)&lt;br&gt;スポーツ万能の友人&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;うらやましい。(心理活动)
&lt;span style=&quot;color:#41E0F5&quot;&gt;が&lt;/span&gt; | 表定语 | バラは美しい&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;ゆえに、人に摘まれる運命にある。
&lt;span style=&quot;color:#F5B041&quot;&gt;を&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后
&lt;span style=&quot;color:#F5B041&quot;&gt;を&lt;/span&gt; | 表宾语：表示动作直接涉及的对象 | 私は毎朝牛乳&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;飲みます。
&lt;span style=&quot;color:#F5B041&quot;&gt;を&lt;/span&gt; | 表宾语：表示动作造成的直接结果 | 積み木で城&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;つくる。
&lt;span style=&quot;color:#F5B041&quot;&gt;を&lt;/span&gt; | 谓语动词是自动词的使动态时，表示使动的对象 | 息子&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;大学に行かせたい。
&lt;span style=&quot;color:#F5B041&quot;&gt;を&lt;/span&gt; | 表示动作经过的场所或动作离开的地点 | 電車道&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;歩いて来る。&lt;br&gt;東京駅&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;今晚の10時に立ちます。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后&lt;br&gt;在某些惯用说法中可接在用言后
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示存在的场所 | 顔&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;笑いを浮かべた。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示动作或作用的时间 | 3時&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;駅で待ち合わせる。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示动作的目标、着落点 | 修学旅行で関西&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;行った。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示行为、动作所关联、涉及的对象 | 友達&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;パソコンを貨した。&lt;br&gt;この商品&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;手を触れてはいけません。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示动作的目的后续&lt;br&gt;“来る”、“行く”等表示趋向的动词&lt;br&gt;接在动词或形式名词“の”、“ため”后 | 遠くから泳ぎ&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;来た人も多い。&lt;br&gt;北京に行く&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;は、どの汽車に乗ったらいいでしよう。&lt;br&gt;この論文を書き終わるの&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;あと何日かかるだろう。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示理由、原因或依据 | あまりの嬉しさ&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;泣き出した。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示事物或状态变化的结果 | 講堂が会場&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;変わりました。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示比较、评价、比例的基准 | ここは海&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;近いが、山&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;は遠い。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示行为、动作进行的方式、状态 | 駅まで山沿い&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;歩いた。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示主体：&lt;br&gt;表示可能的动词“分かる”、“読める”、“見える”等&lt;br&gt;表示要求的动词、形容词、形容动词“要る”、“欲しい“等&lt;br&gt;表示感情的形容词“嬉しい”、“悲しい”等&lt;br&gt;敬语动词 | 写真ぐらい私&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;も写せます。&lt;br&gt;わたし&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;はお金が必要だ。&lt;br&gt;親友の裏切りが私&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;は悲しい。&lt;br&gt;先生&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;はお変わりなく・・・
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示被动句或使动句中动作的实施者 | ぼくの金魚が猫&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;食われた。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 重叠同一个动词表示强调 | 雨が降り&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;降る。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;に&lt;/span&gt; | 表示状态、程度，像副词一样使用 | 水を大量&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;飲むことです。&lt;br&gt;お気付きの点は遠慮なし&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;言ってください。
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | 表示动作，行为发生的场所 | 解説欄&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;詳しく説明する。
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | 表示进行动作时所用的手段或材料 | 金&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;買えない物がたくさんあります。
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | 表示原因、理由 | 会社を風邪&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;休んでいます。
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | 表示期限或限度 | 新幹線は3時間&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;東京・大阪間を走る。
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | 表示动作进行时的状态 | 普通の速さ&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;歩いて5分ほどだ。
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | 表示范围、范畴 | 外交の面&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;も一連の大きな成果を収めた。
&lt;span style=&quot;color:#BD00F9&quot;&gt;で&lt;/span&gt; | 表示动作的主体&lt;br&gt;大多是团体或组织等集合体 | これは当社&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;開発した新製品です。&lt;br&gt;警視庁&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;未成年者犯罪の取り締まりに全力を挙げています。
&lt;span style=&quot;color:#74E302&quot;&gt;と&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后&lt;br&gt;在引用思考、叙述的内容时，也可接在用言、助动词后&lt;br&gt;还可接在某些副词后
&lt;span style=&quot;color:#74E302&quot;&gt;と&lt;/span&gt; | 表示行为、动作的共同者或对象 | 私は母&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;デパートへ行きました。
&lt;span style=&quot;color:#74E302&quot;&gt;と&lt;/span&gt; | 表示事物演变、转化的结果 | 長い努力がむだ&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;なった。
&lt;span style=&quot;color:#74E302&quot;&gt;と&lt;/span&gt; | 表示比较的对象或基准 | 私の国&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;比べると、日本のほうが暑いです。
&lt;span style=&quot;color:#74E302&quot;&gt;と&lt;/span&gt; | 表示称谓或思考、叙述的内容 | 私は張&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;申します。&lt;br&gt;ー度富士山に登ってみたい&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;思います。
&lt;span style=&quot;color:#74E302&quot;&gt;と&lt;/span&gt; | 跟在某些情态副词、体言后，&lt;br&gt;构成状语，表示方式、状态 | 雨がぽつりぽつり&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;降る。&lt;br&gt;二度&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;そんなことはしない。
&lt;span style=&quot;color:#06CE9F&quot;&gt;から&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后&lt;br&gt;接在接续助词“て”后
&lt;span style=&quot;color:#06CE9F&quot;&gt;から&lt;/span&gt; | 表示动作、作用在时间、空间、&lt;br&gt;人物关系、事项上的起点或经由点 | 朝&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;彼を待っている。&lt;br&gt;車&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;降りた男。
&lt;span style=&quot;color:#06CE9F&quot;&gt;から&lt;/span&gt; | 表示原因、理由、依据等 | 小さなこと&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;けんかになった。
&lt;span style=&quot;color:#06CE9F&quot;&gt;から&lt;/span&gt; | 表示原料、材料、成分等 | 酒は米&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;造る。
&lt;span style=&quot;color:#06CE9F&quot;&gt;から&lt;/span&gt; | 表示动作、作用的主体 | そのことは私&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;彼に話しておきます。
&lt;span style=&quot;color:#9A3702&quot;&gt;まで&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后&lt;br&gt;有时可接在用言和助动词后
&lt;span style=&quot;color:#9A3702&quot;&gt;まで&lt;/span&gt; | 表示行为、动作在时间、空间、&lt;br&gt;人物关系、事项上的终点 | 荷物をとなりの部屋&lt;code class=&quot;language-text&quot;&gt;まで&lt;/code&gt;運んでください。&lt;br&gt;50ページ&lt;code class=&quot;language-text&quot;&gt;まで&lt;/code&gt;予習しておく。
&lt;span style=&quot;color:#659A02&quot;&gt;へ&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言或相当于体言的词语后
&lt;span style=&quot;color:#659A02&quot;&gt;へ&lt;/span&gt; | 表示方向或到达点 | 裁判所&lt;code class=&quot;language-text&quot;&gt;へ&lt;/code&gt;訴えなければ解決策がない。
&lt;span style=&quot;color:#659A02&quot;&gt;へ&lt;/span&gt; | 表示动作、作用的对象 | これは母&lt;code class=&quot;language-text&quot;&gt;へ&lt;/code&gt;の手紙です。
&lt;span style=&quot;color:#0264CF&quot;&gt;より&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言、相当于体言的词语后&lt;br&gt;有时可接在动词、形容词、助动词后
&lt;span style=&quot;color:#0264CF&quot;&gt;より&lt;/span&gt; | 表示比较的基准 | 今年は去年&lt;code class=&quot;language-text&quot;&gt;より&lt;/code&gt;ずっと暑いです。
&lt;span style=&quot;color:#0264CF&quot;&gt;より&lt;/span&gt; | 表示限定 | こうする&lt;code class=&quot;language-text&quot;&gt;より&lt;/code&gt;ほかに仕方がない。
&lt;span style=&quot;color:#0264CF&quot;&gt;より&lt;/span&gt; | 表示起点 | 個展は明日&lt;code class=&quot;language-text&quot;&gt;より&lt;/code&gt;開催されます。
&lt;span style=&quot;color:#04B60E&quot;&gt;の&lt;/span&gt; | &lt;strong&gt;接续法&lt;/strong&gt; | 接在体言或相当于体言的词语、副词及某些惯用型后
&lt;span style=&quot;color:#04B60E&quot;&gt;の&lt;/span&gt; | 表示定语 | 図書館&lt;code class=&quot;language-text&quot;&gt;の&lt;/code&gt;本
&lt;span style=&quot;color:#04B60E&quot;&gt;の&lt;/span&gt; | 表示定语从句中的主语 | 鉛筆&lt;code class=&quot;language-text&quot;&gt;の&lt;/code&gt;ほしい人はいませんか。&lt;/p&gt;
&lt;h3 id=&quot;xx-其他常用助词语法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xx-%E5%85%B6%E4%BB%96%E5%B8%B8%E7%94%A8%E5%8A%A9%E8%AF%8D%E8%AF%AD%E6%B3%95&quot; aria-label=&quot;xx 其他常用助词语法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;X.X 其他常用助词语法&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDX_X&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;| 用法 | 范例&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:--- | :--- | :---
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;连续助词&lt;/strong&gt;
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 接续法 | 接在动词、形容词及动词型活用助动词、&lt;br&gt;形容词型活用助动词连用形后
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 表示并列或对比 | 夏は暑く&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;冬は寒いです。
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 表示随时间推移而发生的&lt;br&gt;动作的先后关系 | 夏は過ぎ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;秋が来た。&lt;br&gt;一年前に行っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;以来、あそこ・・・
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 表示动作进行的方式、方法、手段 | 父は毎日電車に乗っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;会社へ行きます。&lt;br&gt;私はラジオの講座を聞い&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;英語を・・・
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 表示前项对后项的叙述内容加以限定 | 彼の意見を無視してそんなことをし&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;はいけない。
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 表示原因、理由&lt;br&gt;只限于客观的表达，&lt;br&gt;句末不能用主观的表达方式 | あまり小さく&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;見えません。&lt;br&gt;教室で騒い&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;しかられました。
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 表示前后项是逆态的接续关系 | 事情を知っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;いて言わないのだから、彼も性格が悪い。
&lt;span style=&quot;color:#41E0F5&quot;&gt;て&lt;/span&gt; | 连接补助动词、补助形容词：&lt;br&gt;ない、いい、ほしい | 先生に作文を直し&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;いただきました。&lt;br&gt;あなたも一緒に行っ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;ほしい。
&lt;span style=&quot;color:#F5B041&quot;&gt;ながら&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;连续助词&lt;/strong&gt;
&lt;span style=&quot;color:#F5B041&quot;&gt;ながら&lt;/span&gt; | 接续法 | 接在动词和动词型活用助动词的连用形、&lt;br&gt;形容词和形容词型活用助动词的终止形、&lt;br&gt;形容动词词干、某些名词后
&lt;span style=&quot;color:#F5B041&quot;&gt;ながら&lt;/span&gt; | 表示动作同时进行或两个动作同时存在 | 天気がいいから、散歩し&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;話しましょう。
&lt;span style=&quot;color:#F5B041&quot;&gt;ながら&lt;/span&gt; | 表示逆态接续 | 不快に思い&lt;code class=&quot;language-text&quot;&gt;ながら&lt;/code&gt;顔色には出さない。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;し&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;连续助词&lt;/strong&gt;
&lt;span style=&quot;color:#0C8FFF&quot;&gt;し&lt;/span&gt; | 接续法 | 接在用言、助动词的终止形后面
&lt;span style=&quot;color:#0C8FFF&quot;&gt;し&lt;/span&gt; | 表示两个或两个以上的事项同时存在 | 遊んでもいたい&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;、勉強もしたい。
&lt;span style=&quot;color:#0C8FFF&quot;&gt;し&lt;/span&gt; | 表示同时存在的事项是后续句子的理由 | 朝は早い&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;、夜は遅い&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;、疲れるのはあたりまえです。
&lt;span style=&quot;color:#BD00F9&quot;&gt;て/でも&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;连续助词&lt;/strong&gt; &lt;strong&gt;ても/でも&lt;/strong&gt;
&lt;span style=&quot;color:#BD00F9&quot;&gt;て/でも&lt;/span&gt; | 接续法 | 接在动词、动词型活用助动词、形容词、形容词型活用助动词的连用形后&lt;br&gt;接在名词、形容动词词干、形容动词型活用助动词词干后时用“でも”
&lt;span style=&quot;color:#BD00F9&quot;&gt;て/でも&lt;/span&gt; | 表示假定让步条件的逆态接续&lt;br&gt;前项条件已经成立的情况下，&lt;br&gt;后项也不受此条件约束，依然成立 | たとえ雨が降っ&lt;code class=&quot;language-text&quot;&gt;ても&lt;/code&gt;、行きます。&lt;br&gt;どんなに丈夫&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;長くは使えないだろう。
&lt;span style=&quot;color:#BD00F9&quot;&gt;て/でも&lt;/span&gt; | 表示既定让步条件的逆态接续&lt;br&gt;表示前项以一既成事实为条件，&lt;br&gt;后项在此条件下也成立 | 雪は夜になっ&lt;code class=&quot;language-text&quot;&gt;ても&lt;/code&gt;やみませんでした。&lt;br&gt;あんなに暑く&lt;code class=&quot;language-text&quot;&gt;ても&lt;/code&gt;だれも暑いと言わなかった。
&lt;span style=&quot;color:#74E302&quot;&gt;たって&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;连续助词&lt;/strong&gt; &lt;strong&gt;たって/だって&lt;/strong&gt;
&lt;span style=&quot;color:#74E302&quot;&gt;たって&lt;/span&gt; | 接续法 | 接在动词、动词型活用助动词、形容词、形容词型活用助动词的连用形后&lt;br&gt;接在名词、形容动词词干、形容动词型活用助动词词干后时用“だって”
&lt;span style=&quot;color:#74E302&quot;&gt;たって&lt;/span&gt; | 与“ても/でも”基本上一样&lt;br&gt;是表示让步意义的逆态接续关系 | 値段が安く&lt;code class=&quot;language-text&quot;&gt;たって&lt;/code&gt;品が悪ければ買わない。&lt;br&gt;呼ん&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;返事しないから、よしなさい。
&lt;span style=&quot;color:#009DF0&quot;&gt;て/では&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;连续助词&lt;/strong&gt; &lt;strong&gt;ては/では&lt;/strong&gt;
&lt;span style=&quot;color:#009DF0&quot;&gt;て/では&lt;/span&gt; | 接续法 | 接在动词、动词型活用助动词、形容词、形容词型活用助动词的连用形后&lt;br&gt;接在名词、形容动词词干、形容动词型活用助动词词干后时用“では”
&lt;span style=&quot;color:#009DF0&quot;&gt;て/では&lt;/span&gt; | 表示假定条件，后项多为否定或消极&lt;br&gt;表示反复出现、进行的行为动作 | 体が弱く&lt;code class=&quot;language-text&quot;&gt;ては&lt;/code&gt;大事業は出来ない。&lt;br&gt;雪は消え&lt;code class=&quot;language-text&quot;&gt;ては&lt;/code&gt;降り、降っ&lt;code class=&quot;language-text&quot;&gt;ては&lt;/code&gt;また消えた。
&lt;span style=&quot;color:#00F053&quot;&gt;ので&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;连续助词&lt;/strong&gt;
&lt;span style=&quot;color:#00F053&quot;&gt;ので&lt;/span&gt; | 接续法 | 接在用言、助动词的连体形后
&lt;span style=&quot;color:#00F053&quot;&gt;ので&lt;/span&gt; | 表示两个事项之间存在客观的&lt;br&gt;或人们都承认的因果关系 | 強いお酒な&lt;code class=&quot;language-text&quot;&gt;ので&lt;/code&gt;、わたしはいただきませんでした。&lt;br&gt;試験が近づいた&lt;code class=&quot;language-text&quot;&gt;ので&lt;/code&gt;、みんな・・・
&lt;span style=&quot;color:#06CE9F&quot;&gt;たり&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;并列助词&lt;/strong&gt;
&lt;span style=&quot;color:#06CE9F&quot;&gt;たり&lt;/span&gt; | 接续法 | 接在用言或助动词连用形后。&lt;br&gt;由“たり”构成的联合式词组具有体言的性质，可以像体言一样用，&lt;br&gt;还可以后接“する”像サ变动词词干一样使用，或者可以直接入句做状语。
&lt;span style=&quot;color:#06CE9F&quot;&gt;たり&lt;/span&gt; | 表示动作在某一时间内变替进行或&lt;br&gt;状态交替出现 | 飲ん&lt;code class=&quot;language-text&quot;&gt;だり&lt;/code&gt;食べ&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;、十分腹をこしらえた。&lt;br&gt;泣い&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;笑っ&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;嘆い&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;うなっ&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;少しも冷静な態度がない。
&lt;span style=&quot;color:#9A3702&quot;&gt;は&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;提示助词&lt;/strong&gt;
&lt;span style=&quot;color:#9A3702&quot;&gt;は&lt;/span&gt; | 接续法 | 接于体言、相当于体言的词语、用言连用形、&lt;br&gt;部分助动词连用形、部分副词及助词后
&lt;span style=&quot;color:#9A3702&quot;&gt;は&lt;/span&gt; | 提示主题&lt;br&gt;可以顶替“が”、“を”提示主语、宾语&lt;br&gt;可以跟在补格助词的后面提示补语&lt;br&gt;(有时也可顶替“へ”和表示位置的“に“) | 桜の花&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;美しい。(提示主语)&lt;br&gt;この映画&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;先週見ました。(提示宾语)&lt;br&gt;バンダ&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;竹の葉をよく食べる。(提示叙述句主语)&lt;br&gt;ここで&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;話せない。(提示补语)&lt;br&gt;一週間に一度ぐらい&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;映画を見に行きたくなる。(提示状语)
&lt;span style=&quot;color:#9A3702&quot;&gt;は&lt;/span&gt; | 表示对比、比较 | 今日&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;休みが取れますが、明日&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;取れません。
&lt;span style=&quot;color:#9A3702&quot;&gt;は&lt;/span&gt; | 表示否定、让步或转折&lt;br&gt;提示一个部分，导致否定、让步或转折&lt;br&gt;“は”出现在谓语里时，这种倾向更加明显&lt;br&gt;出现在谓语里时，跟在活用词连用形后 | こんなに人がいると&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;思わなかった。&lt;br&gt;読んで&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;みたが、わからないところが多い。&lt;br&gt;安いこと&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;安いが、きずがある。&lt;br&gt;借り&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;したが、すく返した。
&lt;span style=&quot;color:#659A02&quot;&gt;も&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;提示助词&lt;/strong&gt;
&lt;span style=&quot;color:#659A02&quot;&gt;も&lt;/span&gt; | 接续法 | 顶替主格助词“が”提示主语&lt;br&gt;顶替宾格助词“を”或与“を”重叠使用提示宾语&lt;br&gt;与补格助词重叠使用提示补语(也可顶替表示时间和位置的“に“)&lt;br&gt;也可以接在时间名词、方位名词、数词、部分副助词、部分副词后提示状语&lt;br&gt;注意区分&lt;code class=&quot;language-text&quot;&gt;て/で+も&lt;/code&gt;与&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;的区别
&lt;span style=&quot;color:#659A02&quot;&gt;も&lt;/span&gt; | 表示同类事物的追加 | あなたが行くなら、私&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;行きます。
&lt;span style=&quot;color:#659A02&quot;&gt;も&lt;/span&gt; | 表示兼提&lt;br&gt;一般用“AもBも+谓语“、&lt;br&gt;“Aも+谓语、Bも+谓语”的形式 | 一等席&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;二等席&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;全部売り切れました。&lt;br&gt;このホテルから山&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;見えれば、湖&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;見えます。
&lt;span style=&quot;color:#659A02&quot;&gt;も&lt;/span&gt; | 表示强调 | 笑い&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;しません。&lt;br&gt;値段は高く&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;ない。
&lt;span style=&quot;color:#659A02&quot;&gt;も&lt;/span&gt; | 表示全面肯定或全面否定 | 何の経験&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;ない。&lt;br&gt;彼はどんな人間と&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;仲良くやっていく。
&lt;span style=&quot;color:#659A02&quot;&gt;も&lt;/span&gt; | 举出一个极端事例，类推其他 | 子供に&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;分かる道理だ。
&lt;span style=&quot;color:#9A0257&quot;&gt;でも&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;提示助词&lt;/strong&gt;
&lt;span style=&quot;color:#9A0257&quot;&gt;でも&lt;/span&gt; | 接续法 | 顶替主格助词“が”提示主语。顶替宾格助词“を”提示宾语&lt;br&gt;与补格助词重叠使用提示补语&lt;br&gt;也可以接在时间名词、方位名词、数词、部分副助词、部分副词后提示状语
&lt;span style=&quot;color:#9A0257&quot;&gt;でも&lt;/span&gt; | 提示一个极端事例，类推其他 | 先生&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;解けない難問。
&lt;span style=&quot;color:#9A0257&quot;&gt;でも&lt;/span&gt; | 表示举例 | 新聞&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;雑誌&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;いいから時間つぶしに貸してくださいませんか。
&lt;span style=&quot;color:#9A0257&quot;&gt;でも&lt;/span&gt; | 与不定词呼应，表示全面肯定 | この店には何&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;ある。
&lt;span style=&quot;color:#0264CF&quot;&gt;だって&lt;/span&gt; | &lt;strong&gt;类型&lt;/strong&gt; | &lt;strong&gt;提示助词&lt;/strong&gt;
&lt;span style=&quot;color:#0264CF&quot;&gt;だって&lt;/span&gt; | 接续法 | 可以顶替主格助词“が”提示主语，顶替宾格助词“を”提示宾语&lt;br&gt;可以与补格助词重叠使用提示补语&lt;br&gt;可以接在时间名词、方位名词、数词、部分副助词、部分副词后提示状语&lt;br&gt;用法和“でも”相似，但和“でも”相比，多用在比较随便、亲切的谈话中
&lt;span style=&quot;color:#0264CF&quot;&gt;だって&lt;/span&gt; | 提出一个极端事例，类推其他 | 私&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;そのくらいのことはできますよ。
&lt;span style=&quot;color:#0264CF&quot;&gt;だって&lt;/span&gt; | 举例性地提示同类事物中的几个 | 映画&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;芝居&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;君の好きなほうに連れていってあげるよ。
&lt;span style=&quot;color:#0264CF&quot;&gt;だって&lt;/span&gt; | 与不定词呼应，&lt;br&gt;表示全面肯定或全面否定 | 彼はいつ&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;笑顔だ。&lt;br&gt;そんなことはだれ&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;分からないでしょう。&lt;/p&gt;
&lt;h2 id=&quot;xi-常用表达&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xi-%E5%B8%B8%E7%94%A8%E8%A1%A8%E8%BE%BE&quot; aria-label=&quot;xi 常用表达 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;XI. 常用表达&lt;/h2&gt;
&lt;p&gt;&lt;span id=&quot;IDXI&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;数字的表达&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%95%B0%E5%AD%97%E7%9A%84%E8%A1%A8%E8%BE%BE&quot; aria-label=&quot;数字的表达 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;数字的表达&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%97%A5%E8%AA%9E%E6%95%B8%E5%AD%97&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;日语数字 WIKI&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;数字&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;音读&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;训读&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;数字&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;音读&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;训读&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;0&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;れい/ゼロ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;まる&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ひと(つ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;10&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;とお&lt;br&gt;そ(用于30-90整十的训读)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;2&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;に&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ふた(つ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;20&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はた(ち)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;3&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;み(っつ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;30&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;みそ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;4&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;し/よん/よ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よ(っつ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;40&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よんじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よそ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;5&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ご&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いつ(つ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;50&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ごじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いそ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;6&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;む(っつ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;60&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろくじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;むそ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;7&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しち/なな&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;なな(つ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;70&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ななじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ななそ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;8&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;や(っつ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;80&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はちじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;やそ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;9&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;く/きゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ここの(つ)&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;90&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きゅうじゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ここのそ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;100&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ひゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もも&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;1000&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;せん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ち&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;200&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にひゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;2000&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にせん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;300&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんびゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;3000&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんぜん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;600&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろっぴゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;800&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はっぴゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;8000&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はっせん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;一万&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いちまん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よろず&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;一億&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いちおく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;一兆&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いっちょ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;点念作：てん&lt;/li&gt;
&lt;li&gt;零的用法：一般数字或单独出现时念为&lt;code class=&quot;language-text&quot;&gt;れい&lt;/code&gt;，车牌或房间号码时念为&lt;code class=&quot;language-text&quot;&gt;まる&lt;/code&gt;，电话号码则大多念为&lt;code class=&quot;language-text&quot;&gt;ゼロ&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;连贯的数数：升序&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;イチ、ニ、サン、シ、ゴ、ロク、シチ、ハチ、ク、ジュウ&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;连贯的数数：降序&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ジュウ、キュウ、ハチ、ナナ、ロク、ゴ、ヨン、サン、ニ、イチ&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;数字4的发音规则&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在日语数字里面，4可以说是发音最复杂的数字之一。现代日语里面常用的发音就有「し・よっ・よん・よ」四种，而其中以「よん」最为常见，「よ」次之。而「し」只出现在「四月」这个单词中，「よっ」只出现在「四日」这个数词中，其余都读「よん」或「よ」。&lt;/p&gt;
&lt;p&gt;4后续助数词的第一个假名若是元音或是「な」行假名的话，和「よん」连在一起读有些拗口，所以这种情况一般不读「よん」，而读「よ」。如：4和下列助数词在一起时一般读「よ」：人、年：四人（よにん）、四年（よねん）。当4后续助数词的第一个假名是「じ」时常读「よ」：字、次：四字（よじ）、四次（よじ）。&lt;/p&gt;
&lt;h3 id=&quot;量词的表达&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%87%8F%E8%AF%8D%E7%9A%84%E8%A1%A8%E8%BE%BE&quot; aria-label=&quot;量词的表达 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;量词的表达&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;量词的促音变化&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;数字&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;か行&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;さ行&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;た行&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;は行&lt;/code&gt;&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１回&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いっかい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１歳&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いっさい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１着&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いっちゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いっふん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;6&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;６回&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろっかい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;６歳&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ろく&lt;/code&gt;さい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;６着&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ろく&lt;/code&gt;ちゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;６分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろっふん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;8&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;８回&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はっかい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;８歳&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はっさい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;８着&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はっちゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;８分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はっふん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;10&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１０回&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅっかい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１０歳&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅっさい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１０着&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅっちゃく&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１０分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅっぷん&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;6在&lt;code class=&quot;language-text&quot;&gt;さ行&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;た行&lt;/code&gt;不发生变化，仍旧是&lt;code class=&quot;language-text&quot;&gt;ろく&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;は行&lt;/code&gt;的量词搭配数字1、6、8、10时，还会从原本的发音&lt;code class=&quot;language-text&quot;&gt;は&lt;/code&gt;变成&lt;code class=&quot;language-text&quot;&gt;ぱ&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;常用量词&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;量词/意思&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;1&lt;br&gt;6&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;2&lt;br&gt;7&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;3&lt;br&gt;8&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;4&lt;br&gt;9&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;5&lt;br&gt;10&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;几&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;/ 个数 | ひとつ | ふたつ | &lt;code class=&quot;language-text&quot;&gt;みっ&lt;/code&gt;つ | &lt;code class=&quot;language-text&quot;&gt;よっ&lt;/code&gt;つ | いつつ |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;| &lt;code class=&quot;language-text&quot;&gt;むっ&lt;/code&gt;つ | ななつ | &lt;code class=&quot;language-text&quot;&gt;やっ&lt;/code&gt;つ | ここのつ | &lt;code class=&quot;language-text&quot;&gt;とお&lt;/code&gt; | &lt;code class=&quot;language-text&quot;&gt;いくつ&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;/ 人数 | &lt;code class=&quot;language-text&quot;&gt;ひとり&lt;/code&gt; | &lt;code class=&quot;language-text&quot;&gt;ふたり&lt;/code&gt; | さんにん | &lt;code class=&quot;language-text&quot;&gt;よ&lt;/code&gt;にん | ごにん |&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;| ろくにん | ななにん | はちにん | きゅうにん | じゅうにん | なんにん
歳 / 岁 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;さい |  |  |  |  |
|  |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;さい |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;さい |
回 / 次 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;かい |  |  |  |  |
| &lt;code class=&quot;language-text&quot;&gt;ろっ&lt;/code&gt;かい |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;かい |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;かい |
個 / 个 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;こ |  |  |  |  |
| &lt;code class=&quot;language-text&quot;&gt;ろっ&lt;/code&gt;こ |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;こ |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;こ |
台 / 台 | いちだい | … |  |  |  |
枚 / 张 | いちまい | … |  |  |  |
冊 / 本 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;さつ |  |  |  |  |
|  |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;さつ |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;さつ |
本 / 根 | &lt;code class=&quot;language-text&quot;&gt;いっぽ&lt;/code&gt;ん |  | さん&lt;code class=&quot;language-text&quot;&gt;ぼ&lt;/code&gt;ん |  |  |
| &lt;code class=&quot;language-text&quot;&gt;ろっぽ&lt;/code&gt;ん |  | &lt;code class=&quot;language-text&quot;&gt;はっぽ&lt;/code&gt;ん |  | &lt;code class=&quot;language-text&quot;&gt;じゅっぽ&lt;/code&gt;ん | なん&lt;code class=&quot;language-text&quot;&gt;ぼ&lt;/code&gt;ん
着 / 件 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;ちゃく |  |  |  |  |
|  |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;ちゃく |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;ちゃく |
足 / 双 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;そく |  | さん&lt;code class=&quot;language-text&quot;&gt;ぞ&lt;/code&gt;く |  |  |
|  |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;そく |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;そく | なん&lt;code class=&quot;language-text&quot;&gt;ぞ&lt;/code&gt;く
杯 / 碗 | &lt;code class=&quot;language-text&quot;&gt;いっぱ&lt;/code&gt;い |  | さん&lt;code class=&quot;language-text&quot;&gt;ば&lt;/code&gt;い |  |  |
| &lt;code class=&quot;language-text&quot;&gt;ろっぱ&lt;/code&gt;い |  | &lt;code class=&quot;language-text&quot;&gt;はっぱ&lt;/code&gt;い |  | &lt;code class=&quot;language-text&quot;&gt;じゅっぱ&lt;/code&gt;い | なん&lt;code class=&quot;language-text&quot;&gt;ば&lt;/code&gt;い
階 / 楼 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;かい |  | さん&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;い |  |  |
| &lt;code class=&quot;language-text&quot;&gt;ろっ&lt;/code&gt;かい |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;かい |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;かい | なん&lt;code class=&quot;language-text&quot;&gt;が&lt;/code&gt;い
匹 / 匹 | &lt;code class=&quot;language-text&quot;&gt;いっぴ&lt;/code&gt;き |  | さん&lt;code class=&quot;language-text&quot;&gt;び&lt;/code&gt;き |  |  |
| &lt;code class=&quot;language-text&quot;&gt;ろっぴ&lt;/code&gt;き |  | &lt;code class=&quot;language-text&quot;&gt;はっぴ&lt;/code&gt;き |  | &lt;code class=&quot;language-text&quot;&gt;じゅっぴ&lt;/code&gt;き | なん&lt;code class=&quot;language-text&quot;&gt;び&lt;/code&gt;き
月 / 月 | &lt;code class=&quot;language-text&quot;&gt;いっ&lt;/code&gt;かげつ |  |  |  |  |
| &lt;code class=&quot;language-text&quot;&gt;ろっ&lt;/code&gt;かげつ |  | &lt;code class=&quot;language-text&quot;&gt;はっ&lt;/code&gt;かげつ |  | &lt;code class=&quot;language-text&quot;&gt;じゅっ&lt;/code&gt;かげつ |&lt;/p&gt;
&lt;h3 id=&quot;算数计算&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%AE%97%E6%95%B0%E8%AE%A1%E7%AE%97&quot; aria-label=&quot;算数计算 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;算数计算&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;四则运算&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;四則計算（しそくけいさん）：四则运算
&lt;ul&gt;
&lt;li&gt;足し算（たしざん）：加法&lt;/li&gt;
&lt;li&gt;引き算（ひきざん）：减法&lt;/li&gt;
&lt;li&gt;掛け算（かけざん）：乘法&lt;/li&gt;
&lt;li&gt;割り算（わりざん）：除法&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;加減乗除（かげんじょうじょ）&lt;/li&gt;
&lt;li&gt;四則演算（しそくえんざん）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;加减乘除&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;=：イコール、は&lt;/li&gt;
&lt;li&gt;+：足す（たす）、プラス&lt;/li&gt;
&lt;li&gt;-：引く（ひく）、マイナス&lt;/li&gt;
&lt;li&gt;X：かける&lt;/li&gt;
&lt;li&gt;/：わる&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;例子&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;5x4/2+3-6=7
&lt;ul&gt;
&lt;li&gt;ご　かける　よん　わる　に　たす　さん　ひく　ろく　は/イコール　なな&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;6+2x3-8/4=10
&lt;ul&gt;
&lt;li&gt;ろく　たす　に　かける　さん　ひく　はち　わる　よん　は　じゅう&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;时间日期的表达&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%97%B6%E9%97%B4%E6%97%A5%E6%9C%9F%E7%9A%84%E8%A1%A8%E8%BE%BE&quot; aria-label=&quot;时间日期的表达 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;时间日期的表达&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;时刻&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时刻&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;时刻&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;时刻&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いちじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;２時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;３時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんじ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;４時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;５時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ごじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;６時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろくじ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;７時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;しちじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;８時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はちじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;９時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くじ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１０時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１１時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅういちじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１２時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうにじ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;０時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;れいじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;何時&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;なんじ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;日语在描述&lt;code class=&quot;language-text&quot;&gt;13时&lt;/code&gt;这样的时间点时，使用的是：&lt;code class=&quot;language-text&quot;&gt;午後一時&lt;/code&gt;（ごごいちじ）这样的方式。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时刻&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;时刻&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;时刻&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いっ&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;２分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にふん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;３分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さん&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;４分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よん&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;５分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ごふん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;６分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろっ&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;７分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ななふん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;８分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はっ&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;９分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きゅうふん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１０分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅう&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１１分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅういっ&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１２分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうにふん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１３分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうさんぷん&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１４分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうよぷん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１５分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうごふん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;３０分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんじゅっ&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;４５分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;よんじゅうごふん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;何分&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;なん&lt;code class=&quot;language-text&quot;&gt;ぷ&lt;/code&gt;ん&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;星期&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;星期&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;翻译&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;日曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にちようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期日&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;月曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;げつようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期一&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;火曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;かようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期二&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;水曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;すいようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期三&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;木曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;もくようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期四&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;金曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きんようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期五&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;土曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;どようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期六&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;何曜日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;なんようび&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;星期几&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;月份&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;月份&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;月份&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;月份&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;いちがつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;２月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にがつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;３月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんがつ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;４月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;がつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;５月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ごがつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;６月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ろくがつ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;７月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;しち&lt;/code&gt;がつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;８月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;はちがつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;９月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;く&lt;/code&gt;がつ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;１０月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうがつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１１月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅういちがつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;１２月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうにがつ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;何月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;なんがつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;日历&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;日曜日&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;月曜日&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;火曜日&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;水曜日&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;木曜日&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;金曜日&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;土曜日&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;1&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;2&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;3&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;4&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;5&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;6&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ついたち&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ふつか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;みっか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;よっか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;いつか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;むいか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;なのか&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;8&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;9&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;10&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;11&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;12&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;13&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ようか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ここのか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;とおか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅういちにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうににち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうさんにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;じゅうよっか&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;15&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;16&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;17&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;18&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;19&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;20&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;21&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;じゅうごにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうろくにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうしちにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうはちにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;じゅうくにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;はつか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじゅういちにち&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;22&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;23&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;24&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;25&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;26&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;27&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;28&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;にじゅうににち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじゅうさんにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;にじゅうよっか&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじゅうごにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじゅうろくにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじゅうしちにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;にじゅうはちにち&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;29&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;30&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;31&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;にじゅうくにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんじゅうにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さんじゅういちにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;何日ですか（なんにちですか）&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;其他时间词汇&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;时间&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;翻译&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;时间&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;翻译&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;时间&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;发音&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;翻译&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;おととい&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;前天&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;昨日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きのう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;昨天&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きょう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今天&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;明日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あした&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;明天&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;明後日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あさって&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后天&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;毎日&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;まいにち&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;每天&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;おとといの朝&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あさ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;前天早晨&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;昨日の朝&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あさ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;昨天早晨&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今朝&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;けさ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今天早上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;明日の朝&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あさ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;明天早晨&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;明後日の朝&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あさ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后天早晨&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;毎朝&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;まいあさ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;每天早上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;おとといの晩&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ばん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;前天晚上&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;昨夜&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ゆうべ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;昨天晚上&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今晩&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;こんばん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今天晚上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;明日の晩&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ばん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;明天晚上&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;明後日の晩&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ばん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后天晚上&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;毎晩&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;まいばん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;每天晚上&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;先々週&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;せんせんしゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;上上周&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;先週&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;せんしゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;上周&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今週&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;こんしゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;本周&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;来週&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;らいしゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;下周&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;再来週&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さらいしゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;下下周&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;毎週&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;まいしゅう&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;每周&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;先々月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;せんせんげつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;上上月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;先月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;せんげつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;上月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;こんげつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;本月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;来月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;らいげつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;下个月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;再来月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さらいげつ&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;下下个月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;毎月&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;まいつき&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;每月&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;一昨年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;おととし&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;前年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;きょねん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;去年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ことし&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;今年&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;来年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;らいねん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;明年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;再来年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;さらいねん&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;后年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;毎年&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;まいとし&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;每年&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;时间表达的助词及句式使用&lt;/strong&gt; &lt;span id=&quot;IDXI_time&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;时间的表述一般根据长度分为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;时间点：对应瞬间动词&lt;/li&gt;
&lt;li&gt;时间段：对应继续动词&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同时要理解的是，时间点和时间段的概念的概念是相对的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;昨日、一日でずっと宿題をしていて、疲れたよ。
&lt;ul&gt;
&lt;li&gt;学习时间是一天，作为参照的自然时长也是一天，因此为时间段&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;秋に結婚するつもりです。
&lt;ul&gt;
&lt;li&gt;决定秋天（的某一天）结婚，时间长度为一天，作为参照的自然时长为一个季节，因此为时间点&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;助词表及范例：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;助词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语义&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;动词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;に&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间点&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;瞬间&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;３時&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;駅で待ち合わせる。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;で&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间段&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;继续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;新幹線は3時間&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;東京・大阪間を走る。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;で&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;期限&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;瞬间&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;演説はあと一時間くらい&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;終わります。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;から&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间开始&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;继续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;朝&lt;code class=&quot;language-text&quot;&gt;から&lt;/code&gt;彼を待っている。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;まで&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间结束&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;继续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;入学申し込みの締め切りは月末&lt;code class=&quot;language-text&quot;&gt;まで&lt;/code&gt;です。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;までに&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;截止期限&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;瞬间&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;子どもを９時&lt;code class=&quot;language-text&quot;&gt;までに&lt;/code&gt;寝させる。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;疑难点分析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;行为的「前、后」
&lt;ul&gt;
&lt;li&gt;前面用&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;：ご飯の前&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;、手を洗います。&lt;/li&gt;
&lt;li&gt;后面用&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;：手を洗った後&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;、食事をします。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;地点的表达&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%9C%B0%E7%82%B9%E7%9A%84%E8%A1%A8%E8%BE%BE&quot; aria-label=&quot;地点的表达 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;地点的表达&lt;/h3&gt;
&lt;p&gt;&lt;span id=&quot;IDXI_place&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;助词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;语义&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;范例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;に&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;存在的场所&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;動物園&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;パンダがいます。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;に&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;动作的目标、着落点&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;修学旅行で関西&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;行った。&lt;br&gt;彼はおつりをポケット&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;入れました。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;で&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;动作，行为发生的场所&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;菊地さんのお宅&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;パーティーを開きます。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;を&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;动作经过的场所&lt;br&gt;动作离开的地点&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;電車道&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;歩いて来る。&lt;br&gt;姉は23歳の時、国&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;出ました。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;疑难点分析&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;交通工具
&lt;ul&gt;
&lt;li&gt;上车用&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;：毎日バス&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;乗って出勤します。&lt;/li&gt;
&lt;li&gt;下车用&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;：バス&lt;code class=&quot;language-text&quot;&gt;を&lt;/code&gt;降りて１０分歩くと学校に着きます。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;勤める/働く
&lt;ul&gt;
&lt;li&gt;勤める用&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;：私は銀行&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;勤めています。&lt;/li&gt;
&lt;li&gt;働く用&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;：兄は父の會社&lt;code class=&quot;language-text&quot;&gt;で&lt;/code&gt;働いています。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;趋向移动
&lt;ul&gt;
&lt;li&gt;后续的动词是表示趋向的移动动词时，动词的到达点可以用“に“、“へ”表示，也可以用“まで”表示。
&lt;ul&gt;
&lt;li&gt;時間がなかったので、駅に(へ/まで)自転車で行った。/没有时间了,就骑自行车去了车站。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;但是，“まで”暗含有到达的不是最终目的地，而是中途一点的意思
&lt;ul&gt;
&lt;li&gt;京駅まで (? に/?へ)電車で行って地下鉄に乗り換えた。/乘电车到东京站换采了地铁。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;问路的表达&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%97%AE%E8%B7%AF%E7%9A%84%E8%A1%A8%E8%BE%BE&quot; aria-label=&quot;问路的表达 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;问路的表达&lt;/h3&gt;
&lt;p&gt;…&lt;/p&gt;
&lt;h3 id=&quot;并列关系多项动作多个目标的表达&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%B9%B6%E5%88%97%E5%85%B3%E7%B3%BB%E5%A4%9A%E9%A1%B9%E5%8A%A8%E4%BD%9C%E5%A4%9A%E4%B8%AA%E7%9B%AE%E6%A0%87%E7%9A%84%E8%A1%A8%E8%BE%BE&quot; aria-label=&quot;并列关系多项动作多个目标的表达 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;并列关系、多项动作（多个目标）的表达&lt;/h3&gt;
&lt;p&gt;在实际使用中，经常会遇到稍微复杂点的情况，需要描述多个要素构成一个表达，或举例多个内容等，这种时候就需要用到这里整理的表达方法了。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;词&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;条目&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;注解&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;と&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;と&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在&lt;code class=&quot;language-text&quot;&gt;体言&lt;/code&gt;、相当于体言的词语后。在引用思考、叙述的内容时，也可接在用言、助动词后。&lt;br&gt;此外，还可接在某些副词后。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;と&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;名词と名词，A和B&lt;br&gt;用于数量较少情况下的&lt;code class=&quot;language-text&quot;&gt;全部列举&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#41E0F5&quot;&gt;と&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;その村の川の水&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;池の水はきれいです。&lt;br&gt;ピーマン&lt;code class=&quot;language-text&quot;&gt;と&lt;/code&gt;たまねぎが大嫌い。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;に&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;に&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在&lt;code class=&quot;language-text&quot;&gt;体言&lt;/code&gt;、相当于体言的词后。最后一个体言后不再加“に“。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;に&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;名词に名词，A和B&lt;br&gt;表示&lt;code class=&quot;language-text&quot;&gt;添加性&lt;/code&gt;的&lt;code class=&quot;language-text&quot;&gt;并列关系&lt;/code&gt;（全部列举）。&lt;br&gt;“に”是累加地列举全部事物，但可以表示对比、对照的并列关系，&lt;br&gt;而“と”是把全部的事物作为个整体一起列举出来&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#F5B041&quot;&gt;に&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;インクは黒いの&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;青いの&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;赤いのがある。&lt;br&gt;白い砂浜&lt;code class=&quot;language-text&quot;&gt;に&lt;/code&gt;緑の松林が何とも言えない美しさだ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;や&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;や&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在&lt;code class=&quot;language-text&quot;&gt;体言&lt;/code&gt;、相当于体言的词语后。や只能接体言。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;や&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;名词や名词や名词、名词や名词など，A和B和C（等/之类）&lt;br&gt;用于数量较多情况下的&lt;code class=&quot;language-text&quot;&gt;列举&lt;/code&gt;，但仅只是全体中的一部分，类似举例&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0C8FFF&quot;&gt;や&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;太郎&lt;code class=&quot;language-text&quot;&gt;や&lt;/code&gt;次郎&lt;code class=&quot;language-text&quot;&gt;や&lt;/code&gt;花子などが私たちの同級生だ。&lt;br&gt;新聞&lt;code class=&quot;language-text&quot;&gt;や&lt;/code&gt;テレビなどで、その事件のことを知った。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;も&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;提示助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;も&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在体言、相当于体言的词语、用言及部分助动词的连用形、部分副词、部分助词之后&lt;br&gt;可顶替主格助词“が”提示主语，顶替宾格助词“を”或与“を”重叠使用提示宾语，&lt;br&gt;与补格助词重叠使用（也可顶替表示时间和位置的“に“）提示补语，&lt;br&gt;也可以接在时间名词、方位名词、数词、部分副助词、部分副词后提示状语&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;も&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;AもBも+谓语；Aも+谓语、Bも+谓语，A和B都&lt;br&gt;提示两个或两个以上的类似事物，表示它们的情况相同，或是同一倾向&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#BD00F9&quot;&gt;も&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;りんご&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;オレンジ&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;果物です。&lt;br&gt;このホテルから山&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;見えれば、湖&lt;code class=&quot;language-text&quot;&gt;も&lt;/code&gt;見えます。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;て&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;连续助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;て&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在动词、形容词及动词型活用助动词、形容词型活用助动词连用形后&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;て&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;AてBてCて，既A又B又C、又A又B又C&lt;br&gt;て的并列描述多用在形容/形容动词上（形容动词时转成で），&lt;br&gt;要注意同表达形式也可以描述前后比较关系，需要注意区分&lt;br&gt;动词的情况多为描述行为的前后顺序执行，一般不适用于并列描述&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#74E302&quot;&gt;て&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;ここは広くて、便利です。&lt;br&gt;田中先生は親切で優しいです。&lt;br&gt;大きくて美味しくて新鮮なりんごを５つ買いました。&lt;br&gt;夏は暑く&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;冬は寒いです。(这里是比较)&lt;br&gt;弟は朝ご飯を食べ&lt;code class=&quot;language-text&quot;&gt;て&lt;/code&gt;学校へ行きました。(这里是先后顺序)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;とか&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;とか&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在体言、相当于体言的词组和用言、助动词终止形后。&lt;br&gt;并列体言则最后一个“とか”可以省略，并列用言时不能省略&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;とか&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词とか词とか词，A啦B啦C啦，A或者B或者C&lt;br&gt;表示&lt;code class=&quot;language-text&quot;&gt;举例性并列&lt;/code&gt;，兼有“や”和“か”的意义，注意该句式举例的意味很强&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#06CE9F&quot;&gt;とか&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;陳さん&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;王さん&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;には話したくありません。&lt;br&gt;暇のときは散歩する&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;、スポーツをする&lt;code class=&quot;language-text&quot;&gt;とか&lt;/code&gt;します。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A3702&quot;&gt;やら&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A3702&quot;&gt;やら&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在体言、相当于体言的词语和用言、助动词连体形后。&lt;br&gt;用“やら”列举时，所并列的最后一个词后一定还要用一个“やら”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A3702&quot;&gt;やら&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词とか词とか词，A啦B啦C啦，A或者B或者C&lt;br&gt;表示&lt;code class=&quot;language-text&quot;&gt;举例性并列&lt;/code&gt;。&lt;br&gt;大多会用在当面临太多选择或想法，而无法下定决心或理出头绪时使用。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A3702&quot;&gt;やら&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;藤井&lt;code class=&quot;language-text&quot;&gt;やら&lt;/code&gt;松村&lt;code class=&quot;language-text&quot;&gt;やら&lt;/code&gt;から問い合わせの手紙が来た。&lt;br&gt;赤いの&lt;code class=&quot;language-text&quot;&gt;やら&lt;/code&gt;、青いの&lt;code class=&quot;language-text&quot;&gt;やら&lt;/code&gt;、きれいなネクタイをたくさん持っている。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#659A02&quot;&gt;だの&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#659A02&quot;&gt;だの&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在体言、相当于体言的词语和用言、助动词终止形（形容动词、形容动词型活用助动词的词干）后。&lt;br&gt;最后的“だの”有时可省略，多用“&lt;del&gt;だの&lt;/del&gt;など”的句型。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#659A02&quot;&gt;だの&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;词だの词だの词、AだのBなど，A啦B啦C啦，A或者B或者C&lt;br&gt;表示&lt;code class=&quot;language-text&quot;&gt;举例性并列&lt;/code&gt;。带有比较粗俗的语感，郑重的文章中不用。&lt;br&gt;说话者大多会带有「不满或责备的情绪」。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#659A02&quot;&gt;だの&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;くだもの&lt;code class=&quot;language-text&quot;&gt;だの&lt;/code&gt;、おかし&lt;code class=&quot;language-text&quot;&gt;だの&lt;/code&gt;食べすぎたので、おなかが痛い。&lt;br&gt;頭が痛い&lt;code class=&quot;language-text&quot;&gt;だの&lt;/code&gt;体がだるい&lt;code class=&quot;language-text&quot;&gt;など&lt;/code&gt;、怠ける口実ばかり探している。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A0257&quot;&gt;か&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A0257&quot;&gt;か&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在体言、相当于体言的词语和用言、助动词连体型后。&lt;br&gt;“か”并列体言时最后一个“か”一般可省略；&lt;br&gt;“か”并列用言时，一般不省略。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A0257&quot;&gt;か&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;AかBかC，A还是B或者C&lt;br&gt;表示&lt;code class=&quot;language-text&quot;&gt;两者择一&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;数者择一&lt;/code&gt;的关系。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#9A0257&quot;&gt;か&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;あなた&lt;code class=&quot;language-text&quot;&gt;か&lt;/code&gt;私が行くべきだ。&lt;br&gt;コーヒー色&lt;code class=&quot;language-text&quot;&gt;か&lt;/code&gt;鼠色&lt;code class=&quot;language-text&quot;&gt;か&lt;/code&gt;に染めてごらん。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0264CF&quot;&gt;なり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0264CF&quot;&gt;なり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;主要接在体言、相当于体言的词语后，也可以接在动词、形容词后。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0264CF&quot;&gt;なり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;AなりBなりC，A还是B还是C&lt;br&gt;以&lt;code class=&quot;language-text&quot;&gt;举例的方式&lt;/code&gt;表示&lt;code class=&quot;language-text&quot;&gt;数者择一&lt;/code&gt;的并列关系。选择的结果可&lt;code class=&quot;language-text&quot;&gt;不限于&lt;/code&gt;列举的事物。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#0264CF&quot;&gt;なり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;お茶&lt;code class=&quot;language-text&quot;&gt;なり&lt;/code&gt;コーヒー&lt;code class=&quot;language-text&quot;&gt;なり&lt;/code&gt;(を)お好きなものをどうぞ。&lt;br&gt;東京へ&lt;code class=&quot;language-text&quot;&gt;なり&lt;/code&gt;大阪へ&lt;code class=&quot;language-text&quot;&gt;なり&lt;/code&gt;早く行っておいでなさい。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#04B60E&quot;&gt;でも&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;提示助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#04B60E&quot;&gt;でも&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在体言、相当于体言的词语、用言及部分助动词的连用形、部分副词、部分助词后。&lt;br&gt;可顶替主格助词“が”提示主语，顶替宾格助词“を”提示宾语，&lt;br&gt;与补格助词重叠使用提示补语，&lt;br&gt;也可以接在时间名词、方位名词、数词、部分副助词、部分副词后提示状语&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#04B60E&quot;&gt;でも&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;AでもBでもCでも，无论A还是B或者C、A也好B也好C也好&lt;br&gt;表示&lt;code class=&quot;language-text&quot;&gt;举例&lt;/code&gt;，该句式在仅只有一个的时候也可以使用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#04B60E&quot;&gt;でも&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;本&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;読んで待っていてください。&lt;br&gt;新聞&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;雑誌&lt;code class=&quot;language-text&quot;&gt;でも&lt;/code&gt;いいから時間つぶしに貸してくださいませんか。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#D1B100&quot;&gt;だって&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;提示助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#D1B100&quot;&gt;だって&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在&lt;code class=&quot;language-text&quot;&gt;体言&lt;/code&gt;、相当于体言的词语、部分副词、部分助词后。&lt;br&gt;可以顶替主格助词“が”提示主语，顶替宾格助词“を”提示宾语，&lt;br&gt;可以与补格助词重叠使用提示补语，&lt;br&gt;也可以接在时间名词、方位名词、数词、部分副助词、部分副词后提示状语&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#D1B100&quot;&gt;だって&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;AだってBだってCだって，无论A还是B还是C&lt;br&gt;“だって”的用法和“でも”相似，但和“でも”相比，多用在比较随便、亲切的谈话中。&lt;br&gt;&lt;code class=&quot;language-text&quot;&gt;举例性地提示&lt;/code&gt;同类事物中的几个&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#D1B100&quot;&gt;だって&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;マンション&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;車&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;、みんな親に買ってもらったものだ。&lt;br&gt;映画&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;芝居&lt;code class=&quot;language-text&quot;&gt;だって&lt;/code&gt;君の好きなほうに連れていってあげるよ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#20D100&quot;&gt;し&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;连续助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#20D100&quot;&gt;し&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在&lt;code class=&quot;language-text&quot;&gt;用言&lt;/code&gt;、助动词的终止形后面；只需要连接中的し，最后一个一般省略&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#20D100&quot;&gt;し&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Aし、B；Aし、Bも；Aし、Bし、C，既A又B、又A又B、既A又B且C&lt;br&gt;常与“も”呼应使用。表示两个或两个以上的事项同时存在&lt;br&gt;表示同时存在的事项是后续句子的理由&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#20D100&quot;&gt;し&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;彼は医者にも行かない&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;、薬も飲んでいません。&lt;br&gt;あの人は酒も飲まない&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;、タバコも吸わない&lt;code class=&quot;language-text&quot;&gt;し&lt;/code&gt;、今どき珍しい青年だ。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#4F00C5&quot;&gt;たり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;并列助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#4F00C5&quot;&gt;たり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在&lt;code class=&quot;language-text&quot;&gt;用言&lt;/code&gt;或助动词连用形后。&lt;br&gt;由“たり”构成的联合式词组具有体言的性质，可以像体言一样用，&lt;br&gt;还可以后接“する”像サ变动词词干一样使用，或者可以直接入句做状语&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#4F00C5&quot;&gt;たり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;AたりBたりCたり，又A又B又C&lt;br&gt;表示动作在某一时间内变替进行或状态交替出现&lt;br&gt;Aたりする，以A为代表进行举例&lt;br&gt;表示举例或者并列，言外暗示还有诸如此类事情。这可以作为并列的特殊用法。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#4F00C5&quot;&gt;たり&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;その老人は泣い&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;騒い&lt;code class=&quot;language-text&quot;&gt;だり&lt;/code&gt;しました。&lt;br&gt;飲ん&lt;code class=&quot;language-text&quot;&gt;だり&lt;/code&gt;食べ&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;、十分腹をこしらえた。&lt;br&gt;近頃の天気は寒かっ&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;暑かっ&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;してたいへん不順です。&lt;br&gt;うそをつい&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;してはいけません。&lt;br&gt;それぐらいのことで怒っ&lt;code class=&quot;language-text&quot;&gt;たり&lt;/code&gt;するものではない。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#00F053&quot;&gt;ては&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;类型&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;strong&gt;连续助词&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#00F053&quot;&gt;ては&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接续&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;接在动词、动词型活用助动词、形容词、形容词型活用助动词的连用形后&lt;br&gt;接在名词、形容动词词干、形容动词型活用助动词词干后时用“では”&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#00F053&quot;&gt;ては&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;解说&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;动词ては动词，A又B、每次A都B&lt;br&gt;表示&lt;code class=&quot;language-text&quot;&gt;反复出现、进行&lt;/code&gt;的行为动作&lt;br&gt;基本上只会是成对出现，不会有两个以上的动词&lt;br&gt;需要注意在表示&lt;code class=&quot;language-text&quot;&gt;每次・・&lt;/code&gt;这样的情况下，ては看起来非常类似&lt;code class=&quot;language-text&quot;&gt;表示假定条件&lt;/code&gt;的用法，注意区分&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;span style=&quot;color:#00F053&quot;&gt;ては&lt;/span&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;范例&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;彼は非常に本が好きで、町へ行っ&lt;code class=&quot;language-text&quot;&gt;ては&lt;/code&gt;本を四、五冊買ってきます。(&lt;code class=&quot;language-text&quot;&gt;每次&lt;/code&gt;上街都)&lt;br&gt;町へ行っ&lt;code class=&quot;language-text&quot;&gt;ては&lt;/code&gt;アイスクリームを買って食べる。(&lt;code class=&quot;language-text&quot;&gt;每次&lt;/code&gt;上街都)&lt;br&gt;雪は消え&lt;code class=&quot;language-text&quot;&gt;ては&lt;/code&gt;降り、降っ&lt;code class=&quot;language-text&quot;&gt;ては&lt;/code&gt;また消えた。&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&quot;xii-语法解析范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#xii-%E8%AF%AD%E6%B3%95%E8%A7%A3%E6%9E%90%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;xii 语法解析范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;XII. 语法解析范例&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;| 注解&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;:--- | :---
&lt;strong&gt;原句&lt;/strong&gt; | あっという間に「利権」と化し、「腐敗」を生み、「争い」になるわ
解析 | 化し：连用表中顿；生み：连用表中顿
&lt;strong&gt;原句&lt;/strong&gt; | 貴女の夫であり、私たちの師であった
解析 | であり：名词+てある-&gt;である-&gt;连用表中顿-&gt;であり
&lt;strong&gt;原句&lt;/strong&gt; | 私が幸せになった訳でも、世の中にが良くなった訳でも無かった
解析 | 訳之前的部分：なる-&gt;连体形-&gt;なる-&gt;过去时-&gt;なった，连体修饰语从句-&gt;私が幸せになった+名词
&lt;strong&gt;原句&lt;/strong&gt; | 弔ってやってくれ
解析 | 弔う连用+て表动作先后 + やる+てくれ表强烈命令
&lt;strong&gt;原句&lt;/strong&gt; | 奪ったりしない
解析 | 奪う连用形+たりする(举出一个代表性的动作或状况作为例子来说明情况)
&lt;strong&gt;原句&lt;/strong&gt; | 検査前のドローンに誤作動を誘発する&lt;code class=&quot;language-text&quot;&gt;プロタラ&lt;/code&gt;とを&lt;code class=&quot;language-text&quot;&gt;仕込め&lt;/code&gt;ば
解析 | 这句很能体现に和を在使用上的差别
&lt;strong&gt;原句&lt;/strong&gt; | &lt;code class=&quot;language-text&quot;&gt;スモリー&lt;/code&gt;が予備を含めて&lt;code class=&quot;language-text&quot;&gt;吹っ飛ん&lt;/code&gt;でるらしい
解析 | 这句可以和上句匹配起来，看下が、を、に三者的关系&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[微信支付接入]]></title><link>https://xenojoshua.com/posts/2019/12/wxpay</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/12/wxpay</guid><pubDate>Fri, 27 Dec 2019 03:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%94%AF%E4%BB%98%E6%B5%81%E7%A8%8B&quot;&gt;2. 支付流程&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E7%BD%91%E9%A1%B5%E7%AB%AF&quot;&gt;2.1 网页端&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E7%A7%BB%E5%8A%A8%E5%8E%9F%E7%94%9F&quot;&gt;2.2 移动原生&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot;&gt;3. 准备工作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-api--sdk&quot;&gt;4. API &amp;#x26; SDK&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-sdk%E9%80%89%E6%8B%A9&quot;&gt;4.1 SDK选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-api%E4%BD%BF%E7%94%A8%E5%9F%BA%E7%A1%80&quot;&gt;4.2 API使用基础&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#421-%E7%BD%91%E9%A1%B5%E7%AB%AF&quot;&gt;4.2.1 网页端&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#422-%E7%A7%BB%E5%8A%A8%E5%8E%9F%E7%94%9F&quot;&gt;4.2.2 移动原生&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E5%B8%B8%E7%94%A8%E6%8E%A5%E5%8F%A3&quot;&gt;4.3 常用接口&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#431-%E7%BB%9F%E4%B8%80%E4%B8%8B%E5%8D%95%E6%8E%A5%E5%8F%A3&quot;&gt;4.3.1 统一下单接口&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#432-%E8%AE%A2%E5%8D%95%E6%9F%A5%E8%AF%A2%E6%8E%A5%E5%8F%A3&quot;&gt;4.3.2 订单查询接口&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E9%87%91%E9%A2%9D%E9%97%AE%E9%A2%98&quot;&gt;4.4 金额问题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#45-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot;&gt;4.5 回调处理&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E6%B2%99%E7%AE%B1%E4%BD%BF%E7%94%A8&quot;&gt;5. 沙箱使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-%E6%B2%99%E7%AE%B1%E7%94%B3%E8%AF%B7&quot;&gt;5.1 沙箱申请&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E6%B2%99%E7%AE%B1%E4%BD%BF%E7%94%A8&quot;&gt;5.2 沙箱使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#53-%E6%B2%99%E7%AE%B1%E9%97%AE%E9%A2%98&quot;&gt;5.3 沙箱问题&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86&quot;&gt;6. 错误处理&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot;&gt;6.1 回调处理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-%E4%BF%AE%E5%A4%8D%E8%AE%A2%E5%8D%95&quot;&gt;6.2 修复订单&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-%E4%B8%8A%E7%BA%BF%E7%94%9F%E6%95%88&quot;&gt;7. 上线生效&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#appendix&quot;&gt;Appendix&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;微信支付的接入，权当笔记。&lt;/p&gt;
&lt;h1 id=&quot;2-支付流程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%94%AF%E4%BB%98%E6%B5%81%E7%A8%8B&quot; aria-label=&quot;2 支付流程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 支付流程&lt;/h1&gt;
&lt;h3 id=&quot;21-网页端&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E7%BD%91%E9%A1%B5%E7%AB%AF&quot; aria-label=&quot;21 网页端 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 网页端&lt;/h3&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;扫码支付 &gt; 模式二&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;官方配图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/wxpay/wxpay_pc.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;流程涉及到几个角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PC网站网页&lt;/li&gt;
&lt;li&gt;PC网站后台&lt;/li&gt;
&lt;li&gt;微信支付系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;支付流程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;打开PC网站网页的商品页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;对商品进行下单&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;发送下单请求到PC网站后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;在自身系统内生成订单（生成内部订单号），并返回给网页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;获得内部订单信息，并将用户导向到支付页面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;确认订单内容，并开始付款流程&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;发起支付请求到PC网站后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;向微信支付系统发起下单请求，并将返回的信息交付给PC网站网页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;收到微信支付返回信息，将其中的QRCode渲染到页面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;打开微信，使用扫码的方式完成支付&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;微信支付系统&lt;/code&gt;确认支付完成，向notify_url发送回调信息&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;验证微信支付回调完成，标记订单状态为已支付&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;22-移动原生&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E7%A7%BB%E5%8A%A8%E5%8E%9F%E7%94%9F&quot; aria-label=&quot;22 移动原生 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 移动原生&lt;/h3&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_3&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;APP支付 &gt; 业务流程&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;官方配图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/wxpay/wxpay_app.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;流程涉及到几个角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PC网站网页&lt;/li&gt;
&lt;li&gt;PC网站后台&lt;/li&gt;
&lt;li&gt;微信支付系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;支付流程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;打开PC网站网页的商品页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;对商品进行下单&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;发送下单请求到PC网站后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;在自身系统内生成订单（生成内部订单号），并返回给网页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;获得内部订单信息，并将用户导向到支付页面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;确认订单内容，并开始付款流程&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;发起支付请求到PC网站后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;向微信支付系统发起下单请求，并将返回的信息交付给PC网站网页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;收到微信支付返回信息，使用其中的参数唤起微信APP&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;在微信APP中完成支付&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;微信支付系统&lt;/code&gt;确认支付完成，向notify_url发送回调信息&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;验证微信支付回调完成，标记订单状态为已支付&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-准备工作&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot; aria-label=&quot;3 准备工作 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 准备工作&lt;/h1&gt;
&lt;p&gt;微信的权限系统非常有问题，没有分级的子账号，只有一个申请人所拥有的主账号。这导致了后续的一系列操作全部都必须主账号持有人来完成（对，你没有看错，必须你的老板来操作，别人不能代劳）。&lt;/p&gt;
&lt;p&gt;申请人必须操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;申请公司账号&lt;/li&gt;
&lt;li&gt;申请支付应用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;申请完成之后，必须获得以下几个信息，程序才可以对接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;APPID：支付应用的ID&lt;/li&gt;
&lt;li&gt;商户号：商户的ID&lt;/li&gt;
&lt;li&gt;商户的API秘钥：这里切记是&lt;code class=&quot;language-text&quot;&gt;商户秘钥&lt;/code&gt;；微信整个生态中应用非常繁多，因此各种秘钥也多，特别是去生成秘钥的又是老板，一般没有技术经验，所以这步非常非常容易出错，会导致后面验证签名无论如何都不正确，所以一定要当心，必须是商户秘钥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;微信支付也有证书，但这并不是必须项，大部分支付API是不需要证书的，只有部分才需要。证书也是在商户部分申请，申请完之后可以打包下载，里面含文件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;apiclient_cert.p12：证书pkcs12格式&lt;/li&gt;
&lt;li&gt;apiclient_cert.pem：证书&lt;/li&gt;
&lt;li&gt;apiclient_key.pem：私钥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;申请及配置的相关操作可以看这篇：&lt;a href=&quot;https://www.leapcloud.cn/website/docs/doc_config/wxwangyezf/wxwangyezhifu.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信公众号支付配置&lt;/a&gt;，以及&lt;a href=&quot;https://www.leapcloud.cn/website/docs/doc_config/wxappzf/weixinapp.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信APP支付配置&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;移动端还会遇到制作应用签名的问题：&lt;a href=&quot;https://www.leapcloud.cn/website/docs/doc_config/keystorecreate/keystorecreate.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Android App 签名生成教程&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;4-api--sdk&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-api--sdk&quot; aria-label=&quot;4 api  sdk permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. API &amp;#x26; SDK&lt;/h1&gt;
&lt;h2 id=&quot;41-sdk选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-sdk%E9%80%89%E6%8B%A9&quot; aria-label=&quot;41 sdk选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 SDK选择&lt;/h2&gt;
&lt;p&gt;npm上可用的SDK包基本上只有：&lt;a href=&quot;https://www.npmjs.com/package/tenpay&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;tenpay&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;SDK的使用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tenpay &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;tenpay&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;appid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;公众号ID&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;mchid&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;微信商户号&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;partnerKey&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;微信支付安全密钥&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;pfx&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fs&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;证书文件路径&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;notify_url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;支付回调网址&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;spbill_create_ip&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;IP地址&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 方式一&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; api &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;tenpay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 方式二&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; api &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tenpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
 
&lt;span class=&quot;token comment&quot;&gt;// 调试模式(传入第二个参数为true, 可在控制台输出数据)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; api &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;tenpay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
 
&lt;span class=&quot;token comment&quot;&gt;// 沙盒模式(用于微信支付验收)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; sandboxAPI &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; tenpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sandbox&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;config说明:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;appid - 公众号ID(必填)&lt;/li&gt;
&lt;li&gt;mchid - 微信商户号(必填)&lt;/li&gt;
&lt;li&gt;partnerKey - 微信支付安全密钥(必填, 在微信商户管理界面获取)&lt;/li&gt;
&lt;li&gt;pfx - 证书文件(选填, 在微信商户管理界面获取)
&lt;ul&gt;
&lt;li&gt;当不需要调用依赖证书的API时可不填此参数&lt;/li&gt;
&lt;li&gt;若业务流程中使用了依赖证书的API则需要在初始化时传入此参数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;notify_url - 支付结果通知回调地址(选填)
&lt;ul&gt;
&lt;li&gt;可以在初始化的时候传入设为默认值, 不传则需在调用相关API时传入&lt;/li&gt;
&lt;li&gt;调用相关API时传入新值则使用新值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;refund_url - 退款结果通知回调地址(选填)
&lt;ul&gt;
&lt;li&gt;可以在初始化的时候传入设为默认值, 不传则使用微信商户后台配置&lt;/li&gt;
&lt;li&gt;调用相关API时传入新值则使用新值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;spbill_create_ip - IP地址(选填)
&lt;ul&gt;
&lt;li&gt;可以在初始化的时候传入设为默认值, 不传则默认值为127.0.0.1&lt;/li&gt;
&lt;li&gt;调用相关API时传入新值则使用新值&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;证书相关可以查阅：&lt;a href=&quot;https://kf.qq.com/faq/161222NneAJf161222U7fARv.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;什么是API证书？如何获取API证书？&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;如果在接入的时候遇到签名问题，可以使用：&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信支付接口签名校验工具&lt;/a&gt;或&lt;a href=&quot;https://pay.weixin.qq.com/wiki/tools/signverify/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信公众平台支付接口调试工具&lt;/a&gt;进行调试。&lt;/p&gt;
&lt;h2 id=&quot;42-api使用基础&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-api%E4%BD%BF%E7%94%A8%E5%9F%BA%E7%A1%80&quot; aria-label=&quot;42 api使用基础 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 API使用基础&lt;/h2&gt;
&lt;h3 id=&quot;421-网页端&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#421-%E7%BD%91%E9%A1%B5%E7%AB%AF&quot; aria-label=&quot;421 网页端 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.1 网页端&lt;/h3&gt;
&lt;p&gt;API接入手册：&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=4_1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;扫码支付 &gt; 接口规则 &gt; 协议规则&lt;/a&gt;。API列表：&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;扫码支付 &gt; API列表 &gt; 统一下单&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;422-移动原生&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#422-%E7%A7%BB%E5%8A%A8%E5%8E%9F%E7%94%9F&quot; aria-label=&quot;422 移动原生 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.2 移动原生&lt;/h3&gt;
&lt;p&gt;API接入手册：&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;APP支付 &gt; 接口规则 &gt; 协议规则&lt;/a&gt;。API列表：&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;APP支付 &gt; API列表 &gt; 统一下单&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;43-常用接口&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E5%B8%B8%E7%94%A8%E6%8E%A5%E5%8F%A3&quot; aria-label=&quot;43 常用接口 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 常用接口&lt;/h2&gt;
&lt;h3 id=&quot;431-统一下单接口&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#431-%E7%BB%9F%E4%B8%80%E4%B8%8B%E5%8D%95%E6%8E%A5%E5%8F%A3&quot; aria-label=&quot;431 统一下单接口 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3.1 统一下单接口&lt;/h3&gt;
&lt;p&gt;范例代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;prepay_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; code_url&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wxpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unifiedOrder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    out_trade_no&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; orderId&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 微信支付的金额是不带小数位的，所有的小数金额都必须*100转为正整数&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 数值先会被小数点后2位截断或补足，然后转为整数字符串&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 8.8     =&gt; 8.80 =&gt; 880&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 9.24678 =&gt; 9.25 =&gt; 925&lt;/span&gt;
    total_fee&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;price&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toFixed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    trade_type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// NATIVE：扫码支付 | APP：原生支付&lt;/span&gt;
    product_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; productId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    prepayId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prepay_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    codeUrl&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; code_url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;拿到返回值之后，后续根据支付类型不同，处理方式也不一样：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;扫码支付&lt;/strong&gt;&lt;br&gt;
需要将code_url的值，转换为QRCode，后续前端才可以将其渲染到HTML页面上（当然也可以直接将url传给前端，让前端渲染）。这里比较好用的是：&lt;a href=&quot;https://www.npmjs.com/package/qrcode&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;qrcode&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;后端代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; QRCode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;qrcode&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; svg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;QRCode &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;codeUrl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;svg&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;HTML页面：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;head&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;qrcode&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token special-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token value css language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 200px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 200px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;前端代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderXml&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; xmlString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// xmlString: svg content&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; doc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DOMParser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseFromString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xmlString&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/xml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; el &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;el&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ownerDocument&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;importNode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;doc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;documentElement&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;renderXml&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;qrcode&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;extra&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;codeUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;原生支付&lt;/strong&gt;&lt;br&gt;
在统一下单接口完成之后，还需要根据prepay_id来申请唤起微信的参数：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; params &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wxpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAppParamsByPrepay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;prepay_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prepayId&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;432-订单查询接口&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#432-%E8%AE%A2%E5%8D%95%E6%9F%A5%E8%AF%A2%E6%8E%A5%E5%8F%A3&quot; aria-label=&quot;432 订单查询接口 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3.2 订单查询接口&lt;/h3&gt;
&lt;p&gt;范例代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wxpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;orderQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;out_trade_no&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; orderId&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;44-金额问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E9%87%91%E9%A2%9D%E9%97%AE%E9%A2%98&quot; aria-label=&quot;44 金额问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 金额问题&lt;/h2&gt;
&lt;p&gt;在刚才&lt;code class=&quot;language-text&quot;&gt;4.3.1&lt;/code&gt;的例子中，代码里其实已经体现出来了。微信支付的金额和支付宝是不一样的，支付宝的金额就是自然的数额，带小数点后两位。而微信的做法不同，微信要求调用接口下单的时候的支付金额必须不带小数位，所有的金额都是小数点后两位的数字&lt;code class=&quot;language-text&quot;&gt;*100转化为整数&lt;/code&gt;的数额。也就是说下单接口金额为&lt;code class=&quot;language-text&quot;&gt;1&lt;/code&gt;的情况，实际支付的是&lt;code class=&quot;language-text&quot;&gt;0.01&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 微信支付的金额是不带小数位的，所有的小数金额都必须*100转为正整数&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 数值先会被小数点后2位截断或补足，然后转为整数字符串&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 8.8     =&gt; 8.80 =&gt; 880&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 9.24678 =&gt; 9.25 =&gt; 925&lt;/span&gt;
total_fee&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;price&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toFixed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;45-回调处理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#45-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot; aria-label=&quot;45 回调处理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5 回调处理&lt;/h2&gt;
&lt;p&gt;微信的所有API都是使用XML作为输入和输出，因此获得的回调信息也是XML。因为之前的API调用中都有SDK处理完了，所以这里就有点恶心，需要自己处理。&lt;/p&gt;
&lt;p&gt;回调结构：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IResOrderPayed&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    return_code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// SUCCESS&lt;/span&gt;
    return_msg&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// OK&lt;/span&gt;
    appid&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// wx3...&lt;/span&gt;
    mch_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 156..&lt;/span&gt;
    nonce_str&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// cwGl...&lt;/span&gt;
    sign&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// C51A...&lt;/span&gt;
    result_code&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// SUCCESS&lt;/span&gt;
    openid&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// oqvcFj-Uf...&lt;/span&gt;
    is_subscribe&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// N&lt;/span&gt;
    trade_type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// NATIVE&lt;/span&gt;
    bank_type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// OTHERS&lt;/span&gt;
    total_fee&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1，需要 / 100&lt;/span&gt;
    fee_type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// CNY&lt;/span&gt;
    transaction_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 42000004...&lt;/span&gt;
    out_trade_no&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    attach&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// &quot;&quot;&lt;/span&gt;
    time_end&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 2019XXXX144155&lt;/span&gt;
    trade_state&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// SUCCESS&lt;/span&gt;
    cash_fee&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 1，需要 / 100&lt;/span&gt;
    trade_state_desc&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 支付成功&lt;/span&gt;
    cash_fee_type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// CNY&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;5-沙箱使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E6%B2%99%E7%AE%B1%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;5 沙箱使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 沙箱使用&lt;/h1&gt;
&lt;p&gt;微信支付的沙箱和支付宝有点不同，支付宝是完全隔离，从环境、访问地址到账号，支付的支付宝APP全部都是单独分离的。微信则不同，账号、测试用APP都还是原来的微信商户号以及用户真实的微信APP，但访问地址是隔离的，在原来的API地址中间插入&lt;code class=&quot;language-text&quot;&gt;/sandboxnew/&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;虽然易用性上看起来是微信占优，但实际使用上微信的沙箱有相当多的问题，甚至我研发到最后完成，都完全没使用过沙箱，都是使用0.01的金额进行下单测试。&lt;/p&gt;
&lt;h2 id=&quot;51-沙箱申请&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-%E6%B2%99%E7%AE%B1%E7%94%B3%E8%AF%B7&quot; aria-label=&quot;51 沙箱申请 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 沙箱申请&lt;/h2&gt;
&lt;p&gt;和支付宝一样，微信支付的沙箱使用不需要额外申请。&lt;/p&gt;
&lt;h2 id=&quot;52-沙箱使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E6%B2%99%E7%AE%B1%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;52 沙箱使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 沙箱使用&lt;/h2&gt;
&lt;p&gt;使用方面，可以看一篇第三方的教程：&lt;a href=&quot;https://juejin.im/post/5bea7c1d6fb9a04a053f36c3&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;浅析微信支付：如何使用沙箱环境测试&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在使用刚才说的SDK的情况下，只需要在SDK初始化的地方做点调整即可：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    appid&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;appId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    mchid&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mchId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    partnerKey&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;appSecret&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pfx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; LibFs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;LibPath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../../../pem/wxpay/apiclient_key.pem&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    notify_url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;callbackUrl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    spbill_create_ip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;allowedIp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Tenpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;IConfig&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// wxpay&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isSandbox&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    tenpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isTest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSignkey&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;res&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sandbox_signkey&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wxpay &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tenpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;partnerKey&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sandbox&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isTest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;wxpay &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tenpay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isTest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;沙箱每次使用的秘钥（商户的API秘钥）和正式环境不一样，正式环境是配置死的，直接拿下来用即可。而沙箱则需要先使用正式环境的商户秘钥去调用&lt;code class=&quot;language-text&quot;&gt;getSignkey&lt;/code&gt;获取沙箱使用的临时商户秘钥，才可以后续继续调用API。&lt;/p&gt;
&lt;h2 id=&quot;53-沙箱问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#53-%E6%B2%99%E7%AE%B1%E9%97%AE%E9%A2%98&quot; aria-label=&quot;53 沙箱问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3 沙箱问题&lt;/h2&gt;
&lt;p&gt;理解了沙箱的隔离以及如何初始化沙箱SDK之后，如果直接实际调用的话，还是会遇到问题：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;沙箱支付金额(1)无效，请检查需要验收的case&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;参见：&lt;a href=&quot;https://github.com/Wechat-Group/WxJava/issues/668&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信支付的沙箱环境能否使用？#668&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这里还需要额外做一个操作：在&lt;code class=&quot;language-text&quot;&gt;微信支付商户接入验收助手&lt;/code&gt;这个公众号申请你的验收case，写入验收金额作为use case。后续在沙箱环境做测试的时候，金额必须完全符合之前申请的验收case，否则报错。&lt;/p&gt;
&lt;h1 id=&quot;6-错误处理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86&quot; aria-label=&quot;6 错误处理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. 错误处理&lt;/h1&gt;
&lt;h2 id=&quot;61-回调处理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot; aria-label=&quot;61 回调处理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 回调处理&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 业务处理&lt;/span&gt;
    
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/xml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;xml&gt;
&amp;lt;return_code&gt;&amp;lt;![CDATA[SUCCESS]]&gt;&amp;lt;/return_code&gt;
&amp;lt;return_msg&gt;&amp;lt;![CDATA[OK]]&gt;&amp;lt;/return_msg&gt;
&amp;lt;/xml&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;application/xml&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;lt;xml&gt;
&amp;lt;return_code&gt;&amp;lt;![CDATA[FAIL]]&gt;&amp;lt;/return_code&gt;
&amp;lt;return_msg&gt;&amp;lt;![CDATA[&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;]]&gt;&amp;lt;/return_msg&gt;
&amp;lt;/xml&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;62-修复订单&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-%E4%BF%AE%E5%A4%8D%E8%AE%A2%E5%8D%95&quot; aria-label=&quot;62 修复订单 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 修复订单&lt;/h2&gt;
&lt;p&gt;在某些情况下，回调可能没有收到，或者一直报错导致回调没有正常处理。表现在用户视角，就是支付完成后订单状态无法正常改为支付完成（也就不会发货）。这是很糟糕的，因此需要制作修复订单功能。&lt;/p&gt;
&lt;p&gt;客户端在检查到订单状态为等待支付之后，可以提供一个入口给用户，用户点击之后，应用后端应该向支付宝查询订单信息，如果在支付宝这里已经是&lt;code class=&quot;language-text&quot;&gt;已支付&lt;/code&gt;而在应用这边还是&lt;code class=&quot;language-text&quot;&gt;等待支付&lt;/code&gt;的话，就立即将业务订单改为已支付，并向用户发货。&lt;/p&gt;
&lt;h1 id=&quot;7-上线生效&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-%E4%B8%8A%E7%BA%BF%E7%94%9F%E6%95%88&quot; aria-label=&quot;7 上线生效 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. 上线生效&lt;/h1&gt;
&lt;p&gt;微信支付应该是在应用申请审核通过的时候就直接上线了，不需要额外操作。&lt;/p&gt;
&lt;h1 id=&quot;appendix&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#appendix&quot; aria-label=&quot;appendix permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Appendix&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Pay/Vendor_Service_Center.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信APP支付接入商户服务中心&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/753393a0514a&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信APP支付接入&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/59c4bc7df265da06434b8c2b&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信App支付全解析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.leapcloud.cn/website/docs/doc_config/wxwangyezf/wxwangyezhifu.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信公众号支付配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.leapcloud.cn/website/docs/doc_config/wxappzf/weixinapp.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信APP支付配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.leapcloud.cn/website/docs/doc_config/keystorecreate/keystorecreate.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Android App 签名生成教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kf.qq.com/faq/161222NneAJf161222U7fARv.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;什么是API证书？如何获取API证书？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信网页开发 &gt; 网页授权&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/5bea7c1d6fb9a04a053f36c3&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;浅析微信支付：如何使用沙箱环境测试&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Wechat-Group/WxJava/issues/668&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信支付的沙箱环境能否使用？#668&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=20_1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信支付接口签名校验工具&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pay.weixin.qq.com/wiki/tools/signverify/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信公众平台支付接口调试工具&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.51cto.com/xihan/2096880&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信支付接口返回“签名错误”的排查方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/yhm_brave/article/details/70240935&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信支付统一下单，签名错误&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/qq_35624642/article/details/53667679&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;微信支付统一下单，签名错误（生成的签名和测试工具生成的一样还报错）解决方法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[支付宝接入]]></title><link>https://xenojoshua.com/posts/2019/12/alipay</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/12/alipay</guid><pubDate>Fri, 27 Dec 2019 02:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%94%AF%E4%BB%98%E6%B5%81%E7%A8%8B&quot;&gt;2. 支付流程&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E7%BD%91%E9%A1%B5%E7%AB%AF&quot;&gt;2.1 网页端&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E7%A7%BB%E5%8A%A8%E5%8E%9F%E7%94%9F&quot;&gt;2.2 移动原生&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot;&gt;3. 准备工作&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E8%B4%A6%E5%8F%B7%E7%94%B3%E8%AF%B7&quot;&gt;3.1 账号申请&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E5%BA%94%E7%94%A8%E7%94%B3%E8%AF%B7&quot;&gt;3.2 应用申请&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E7%A7%98%E9%92%A5%E7%94%B3%E8%AF%B7&quot;&gt;3.3 秘钥申请&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-api--sdk&quot;&gt;4. API &amp;#x26; SDK&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-sdk%E9%80%89%E6%8B%A9&quot;&gt;4.1 SDK选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-api%E4%BD%BF%E7%94%A8%E5%9F%BA%E7%A1%80&quot;&gt;4.2 API使用基础&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E5%B8%B8%E7%94%A8%E6%8E%A5%E5%8F%A3&quot;&gt;4.3 常用接口&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#431-pc%E7%BD%91%E9%A1%B5%E6%94%AF%E4%BB%98%E4%B8%8B%E5%8D%95&quot;&gt;4.3.1 PC网页支付下单&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#432-app%E6%94%AF%E4%BB%98%E4%B8%8B%E5%8D%95&quot;&gt;4.3.2 APP支付下单&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#433-%E6%94%AF%E4%BB%98%E5%AE%9D%E8%AE%A2%E5%8D%95%E6%9F%A5%E8%AF%A2&quot;&gt;4.3.3 支付宝订单查询&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot;&gt;4.4 回调处理&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#441-return_url&quot;&gt;4.4.1 return_url&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#442-notify_url&quot;&gt;4.4.2 notify_url&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E6%B2%99%E7%AE%B1%E4%BD%BF%E7%94%A8&quot;&gt;5. 沙箱使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-%E6%B2%99%E7%AE%B1%E7%94%B3%E8%AF%B7&quot;&gt;5.1 沙箱申请&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E6%B2%99%E7%AE%B1%E7%AE%A1%E7%90%86&quot;&gt;5.2 沙箱管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#53-%E6%B2%99%E7%AE%B1%E6%94%AF%E4%BB%98&quot;&gt;5.3 沙箱支付&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86&quot;&gt;6. 错误处理&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot;&gt;6.1 回调处理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-%E4%BF%AE%E5%A4%8D%E8%AE%A2%E5%8D%95&quot;&gt;6.2 修复订单&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-%E4%B8%8A%E7%BA%BF%E7%94%9F%E6%95%88&quot;&gt;7. 上线生效&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#appendix&quot;&gt;Appendix&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;支付宝的接入，权当笔记。&lt;/p&gt;
&lt;h1 id=&quot;2-支付流程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%94%AF%E4%BB%98%E6%B5%81%E7%A8%8B&quot; aria-label=&quot;2 支付流程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 支付流程&lt;/h1&gt;
&lt;h3 id=&quot;21-网页端&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E7%BD%91%E9%A1%B5%E7%AB%AF&quot; aria-label=&quot;21 网页端 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 网页端&lt;/h3&gt;
&lt;p&gt;PC网页端的支付，官方文档在：&lt;a href=&quot;https://docs.open.alipay.com/270/105899/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开发文档 / 电脑网站支付 / 快速接入&lt;/a&gt;。这篇应该说是完整的tutorial，里面也包含了支付的整个流程。&lt;/p&gt;
&lt;p&gt;官方配图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/alipay/alipay_pc_process.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;总觉得支付宝的这个流程图有点问题，并没有很好解释流程顺序。这里整理一个文字版。&lt;/p&gt;
&lt;p&gt;流程涉及到几个角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PC网站网页&lt;/li&gt;
&lt;li&gt;PC网站后台&lt;/li&gt;
&lt;li&gt;支付宝系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;支付流程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;打开PC网站网页的商品页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;对商品进行下单&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;发送下单请求到PC网站后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;在自身系统内生成订单（生成内部订单号），并返回给网页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;获得内部订单信息，并将用户导向到支付页面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;确认订单内容，并开始付款流程&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;发起支付请求到PC网站后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;向支付宝系统发起下单请求
&lt;ul&gt;
&lt;li&gt;其中附加了notify_url，会在支付完成后收到回调&lt;/li&gt;
&lt;li&gt;且附加了return_url，会在支付完成后将页面导向到该页面&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;将支付宝返回的信息交付给PC网站网页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站网页&lt;/code&gt;收到支付宝返回信息，使用其中的信息将页面导向到支付宝的付款页面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;在支付宝的付款页面完成付款&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;支付宝系统&lt;/code&gt;确认支付完成，将用户网页重定向到return_url的页面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;支付宝系统&lt;/code&gt;确认支付完成，向notify_url发送回调信息&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;PC网站后台&lt;/code&gt;验证支付宝回调完成，标记订单状态为已支付&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;22-移动原生&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E7%A7%BB%E5%8A%A8%E5%8E%9F%E7%94%9F&quot; aria-label=&quot;22 移动原生 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 移动原生&lt;/h3&gt;
&lt;p&gt;移动端原生支付和PC网页支付差异不是很大，官方文档在：&lt;a href=&quot;https://docs.open.alipay.com/204/105297/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开发文档 / App支付 / 快速接入&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;官方配图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/alipay/alipay_native_process.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;这个图还算可以，老样子整理一个文字版。&lt;/p&gt;
&lt;p&gt;流程涉及到几个角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;手机APP&lt;/li&gt;
&lt;li&gt;APP后台&lt;/li&gt;
&lt;li&gt;支付宝系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;支付流程如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;打开手机APP的商品页&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;对商品进行下单&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;手机APP&lt;/code&gt;发送下单请求到APP后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;APP后台&lt;/code&gt;在自身系统内生成订单（生成内部订单号），并返回给APP&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;手机APP&lt;/code&gt;获得内部订单信息，并将用户导向到支付页面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;确认订单内容，并开始付款流程&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;手机APP&lt;/code&gt;发起支付请求到APP后台&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;APP后台&lt;/code&gt;向支付宝系统发起下单请求，获得支付宝APP唤醒参数，并交付给手机APP
&lt;ul&gt;
&lt;li&gt;其中附加了notify_url，会在支付完成后收到回调&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;手机APP&lt;/code&gt;收到支付宝返回信息，使用其中的参数唤醒支付宝APP&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;用户&lt;/code&gt;在支付宝APP完成付款&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;支付宝系统&lt;/code&gt;确认支付完成，返回手机APP&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;支付宝系统&lt;/code&gt;确认支付完成，向notify_url发送回调信息&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;APP后台&lt;/code&gt;验证支付宝回调完成，标记订单状态为已支付&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-准备工作&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%87%86%E5%A4%87%E5%B7%A5%E4%BD%9C&quot; aria-label=&quot;3 准备工作 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 准备工作&lt;/h1&gt;
&lt;p&gt;在正式接入支付宝之前，还需要做一些准备工作，主要是一系列账号、应用、秘钥的申请。&lt;/p&gt;
&lt;h2 id=&quot;31-账号申请&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E8%B4%A6%E5%8F%B7%E7%94%B3%E8%AF%B7&quot; aria-label=&quot;31 账号申请 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 账号申请&lt;/h2&gt;
&lt;p&gt;公司账号申请都是老板做的事情，虽然繁琐但和技术人员没什么关系。创建完成后可以通过&lt;a href=&quot;https://docs.open.alipay.com/200/ug05sr/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;账户成员管理&lt;/a&gt;将员工账号加入到管理群组里，方便员工直接进行开发。&lt;/p&gt;
&lt;p&gt;员工可以通过&lt;a href=&quot;https://openhome.alipay.com/platform/manageHome.htm&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;这个链接&lt;/a&gt;，登入到支付宝进行账号和应用的管理。&lt;/p&gt;
&lt;h2 id=&quot;32-应用申请&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E5%BA%94%E7%94%A8%E7%94%B3%E8%AF%B7&quot; aria-label=&quot;32 应用申请 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 应用申请&lt;/h2&gt;
&lt;p&gt;见官方文档：&lt;a href=&quot;https://docs.open.alipay.com/200/105310&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开发文档 / 开发指南 / 创建应用&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;刚创建出来的应用是没有任何功能的，支付宝的各种功能（包括最基础的支付功能）都是支付应用下的&lt;code class=&quot;language-text&quot;&gt;应用功能&lt;/code&gt;，一般来说每个都需要单独开通，某些开通还需要一定的条件，比如说网页支付开通的话你必须首先要有一个已经上线的网页而且要有明确的支付功能（申请失败如下）。等等。见：&lt;a href=&quot;https://docs.open.alipay.com/200/105314/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;签约功能&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/alipay/alipay_pc_app_failure.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;在这一步最重要的是要把支付应用的APP_ID记录下来。&lt;/p&gt;
&lt;h2 id=&quot;33-秘钥申请&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E7%A7%98%E9%92%A5%E7%94%B3%E8%AF%B7&quot; aria-label=&quot;33 秘钥申请 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 秘钥申请&lt;/h2&gt;
&lt;p&gt;见官方文档：&lt;a href=&quot;https://docs.open.alipay.com/291/105971/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开发文档 / 签名专区 / 第一步：生成 RSA 密钥&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;官方有提供一个工具&lt;code class=&quot;language-text&quot;&gt;支付宝开放平台开发助手&lt;/code&gt;，可以用这个工具进行秘钥制作，比较方便：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&amp;#x26;platform=win&amp;#x26;channelType=WEB&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;WIN版本&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ideservice.alipay.com/ide/getPluginUrl.htm?clientType=assistant&amp;#x26;platform=mac&amp;#x26;channelType=WEB&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;MAC版本&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后续研发上遇到签名问题可以参考：&lt;a href=&quot;https://docs.open.alipay.com/291/106096/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;自助排查&lt;/a&gt;以及&lt;a href=&quot;https://docs.open.alipay.com/291/106098/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;常见问题&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这一步操作完成后应该会获得三个文件，需要妥善保存：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;alipay的公钥
&lt;ul&gt;
&lt;li&gt;文件以&lt;code class=&quot;language-text&quot;&gt;-----BEGIN PUBLIC KEY-----&lt;/code&gt;开头&lt;/li&gt;
&lt;li&gt;文件以&lt;code class=&quot;language-text&quot;&gt;-----END PUBLIC KEY-----&lt;/code&gt;结尾&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;应用的公钥
&lt;ul&gt;
&lt;li&gt;文件以&lt;code class=&quot;language-text&quot;&gt;-----BEGIN PUBLIC KEY-----&lt;/code&gt;开头&lt;/li&gt;
&lt;li&gt;文件以&lt;code class=&quot;language-text&quot;&gt;-----END PUBLIC KEY-----&lt;/code&gt;结尾&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;应用的私钥
&lt;ul&gt;
&lt;li&gt;文件以&lt;code class=&quot;language-text&quot;&gt;-----BEGIN RSA PRIVATE KEY-----&lt;/code&gt;开头&lt;/li&gt;
&lt;li&gt;文件以&lt;code class=&quot;language-text&quot;&gt;-----END RSA PRIVATE KEY-----&lt;/code&gt;结尾&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下载下来的公钥和私钥都是不断行的连续字符串，还需要借助像是&lt;a href=&quot;https://www.samltool.com/format_privatekey.php&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Online tool to format private key. - SAMLTool.com&lt;/a&gt;这样的工具进行格式转换，断行。如果没有文件头和文件尾的话，还需要手动添加。&lt;/p&gt;
&lt;h1 id=&quot;4-api--sdk&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-api--sdk&quot; aria-label=&quot;4 api  sdk permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. API &amp;#x26; SDK&lt;/h1&gt;
&lt;h2 id=&quot;41-sdk选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-sdk%E9%80%89%E6%8B%A9&quot; aria-label=&quot;41 sdk选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 SDK选择&lt;/h2&gt;
&lt;p&gt;Node.js进行开发的话，有两个npm库可选：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/alipay-node-sdk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;alipay-node-sdk&lt;/a&gt;：这个库非官方，但维护的很好，而且使用的人也不少，可以一用&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/alipay-sdk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Alipay SDK&lt;/a&gt;：这个库是官方的，但封装得还没有上一个好，而且文档也很糟糕，但毕竟是官方的，所以还是首选&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;官方SDK的使用需要了解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.yuque.com/chenqiu/alipay-node-sdk/config-sdk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;SDK 配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.yuque.com/chenqiu/alipay-node-sdk/with_biz_content&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;包含业务参数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.yuque.com/chenqiu/alipay-node-sdk/without_biz_content&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;不包含业务参数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.yuque.com/chenqiu/alipay-node-sdk/page_api&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;页面类接口调用&lt;/a&gt;：其实后续PC和APP下单用的都是这种模式，调用支付宝接口后获得对应的信息，然后返回给应用客户端，让它们触发后续流程&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.yuque.com/chenqiu/alipay-node-sdk/notify_verify&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;通知验签&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，官方SDK有一个比较严重的BUG：&lt;a href=&quot;https://github.com/alipay/alipay-sdk-nodejs-all/issues/45&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;设置了 passbackParams 会导致 alipaySdk.checkNotifySign 失败 #45&lt;/a&gt;，会直接影响使用，需要注意。&lt;/p&gt;
&lt;p&gt;解决方案：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;passback_params &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;encodeURIComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;passback_params&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; verified &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; alipaySdk&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;checkNotifySign&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;42-api使用基础&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-api%E4%BD%BF%E7%94%A8%E5%9F%BA%E7%A1%80&quot; aria-label=&quot;42 api使用基础 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 API使用基础&lt;/h2&gt;
&lt;p&gt;官方的API文档在：&lt;a href=&quot;https://docs.open.alipay.com/api_1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;支付API&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;支付宝的API的接口，参数都分为&lt;code class=&quot;language-text&quot;&gt;公共请求参数&lt;/code&gt;以及&lt;code class=&quot;language-text&quot;&gt;请求参数&lt;/code&gt;。简单点来说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公共请求参数：支付宝级别比较顶层的参数，比如说：app_id、sign等&lt;/li&gt;
&lt;li&gt;请求参数：非公共请求参数之外的其他一切参数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;请求参数会放在公共请求参数的&lt;code class=&quot;language-text&quot;&gt;biz_content&lt;/code&gt;里，至于怎么放进去的可以不用关心，SDK都会直接封装掉。&lt;/p&gt;
&lt;p&gt;API的测试可以通过：&lt;a href=&quot;https://openhome.alipay.com/platform/demoManage.htm#/alipay.trade.page.pay&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;在线调试(Beta)&lt;/a&gt;来模拟使用。&lt;/p&gt;
&lt;h2 id=&quot;43-常用接口&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E5%B8%B8%E7%94%A8%E6%8E%A5%E5%8F%A3&quot; aria-label=&quot;43 常用接口 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 常用接口&lt;/h2&gt;
&lt;p&gt;官方SDK的初始化，沙箱和正式用的是两套秘钥，这块需要动态处理下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AlipaySdk &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;alipay-sdk/lib/alipay&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; AlipayFormData &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;alipay-sdk/lib/form&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vendorConfig &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getVendor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Constant&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VENDOR_ALIPAY_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; IVendorConfigAlipay&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; isSandbox &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getRaw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sandbox&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notifyUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;callbackUrl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;returnUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;returnUrl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pubKeyPath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LibPath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    __dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../../../pem/alipay&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isSandbox &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sandbox/alipay.pub.txt&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;alipay.pub.txt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; priKeyPath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; LibPath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    __dirname&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;../../../pem/alipay&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; isSandbox &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sandbox/app.pri.txt&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;app.pri.txt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gateway &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; isSandbox
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://openapi.alipaydev.com/gateway.do&quot;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://openapi.alipay.com/gateway.do&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alipay::sdk::pubKeyPath&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pubKeyPath&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alipay::sdk::priKeyPath&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; priKeyPath&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alipay::sdk::gateway&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gateway&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;aliPay &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AlipaySdk&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    appId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; vendorConfig&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;appId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    alipayPublicKey&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; LibFs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pubKeyPath&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    privateKey&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; LibFs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readFileSync&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;priKeyPath&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    gateway&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gateway&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    signType&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;RSA2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;431-pc网页支付下单&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#431-pc%E7%BD%91%E9%A1%B5%E6%94%AF%E4%BB%98%E4%B8%8B%E5%8D%95&quot; aria-label=&quot;431 pc网页支付下单 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3.1 PC网页支付下单&lt;/h3&gt;
&lt;p&gt;文档在：&lt;a href=&quot;https://docs.open.alipay.com/api_1/alipay.trade.page.pay&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;alipay.trade.page.pay&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;范例代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; formData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AlipayFormData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
formData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addField&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;returnUrl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;returnUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
formData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addField&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;notifyUrl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notifyUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
formData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addField&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bizContent&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    outTradeNo&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; orderId&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    productCode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FAST_INSTANT_TRADE_PAY&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    totalAmount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    subject&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; desc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    passbackParams&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;encodeURIComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    timeoutExpress&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;seconds &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    qrPayMode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;aliPay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;alipay.trade.page.pay&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;formData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; log&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;info&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;范例返回：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;form&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://openapi.alipaydev.com/gateway.do?method=alipay.trade.page.pay&amp;amp;app_id=...&amp;amp;charset=utf-8&amp;amp;version=1.0&amp;amp;sign_type=RSA2&amp;amp;timestamp=2019-XX-XX%2015%3A20%3A24&amp;amp;return_url=...&amp;amp;notify_url=...&amp;amp;sign=...&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;method&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;alipaySDKSubmit1577431224474&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;alipaySDKSubmit1577431224474&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;alipay_sdk&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;alipay-sdk-nodejs-3.0.8&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;hidden&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;biz_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;{&lt;span class=&quot;token entity named-entity&quot; title=&quot;&amp;quot;&quot;&gt;&amp;amp;quot;&lt;/span&gt;out_trade_no&lt;span class=&quot;token entity named-entity&quot; title=&quot;&amp;quot;&quot;&gt;&amp;amp;quot;&lt;/span&gt;:143123,&lt;span class=&quot;token entity named-entity&quot; title=&quot;&amp;quot;&quot;&gt;&amp;amp;quot;&lt;/span&gt;product_code&lt;span class=&quot;token entity named-entity&quot; title=&quot;&amp;quot;&quot;&gt;&amp;amp;quot;&lt;/span&gt;:&lt;span class=&quot;token entity named-entity&quot; title=&quot;&amp;quot;&quot;&gt;&amp;amp;quot;&lt;/span&gt;FAST_INSTANT_TRADE_PAY...}&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;forms&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alipaySDKSubmit1577431224474&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;返回的是一个字符串，这串字符串交付给网页，让JS直接append到当前页面上，就会进行跳转（form.submit），到支付宝的页面让用户付款。&lt;/p&gt;
&lt;h3 id=&quot;432-app支付下单&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#432-app%E6%94%AF%E4%BB%98%E4%B8%8B%E5%8D%95&quot; aria-label=&quot;432 app支付下单 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3.2 APP支付下单&lt;/h3&gt;
&lt;p&gt;文档在：&lt;a href=&quot;https://docs.open.alipay.com/api_1/alipay.trade.app.pay&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;alipay.trade.app.pay&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;范例代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; formData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AlipayFormData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
formData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setMethod&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
formData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addField&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;notifyUrl&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;notifyUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
formData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addField&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;bizContent&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    outTradeNo&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; orderId&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    productCode&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;QUICK_MSECURITY_PAY&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    totalAmount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    subject&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; desc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    passbackParams&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;encodeURIComponent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    timeoutExpress&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;seconds &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;aliPay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;alipay.trade.app.pay&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;formData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; log&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;info&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;范例返回：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;https://openapi.alipaydev.com/gateway.do?method&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;alipay.trade.app.pay&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;app_id&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;charset&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;utf-8&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;sign_type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;RSA2&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;timestamp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2019&lt;/span&gt;-XX-XX%2015%3A23%3A25&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;notify_url&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这一串字符串需要去掉头部的gateway：&lt;code class=&quot;language-text&quot;&gt;https://openapi.alipaydev.com/gateway.do?&lt;/code&gt;，只需要把剩下的参数部分交付给移动APP即可，移动APP会使用这些参数唤醒支付宝APP。&lt;/p&gt;
&lt;h3 id=&quot;433-支付宝订单查询&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#433-%E6%94%AF%E4%BB%98%E5%AE%9D%E8%AE%A2%E5%8D%95%E6%9F%A5%E8%AF%A2&quot; aria-label=&quot;433 支付宝订单查询 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3.3 支付宝订单查询&lt;/h3&gt;
&lt;p&gt;文档在：&lt;a href=&quot;https://docs.open.alipay.com/api_1/alipay.trade.query&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;alipay.trade.query&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;范例代码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;aliPay&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alipay.trade.query&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    bizContent&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;out_trade_no&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; orderId&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;log&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;info&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;log&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;返回的结果详见官方API文档。&lt;/p&gt;
&lt;h2 id=&quot;44-回调处理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot; aria-label=&quot;44 回调处理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 回调处理&lt;/h2&gt;
&lt;h3 id=&quot;441-return_url&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#441-return_url&quot; aria-label=&quot;441 return_url permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4.1 return_url&lt;/h3&gt;
&lt;p&gt;在return_url上收到的参数如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;charset&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;out_trade_no&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;143123&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;method&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;alipay.trade.page.pay.return&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;total_amount&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sign&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;B5wBu/icxG9u12XyBKUu...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;auth_app_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;201...422&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;app_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;201...422&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sign_type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;RSA2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;seller_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;208...342&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;timestamp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2019-XX-XX 15:48:17&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;442-notify_url&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#442-notify_url&quot; aria-label=&quot;442 notify_url permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4.2 notify_url&lt;/h3&gt;
&lt;p&gt;在notify_url上收到的参数如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; 
  &lt;span class=&quot;token property&quot;&gt;&quot;gmt_create&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2019-XX-XX 15:48:01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;charset&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;subject&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;测试商品名&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;sign&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;OMcW3K9Sy...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;buyer_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;208...342&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;body&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;测试商品描述&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;invoice_amount&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;notify_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2019...589&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;fund_bill_list&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;[{\&quot;amount\&quot;:\&quot;0.01\&quot;,\&quot;fundChannel\&quot;:\&quot;ALIPAYACCOUNT\&quot;}]&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;notify_type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;trade_status_sync&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;trade_status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;TRADE_SUCCESS&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;receipt_amount&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;app_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;201...422&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;buyer_pay_amount&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;sign_type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;RSA2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;seller_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;208...342&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;gmt_payment&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2019-XX-XX 15:48:15&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;notify_time&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2019-XX-XX 15:48:16&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;passback_params&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;%7B%22orderId%22%3A143123%2C%22salt%22%3A%221fvwtia2k4nuszx2%22%7D&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;out_trade_no&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;143123&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;total_amount&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;trade_no&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;2019...383&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;auth_app_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;201...422&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;point_amount&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;0.00&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;5-沙箱使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E6%B2%99%E7%AE%B1%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;5 沙箱使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 沙箱使用&lt;/h1&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://docs.open.alipay.com/200/105311/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开发文档 / 开发指南 / 使用沙箱环境&lt;/a&gt;。移动APP的沙箱使用还需要一些额外的调整：&lt;a href=&quot;https://docs.open.alipay.com/204/106450/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开发文档 / App支付 / 沙箱联调指南&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;51-沙箱申请&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-%E6%B2%99%E7%AE%B1%E7%94%B3%E8%AF%B7&quot; aria-label=&quot;51 沙箱申请 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 沙箱申请&lt;/h2&gt;
&lt;p&gt;沙箱不需要额外申请，在支付应用创建完成之后，其沙箱自动创建完成。&lt;/p&gt;
&lt;h2 id=&quot;52-沙箱管理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E6%B2%99%E7%AE%B1%E7%AE%A1%E7%90%86&quot; aria-label=&quot;52 沙箱管理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 沙箱管理&lt;/h2&gt;
&lt;p&gt;沙箱有单独的管理页面，上面主要要处理几个事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;获取沙箱的APP ID；沙箱应用是单独的应用，和正式应用是隔离的，在沙箱环境使用正式应用的APP ID会告知没有该应用，反之亦然&lt;/li&gt;
&lt;li&gt;制作沙箱单独的秘钥；该秘钥和正式环境是隔离的，需要单独制作&lt;/li&gt;
&lt;li&gt;获取沙箱支付宝APP的账号和密码以及支付密码；在测试的时候会使用到&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;53-沙箱支付&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#53-%E6%B2%99%E7%AE%B1%E6%94%AF%E4%BB%98&quot; aria-label=&quot;53 沙箱支付 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3 沙箱支付&lt;/h2&gt;
&lt;p&gt;沙箱环境有单独的一个调试用支付宝APP（用正常的支付宝APP扫码会失败，也无法被沙箱应用唤醒），只有android版本：&lt;a href=&quot;https://sandbox.alipaydev.com/user/downloadApp.htm&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;下载链接&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在沙箱管理页面上能获取到对应的账号信息等。使用这些信息登入支付宝沙箱APP，然后就可以进行测试支付了。&lt;/p&gt;
&lt;h1 id=&quot;6-错误处理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86&quot; aria-label=&quot;6 错误处理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. 错误处理&lt;/h1&gt;
&lt;h2 id=&quot;61-回调处理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-%E5%9B%9E%E8%B0%83%E5%A4%84%E7%90%86&quot; aria-label=&quot;61 回调处理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 回调处理&lt;/h2&gt;
&lt;p&gt;无论对错，业务服务器后端都需要以&lt;code class=&quot;language-text&quot;&gt;text/plain&lt;/code&gt;的格式响应，如果回调处理没有问题，就返回&lt;code class=&quot;language-text&quot;&gt;success&lt;/code&gt;，如果报错，则返回&lt;code class=&quot;language-text&quot;&gt;fail&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 在这里处理业务&lt;/span&gt;

    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text/plain&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;success&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text/plain&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fail&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;62-修复订单&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-%E4%BF%AE%E5%A4%8D%E8%AE%A2%E5%8D%95&quot; aria-label=&quot;62 修复订单 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 修复订单&lt;/h2&gt;
&lt;p&gt;在某些情况下，回调可能没有收到，或者一直报错导致回调没有正常处理。表现在用户视角，就是支付完成后订单状态无法正常改为支付完成（也就不会发货）。这是很糟糕的，因此需要制作修复订单功能。&lt;/p&gt;
&lt;p&gt;客户端在检查到订单状态为等待支付之后，可以提供一个入口给用户，用户点击之后，应用后端应该向支付宝查询订单信息，如果在支付宝这里已经是&lt;code class=&quot;language-text&quot;&gt;已支付&lt;/code&gt;而在应用这边还是&lt;code class=&quot;language-text&quot;&gt;等待支付&lt;/code&gt;的话，就立即将业务订单改为已支付，并向用户发货。&lt;/p&gt;
&lt;h1 id=&quot;7-上线生效&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-%E4%B8%8A%E7%BA%BF%E7%94%9F%E6%95%88&quot; aria-label=&quot;7 上线生效 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. 上线生效&lt;/h1&gt;
&lt;p&gt;开发完成（甚至在这之前）就可以&lt;a href=&quot;https://docs.open.alipay.com/200/golive/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;上线应用&lt;/a&gt;，之前在申请应用的时候提到过的功能开通，签约等，很大一部分都需要应用上线之后才可以做，所以这个操作可以尽早。最基础的支付功能基本上签约没什么难度，早点签约早点开通。&lt;/p&gt;
&lt;h1 id=&quot;appendix&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#appendix&quot; aria-label=&quot;appendix permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Appendix&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/weibo1230123/article/details/80214424&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;支付宝和微信的支付流程图&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/xch-yang/p/10336922.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;手把手教你接入支付宝支付&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/luckyyang/p/9517402.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;支付宝支付之扫码支付（电脑网站支付）、H5支付（手机网站支付）相关业务流程分析总结&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://my.oschina.net/u/2428791/blog/617651&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;支付宝支付接口中notify_url 与 return_url 的区别&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Docker Registry 的简单使用]]></title><link>https://xenojoshua.com/posts/2019/12/docker-registry</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/12/docker-registry</guid><pubDate>Thu, 26 Dec 2019 03:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85--%E5%90%AF%E5%8A%A8&quot;&gt;2. 安装 &amp;#x26; 启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E8%AE%BF%E9%97%AE%E9%99%90%E5%88%B6&quot;&gt;3. 访问限制&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-api&quot;&gt;3. API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E5%88%A0%E9%99%A4%E9%95%9C%E5%83%8F&quot;&gt;4. 删除镜像&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Docker和镜像在工作中是越来越常见了，而镜像仓库的需求也变得越来越常见。Docker官方给的解决方案是私有Registry仓库，官方也给了镜像进行对应的使用。但不得不说Docker的Registry是真的不好用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有UI界面&lt;/li&gt;
&lt;li&gt;只有很弱的访问权限限制&lt;/li&gt;
&lt;li&gt;所有接口都必须通过HTTP请求方式进行，没有提供命令行工具等简化操作&lt;/li&gt;
&lt;li&gt;没有删除镜像的手段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外还有很多，这里就不一并列举了。&lt;/p&gt;
&lt;p&gt;因此，市面上也有不少alternative替代方案，做的最好的应该是&lt;a href=&quot;https://goharbor.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;harbor&lt;/a&gt;。如果是大型企业或者是有比较严谨的权限控制需求的话，推荐使用harbor。&lt;/p&gt;
&lt;p&gt;但针对小公司来说，更简单快速的部署和更简单的运维是相对来说更重要的事情，因此Docker Registry的使用也是有市场的。这里就简单做下使用上的介绍。&lt;/p&gt;
&lt;h1 id=&quot;2-安装--启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85--%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;2 安装  启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 安装 &amp;#x26; 启动&lt;/h1&gt;
&lt;p&gt;使用的还是官方的镜像：&lt;a href=&quot;https://hub.docker.com/_/registry&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;registry&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://docs.docker.com/registry/deploying/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deploy a registry server&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;启动命令：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; network create registry

$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; docker_registry &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--network&lt;/span&gt; registry &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--restart&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;always &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15000&lt;/span&gt;:5000 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /tmp/registry/auth:/data/registry/auth &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /tmp/registry/data:/var/lib/registry &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /tmp/registry/config.yml:/etc/docker/registry/config.yml &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;REGISTRY_AUTH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;htpasswd &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;REGISTRY_AUTH_HTPASSWD_REALM&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Registry Realm&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;REGISTRY_AUTH_HTPASSWD_PATH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/data/registry/auth/htpasswd &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    registry:2.7.1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;容器内配置文件的位置：&lt;code class=&quot;language-text&quot;&gt;/etc/docker/registry/config.yml&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;当前例子中使用的是没有前置proxy，并且仅设置了最简单的用户名密码访问限制的情况。关于这块的访问限制相关，更详细的内容可以查看官方文档：&lt;a href=&quot;https://docs.docker.com/registry/deploying/#restricting-access&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Restricting access&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;生成秘钥可以使用命令：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--entrypoint&lt;/span&gt; htpasswd &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    registry:2.7.1 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-Bbn&lt;/span&gt; username password &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; /tmp/registry/auth/htpasswd&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果需要结合nginx使用的话（一般推荐这样做），需要参见：&lt;a href=&quot;https://docs.docker.com/registry/recipes/nginx/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Authenticate proxy with nginx&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;参考配置文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nginx&quot;&gt;&lt;pre class=&quot;language-nginx&quot;&gt;&lt;code class=&quot;language-nginx&quot;&gt;&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;events&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;worker_connections&lt;/span&gt;  &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;http&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;upstream&lt;/span&gt; docker-registry&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt; registry:5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;## Set a variable to help us decide if we need to add the&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;## &apos;Docker-Distribution-Api-Version&apos; header.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;## The registry always sets this header.&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;## In the case of nginx performing auth, the header is unset&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;## since nginx is auth-ing before proxying.&lt;/span&gt;
  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$upstream_http_docker_distribution_api_version&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$docker_distribution_api_version&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &apos;&apos; &apos;registry/2.0&apos;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt; ssl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server_name&lt;/span&gt; myregistrydomain.com&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# SSL&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_certificate&lt;/span&gt; /etc/nginx/conf.d/domain.crt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_certificate_key&lt;/span&gt; /etc/nginx/conf.d/domain.key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_protocols&lt;/span&gt; TLSv1.1 TLSv1.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_ciphers&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH&apos;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_prefer_server_ciphers&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;on&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ssl_session_cache&lt;/span&gt; shared:SSL:10m&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# disable any limits to avoid HTTP 413 for large image uploads&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;client_max_body_size&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;chunked_transfer_encoding&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;on&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; /v2/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Do not allow connections from docker 1.5 and earlier&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# docker pre-1.6.0 did not properly set the user agent on ping, catch &quot;Go *&quot; user agents&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; (&lt;span class=&quot;token variable&quot;&gt;$http_user_agent&lt;/span&gt; ~ &lt;span class=&quot;token string&quot;&gt;&quot;^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$&quot;&lt;/span&gt; )&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;# To add basic authentication to v2 use auth_basic setting.&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;auth_basic&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Registry realm&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;auth_basic_user_file&lt;/span&gt; /etc/nginx/conf.d/nginx.htpasswd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token comment&quot;&gt;## If $docker_distribution_api_version is empty, the header is not added.&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;## See the map directive above where this variable is defined.&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;add_header&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Docker-Distribution-Api-Version&apos;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$docker_distribution_api_version&lt;/span&gt; always&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_pass&lt;/span&gt;                          http://docker-registry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt;  Host              &lt;span class=&quot;token variable&quot;&gt;$http_host&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;# required for docker client&apos;s sake&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt;  X-Real-IP         &lt;span class=&quot;token variable&quot;&gt;$remote_addr&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# pass on real client&apos;s IP&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt;  X-Forwarded-For   &lt;span class=&quot;token variable&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt;  X-Forwarded-Proto &lt;span class=&quot;token variable&quot;&gt;$scheme&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_read_timeout&lt;/span&gt;                  &lt;span class=&quot;token number&quot;&gt;900&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-访问限制&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E8%AE%BF%E9%97%AE%E9%99%90%E5%88%B6&quot; aria-label=&quot;3 访问限制 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 访问限制&lt;/h1&gt;
&lt;p&gt;在刚才的启动命令部分已经提到了&lt;code class=&quot;language-text&quot;&gt;如何制作用户名和密码的访问限制秘钥&lt;/code&gt;。而作为用户访问Registry则是另一回事。&lt;/p&gt;
&lt;p&gt;私有Registry如果架设的是HTTP，而不是HTTPS的话，访问的客户端需要修改配置，将该Registry的地址列入允许的不安全访问列表内，才可以正常访问。一般来说这个配置文件是在：&lt;code class=&quot;language-text&quot;&gt;~/.docker/daemon.json&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;范例：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;insecure-registries&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;127.0.0.1:15000&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;修改完成之后必须重启本地的docker进程，该配置才会生效。&lt;/p&gt;
&lt;p&gt;然后使用&lt;code class=&quot;language-text&quot;&gt;docker login 127.0.0.1:15000&lt;/code&gt;进行登录，这会在&lt;code class=&quot;language-text&quot;&gt;~/.docker/config.json&lt;/code&gt;文件中生成一个登录项。但访问凭证一般不会直接存储在这里，OSX操作系统是使用keychain来进行存储。参见：&lt;a href=&quot;https://docs.docker.com/engine/reference/commandline/login/#credentials-store&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Credentials store&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在某些场合，需求预先生成访问凭证，而不是到实际运行的主机上进行docker login。这时候使用命令来生成凭证，并手动生成对应的登录项配置文件，放到指定的位置来生效。&lt;/p&gt;
&lt;p&gt;根据用户名和密码来生成凭证：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token builtin class-name&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-n&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;:&lt;span class=&quot;token variable&quot;&gt;$password&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; base64
&lt;span class=&quot;token comment&quot;&gt;# dGVzdDphYmMxMjNf&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;生成登录项配置文件&lt;code class=&quot;language-text&quot;&gt;~/.docker/config.json&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;auths&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;127.0.0.1:15000&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token property&quot;&gt;&quot;auth&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dGVzdDphYmMxMjNf&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这样后续的使用就没有问题了，当然这样做是非常不安全的，不推荐使用。&lt;/p&gt;
&lt;h1 id=&quot;3-api&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-api&quot; aria-label=&quot;3 api permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. API&lt;/h1&gt;
&lt;p&gt;因为registry没有提供UI界面，所有的操作都必须通过RESTful API来进行。&lt;/p&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://docs.docker.com/registry/spec/api/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HTTP API V2&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;常用API范例：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;查看所有的仓库清单&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$password&lt;/span&gt; http://127.0.0.1:15000/v2/_catalog &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;repositories&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;fullstack/builder&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;fullstack/common&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;fullstack/gateway&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;fullstack/runner&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;fullstack/server&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;查看某个仓库的所有tag&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$password&lt;/span&gt; http://127.0.0.1:15000/v2/fullstack/common/tags/list &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fullstack/common&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;tags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;0.0.42&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;0.0.43&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;0.0.35&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;0.0.32&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;0.0.33&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;0.0.34&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;查看某个仓库某个tag的digest&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$password&lt;/span&gt; http://127.0.0.1:15000/v2/fullstack/common/manifests/0.0.43 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--header&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Accept: application/vnd.docker.distribution.manifest.v2+json&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token string&quot;&gt;&apos;.config|.digest&apos;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;&quot;sha256:23ffb64a5f8c7bf748eb80830d7f3be7f5de613ba9d37817fe7771180b59fdc5&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;根据digest删除某个仓库的某个tag&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$username&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$password&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-I&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; DELETE &lt;span class=&quot;token string&quot;&gt;&quot;http://127.0.0.1:15000/v2/fullstack/common/manifests/sha256:23ffb64a5f8c7bf748eb80830d7f3be7f5de613ba9d37817fe7771180b59fdc5&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;HTTP/1.1 &lt;span class=&quot;token number&quot;&gt;202&lt;/span&gt; Accepted
Docker-Distribution-Api-Version: registry/2.0
X-Content-Type-Options: nosniff
Date: Thu, &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt; Dec &lt;span class=&quot;token number&quot;&gt;2019&lt;/span&gt; 09:17:51 GMT
Content-Length: &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;只要返回的CODE是&lt;code class=&quot;language-text&quot;&gt;202&lt;/code&gt;，说明就是没问题的，正常删除。&lt;/p&gt;
&lt;h1 id=&quot;4-删除镜像&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E5%88%A0%E9%99%A4%E9%95%9C%E5%83%8F&quot; aria-label=&quot;4 删除镜像 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 删除镜像&lt;/h1&gt;
&lt;p&gt;刚才在API中已经提到了根据digest删除某个tag，但是这时候镜像的真实数据还并没有被删除。还需要做几步操作。&lt;/p&gt;
&lt;p&gt;首先需要修改Registry的配置文件，允许删除操作。注意下面范例的：&lt;code class=&quot;language-text&quot;&gt;storage.delete.enabled: true&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; registry
&lt;span class=&quot;token key atrule&quot;&gt;storage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;cache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;blobdescriptor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; inmemory
  &lt;span class=&quot;token key atrule&quot;&gt;filesystem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;rootdirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /var/lib/registry
  &lt;span class=&quot;token key atrule&quot;&gt;delete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;addr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;X-Content-Type-Options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;nosniff&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;storagedriver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
    &lt;span class=&quot;token key atrule&quot;&gt;threshold&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后需要进入容器内部进行删除操作：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; /bin/sh
/&lt;span class=&quot;token comment&quot;&gt;# /bin/registry garbage-collect /etc/docker/registry/config.yml&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;即便这样，被删除的tag仍旧会出现在tag列表API的结果里。Docker官方对删除就完全没做好支持。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Gitea简单介绍及使用]]></title><link>https://xenojoshua.com/posts/2019/12/gitea-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/12/gitea-note</guid><pubDate>Thu, 26 Dec 2019 02:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E4%BD%BF%E7%94%A8&quot;&gt;2. 使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E5%AE%89%E8%A3%85%E5%90%AF%E5%8A%A8&quot;&gt;2.1 安装启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E9%85%8D%E7%BD%AE&quot;&gt;2.2 配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-command-line&quot;&gt;2.3 Command Line&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#24-api&quot;&gt;2.4 API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#25-%E8%AE%BF%E9%97%AE%E6%8E%88%E6%9D%83&quot;&gt;2.5 访问授权&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#251-token%E6%8E%88%E6%9D%83&quot;&gt;2.5.1 Token授权&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#252-oauth2%E6%8E%88%E6%9D%83&quot;&gt;2.5.2 OAuth2授权&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Gitea是一款使用Golang编写的可自运营的代码管理工具。&lt;/p&gt;
&lt;p&gt;在这个领域，名气最响的应该是Gitlab。但实际使用中Gitlab也有点问题，首先就是资源占用。Gitlab是使用ruby编写的，好几年之前刚出来的时候，一台1G内存的虚拟主机连安装运行都做不到，着实震惊。时至今日都已经发展到了以docker镜像分发，gitlab仍旧会有体积和运行时资源占用的问题。另一点就是功能，对于一般标准团队来说，gitlab的功能太过于丰富，这是往好的地方说，往坏的地方说就是它包含了太多不需要的东西，而这些东西还占用磁盘和运行时资源。&lt;/p&gt;
&lt;p&gt;于是着手查看开源的alternative方案，很快就找到了golang研发的gitea。使用golang研发的软件分发都很容易，体积小，安装使用简单，运行时占用资源少。且gitea的功能很完备，某些自身不具备的功能也能通过第三方来解决，比如CI就可以结合同样是golang研发的drone来实施。&lt;/p&gt;
&lt;p&gt;相关资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gitea.io/zh-cn/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;官网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://try.gitea.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;线上实例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.gitea.io/zh-cn/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;文档&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;2 使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 使用&lt;/h1&gt;
&lt;h2 id=&quot;21-安装启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E5%AE%89%E8%A3%85%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;21 安装启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 安装启动&lt;/h2&gt;
&lt;p&gt;安装使用仍旧推荐使用官方镜像：&lt;a href=&quot;https://hub.docker.com/r/gitea/gitea/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gitea/gitea&lt;/a&gt;。官方指引：&lt;a href=&quot;https://docs.gitea.io/zh-cn/install-with-docker/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;从Docker安装&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;  &lt;span class=&quot;token key atrule&quot;&gt;localbuild_gitea&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; gitea/gitea&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;1.10.0
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; localbuild_gitea
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; localbuild_gitea
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; net
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 13000&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;13000&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 122&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;122&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;file
      &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 512m
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
    &lt;span class=&quot;token key atrule&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wget http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//127.0.0.1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;13000 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;q &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;O &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; /dev/null 2&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token important&quot;&gt;&amp;amp;1&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
      &lt;span class=&quot;token key atrule&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20s
      &lt;span class=&quot;token key atrule&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ./vendor/gitea&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/data&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;关于启动时的环境变量相关，官方有一个讨论帖：&lt;a href=&quot;https://github.com/go-gitea/gitea/issues/350&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configure with env variables #350&lt;/a&gt;，但貌似还没有任何结论，当前最佳实践是做好配置文件之后映射到容器内。&lt;/p&gt;
&lt;p&gt;关于gitea使用的数据库，如果是默认配置的话，是会使用Postgre数据库，存放在容器内的&lt;code class=&quot;language-text&quot;&gt;/data/gitea/gitea.db&lt;/code&gt;位置。&lt;/p&gt;
&lt;p&gt;gitea的数据全部都放在容器内的&lt;code class=&quot;language-text&quot;&gt;/data&lt;/code&gt;文件夹下，一般需要将这个文件夹映射出来。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;/data&lt;/code&gt;文件夹内部文件结构如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/-
 | git /-                                           # 存放所有git仓库数据
 |      | repositories /-                           # 代码库存放位置
 |      |               | fullstack /-              # 组织
 |      |               |            | common.git   # 组织下的代码库
 |      |               |            | gateway.git
 |      |               |            | server.git
 | gitea /-                                         # 存放gitea自身的系统文件
 |        | conf /-
 |        |       | app.ini                         # gitea配置文件
 |        | log                                     # gitea日志文件
 |        | gitea.db                                # Postgre数据库文件
 | ssh                                              # 秘钥文件&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/gitea-note/home.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;22-配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;22 配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 配置&lt;/h2&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://docs.gitea.io/zh-cn/config-cheat-sheet/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;配置说明&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;映射路径在容器内的&lt;code class=&quot;language-text&quot;&gt;/data/gitea/conf/app.ini&lt;/code&gt;。一般主要是URL和端口之类的需要调整下，还有就是数据库的访问方式。&lt;/p&gt;
&lt;h2 id=&quot;23-command-line&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-command-line&quot; aria-label=&quot;23 command line permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 Command Line&lt;/h2&gt;
&lt;p&gt;gitea还可以作为一个命令行工具来执行CLI命令，官方文档在：&lt;a href=&quot;https://docs.gitea.io/zh-cn/command-line/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Command Line&lt;/a&gt;。执行的时候可能还会需要用到部分环境变量，见：&lt;a href=&quot;https://docs.gitea.io/zh-cn/specific-variables/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;环境变量清单&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;不过作为命令行工具来使用的机会比较少见。&lt;/p&gt;
&lt;h2 id=&quot;24-api&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#24-api&quot; aria-label=&quot;24 api permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4 API&lt;/h2&gt;
&lt;p&gt;gitea提供RESTful的API，这块是自动化的主力，需要好好看下如何使用。&lt;/p&gt;
&lt;p&gt;官方API文档在：&lt;a href=&quot;https://docs.gitea.io/zh-cn/api-usage/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gitea API 使用指南&lt;/a&gt;。这篇指引主要是阐明了如何使用API，如何处理访问控制之类的。具体的API调用参数和返回值，以及API列表，可以查看官方的swagger：&lt;a href=&quot;https://try.gitea.io/api/swagger#/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gitea API.&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;给几个curl调用的例子：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在fullstack组织下，创建代码库common&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; POST &lt;span class=&quot;token string&quot;&gt;&quot;http://127.0.0.1:13000/api/v1/admin/users/fullstack/repos&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;accept: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: token 752e305de4936a769d2ed962b3e019f8866e510a&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Content-Type: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{ &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;name&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;common&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;, &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;auto_init&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: false, &lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;private&lt;span class=&quot;token entity&quot; title=&quot;\&amp;quot;&quot;&gt;\&quot;&lt;/span&gt;: true }&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;删除fullstack组织下的代码库common&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; DELETE &lt;span class=&quot;token string&quot;&gt;&quot;http://127.0.0.1:13000/api/v1/repos/fullstack/common&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;accept: application/json&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-H&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Authorization: token 752e305de4936a769d2ed962b3e019f8866e510a&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;25-访问授权&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#25-%E8%AE%BF%E9%97%AE%E6%8E%88%E6%9D%83&quot; aria-label=&quot;25 访问授权 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.5 访问授权&lt;/h2&gt;
&lt;p&gt;授权主要有两种方式。&lt;/p&gt;
&lt;h3 id=&quot;251-token授权&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#251-token%E6%8E%88%E6%9D%83&quot; aria-label=&quot;251 token授权 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.5.1 Token授权&lt;/h3&gt;
&lt;p&gt;Token授权是最简单的。通过发行token，让拥有token的终端可以直接调用API进行操作。&lt;/p&gt;
&lt;p&gt;发行Token也很简单：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;点击右上角&lt;code class=&quot;language-text&quot;&gt;用户头像&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;点击下拉菜单的&lt;code class=&quot;language-text&quot;&gt;设置&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;点击新页面导航栏中间的&lt;code class=&quot;language-text&quot;&gt;应用&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在&lt;code class=&quot;language-text&quot;&gt;管理Access Tokens&lt;/code&gt;部分输入Token名，点击&lt;code class=&quot;language-text&quot;&gt;生成令牌&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要注意的是，令牌生成之后内容只会展现一次，后续就只有删除操作。如果遗忘的话就只能删除然后申请新的了。&lt;/p&gt;
&lt;h3 id=&quot;252-oauth2授权&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#252-oauth2%E6%8E%88%E6%9D%83&quot; aria-label=&quot;252 oauth2授权 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.5.2 OAuth2授权&lt;/h3&gt;
&lt;p&gt;OAuth2也算是现在比较常见的授权方法，和Token不同的是两者的应用场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Token：更多的用在自动化部署等，需要简单访问权限的场景&lt;/li&gt;
&lt;li&gt;OAuth2：更多的用在第三方应用程序和gitea的整合，比如CI工具等&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;操作上也很简单，在Token同一界面上的&lt;code class=&quot;language-text&quot;&gt;管理 OAuth2 应用程序&lt;/code&gt;界面部分，按提示操作即可。一样的，秘钥只会在创建完成后展示一次，后续秘钥只能重置，不能再次展示。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Consul Notes]]></title><link>https://xenojoshua.com/posts/2019/12/consul-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/12/consul-note</guid><pubDate>Wed, 25 Dec 2019 02:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E9%80%89%E5%9E%8B&quot;&gt;2. 选型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E6%9E%B6%E6%9E%84&quot;&gt;3. 架构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8&quot;&gt;4. 使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E5%90%AF%E5%8A%A8&quot;&gt;4.1 启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-api&quot;&gt;4.2 API&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#421-%E6%A0%B9%E6%8D%AE%E8%8A%82%E7%82%B9%E5%81%A5%E5%BA%B7%E7%8A%B6%E6%80%81%E8%8E%B7%E5%8F%96%E8%8A%82%E7%82%B9&quot;&gt;4.2.1 根据节点健康状态获取节点&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#422-%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E6%9C%8D%E5%8A%A1&quot;&gt;4.2.2 获取所有服务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#423-%E6%A0%B9%E6%8D%AE%E6%9C%8D%E5%8A%A1%E5%90%8D%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E5%AF%B9%E5%BA%94%E7%9A%84%E6%9C%8D%E5%8A%A1%E8%8A%82%E7%82%B9&quot;&gt;4.2.3 根据服务名获取所有对应的服务节点&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#424-%E6%A0%B9%E6%8D%AEservice-id%E8%8E%B7%E5%8F%96%E5%85%B7%E4%BD%93%E4%BF%A1%E6%81%AF&quot;&gt;4.2.4 根据service id获取具体信息&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#425-%E5%88%A0%E9%99%A4%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E7%9A%84%E6%B3%A8%E5%86%8C&quot;&gt;4.2.5 删除某个服务的注册&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-ui&quot;&gt;4.3 UI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-template&quot;&gt;4.4 Template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#45-dns&quot;&gt;4.5 DNS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#46-application&quot;&gt;4.6 Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#47-health-check&quot;&gt;4.7 Health Check&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#appendix&quot;&gt;Appendix&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#consul-agent---help-id_app_agent_help&quot;&gt;consul agent —help {#ID_APP_AGENT_HELP}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#consul---help&quot;&gt;consul —help&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Consul一般用来作为服务注册和服务发现软件。&lt;a href=&quot;https://www.consul.io/intro/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;官方介绍&lt;/a&gt;如下：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Consul is a service mesh solution providing a full featured control plane with service discovery, configuration, and segmentation functionality. Each of these features can be used individually as needed, or they can be used together to build a full service mesh. Consul requires a data plane and supports both a proxy and native integration model. Consul ships with a simple built-in proxy so that everything works out of the box, but also supports 3rd party proxy integrations such as Envoy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;文档资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.consul.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;consul.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.consul.io/docs/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Consul Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.consul.io/docs/internals/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Consul Internals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.consul.io/api/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;API Introduction&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-选型&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E9%80%89%E5%9E%8B&quot; aria-label=&quot;2 选型 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 选型&lt;/h1&gt;
&lt;p&gt;市面上常用的开源服务发现软件主要有：&lt;a href=&quot;https://github.com/hashicorp/consul&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;consul&lt;/a&gt;、&lt;a href=&quot;https://github.com/etcd-io/etcd&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;etcd&lt;/a&gt;、&lt;a href=&quot;https://github.com/apache/zookeeper&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;zookeeper&lt;/a&gt;。前两者都是用golang研发的，而zookeeper则是java研发的（你懂我意思吧）。&lt;/p&gt;
&lt;p&gt;这里就有选型的问题了，不过了解下来相互之间的差异不能说很大，基本上都在可接受范围内。特别是consul和etcd都使用raft作为分布式一致性协议，可以说非常趋同了。etcd关注度更高（特别是K8S官方使用了它），功能简单，主要在大型系统中作为分布式K/V存储使用；而consul的功能更强大（完整、开箱即用）且易用性更高。&lt;/p&gt;
&lt;p&gt;相关资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.consul.io/intro/vs/zookeeper.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Consul vs. ZooKeeper, doozerd, etcd&lt;/a&gt;：这篇是consul官方的，不过我觉得讲得其实不多，没什么价值&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/yurishkuro/10cb2dc42f42a007a8ce0e055ed0d171&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;etcd vs consul vs ???&lt;/a&gt;：文章的作者居然是Jaeger的作者，看完我才刚发现；写得很好，基本上主要的点都比对出来了，价值极高&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.servercoder.com/2018/03/30/consul-vs-zookeeper-etcd/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;服务发现框架选型，Consul还是Zookeeper还是etcd&lt;/a&gt;：中文，带表格比对，简单易理解&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://matthewpalmer.net/kubernetes-app-developer/articles/how-does-kubernetes-use-etcd.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How Does Kubernetes Use etcd?&lt;/a&gt;：主要说明了K8S为什么以及如何使用etcd，主要还是作为存储系统&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-架构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E6%9E%B6%E6%9E%84&quot; aria-label=&quot;3 架构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 架构&lt;/h1&gt;
&lt;p&gt;官方的架构介绍在：&lt;a href=&quot;https://www.consul.io/docs/internals/architecture.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Consul Architecture&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/consul-note/consul-arch.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;简单来说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;节点分为&lt;code class=&quot;language-text&quot;&gt;client&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;server负责存储数据，并形成集群，使用raft保证集群一致性&lt;/li&gt;
&lt;li&gt;client负责直接和业务对象连接，并将数据同步到server上&lt;/li&gt;
&lt;li&gt;所有的节点都是通过gossip连接起来的&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;4-使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;4 使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 使用&lt;/h1&gt;
&lt;h2 id=&quot;41-启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;41 启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 启动&lt;/h2&gt;
&lt;p&gt;一般直接使用docker镜像：&lt;a href=&quot;https://hub.docker.com/_/consul&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;consul&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;启动方面非常简单，全部都是用&lt;code class=&quot;language-text&quot;&gt;agent&lt;/code&gt;命令，参数细节放在后面的附录部分，太长了：&lt;a href=&quot;#ID_APP_AGENT_HELP&quot;&gt;consul agent —help&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;常用参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--node=$name&lt;/code&gt;指定节点名称&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--server&lt;/code&gt;表示节点是server节点&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--bootstrap&lt;/code&gt;表示节点以bootstrap模式启动&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--ui&lt;/code&gt;表示当前节点会提供管理UI界面&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--client=0.0.0.0&lt;/code&gt;指定监听地址&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--join=$host&lt;/code&gt;指定启动时尝试加入集群时连接的目标节点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面给个例子，集群3个server节点，2个client节点：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;  &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; consul&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;1.6.1
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_server1
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_server1
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; net
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; 18500&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8500&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8600&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# DNS&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8500&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTP API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8501&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTPS API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8502&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# gRPC API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8301&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# LAN Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8302&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Wan Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8300&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Server RPC address&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;file
      &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 512m
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
    &lt;span class=&quot;token key atrule&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wget http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//127.0.0.1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;8500/v1/health/node/consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server1 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;q &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;O &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; /dev/null 2&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token important&quot;&gt;&amp;amp;1&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
      &lt;span class=&quot;token key atrule&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20s
      &lt;span class=&quot;token key atrule&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; consul_server1_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/consul/data
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; CONSUL_BIND_INTERFACE=eth0
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      agent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node=consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;bootstrap&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client=0.0.0.0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;ui
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; consul&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;1.6.1
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_server2
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_server2
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; net
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8600&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# DNS&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8500&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTP API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8501&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTPS API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8502&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# gRPC API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8301&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# LAN Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8302&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Wan Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8300&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Server RPC address&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;file
      &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 512m
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
    &lt;span class=&quot;token key atrule&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wget http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//127.0.0.1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;8500/v1/health/node/consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server2 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;q &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;O &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; /dev/null 2&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token important&quot;&gt;&amp;amp;1&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
      &lt;span class=&quot;token key atrule&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20s
      &lt;span class=&quot;token key atrule&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; consul_server2_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/consul/data
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; CONSUL_BIND_INTERFACE=eth0
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      agent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node=consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client=0.0.0.0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;join=fullstack_consul_server1
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; consul&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;1.6.1
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_server3
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_server3
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; net
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8600&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# DNS&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8500&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTP API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8501&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTPS API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8502&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# gRPC API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8301&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# LAN Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8302&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Wan Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8300&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Server RPC address&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;file
      &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 512m
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
    &lt;span class=&quot;token key atrule&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wget http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//127.0.0.1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;8500/v1/health/node/consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server3 &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;q &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;O &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; /dev/null 2&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token important&quot;&gt;&amp;amp;1&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
      &lt;span class=&quot;token key atrule&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20s
      &lt;span class=&quot;token key atrule&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; consul_server3_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/consul/data
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; CONSUL_BIND_INTERFACE=eth0
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      agent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node=consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client=0.0.0.0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;join=fullstack_consul_server1
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_client1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; consul&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;1.6.1
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_client1
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_client1
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; net
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8600&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# DNS&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8500&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTP API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8501&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTPS API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8502&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# gRPC API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8301&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# LAN Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8302&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Wan Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8300&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Server RPC address&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;file
      &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 512m
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
    &lt;span class=&quot;token key atrule&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wget http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//127.0.0.1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;8500/v1/health/node/consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;q &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;O &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; /dev/null 2&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token important&quot;&gt;&amp;amp;1&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
      &lt;span class=&quot;token key atrule&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20s
      &lt;span class=&quot;token key atrule&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; consul_client1_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/consul/data
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; CONSUL_BIND_INTERFACE=eth0
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      agent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node=consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client=0.0.0.0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;join=fullstack_consul_server1
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_client2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; consul&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;1.6.1
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_client2
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; fullstack_consul_client2
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; net
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8600&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# DNS&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8500&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTP API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8501&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# HTTPS API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8502&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# gRPC API&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8301&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# LAN Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8302&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Wan Serf&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8300&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Server RPC address&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
      &lt;span class=&quot;token key atrule&quot;&gt;fullstack_consul_server3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service_healthy
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; json&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;file
      &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 512m
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
    &lt;span class=&quot;token key atrule&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wget http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//127.0.0.1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;8500/v1/health/node/consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;q &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;O &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; /dev/null 2&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token important&quot;&gt;&amp;amp;1&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
      &lt;span class=&quot;token key atrule&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20s
      &lt;span class=&quot;token key atrule&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; consul_client2_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/consul/data
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; CONSUL_BIND_INTERFACE=eth0
    &lt;span class=&quot;token key atrule&quot;&gt;command&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      agent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;node=consul&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;client=0.0.0.0&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;join=fullstack_consul_server1
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;部署完成后节点如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/consul-note/nodes.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;42-api&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-api&quot; aria-label=&quot;42 api permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 API&lt;/h2&gt;
&lt;p&gt;官方API文档在：&lt;a href=&quot;https://www.consul.io/api/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;API Introduction&lt;/a&gt;。Consul使用RESTful的HTTP请求来提供服务，所有的客户端或命令行工具无非就是RESTful API的封装。所以如果有需要，可以直接使用curl来发送HTTP请求调用接口。&lt;/p&gt;
&lt;p&gt;下面的例子中会涉及到一些demo应用程序的节点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;app server 3个节点&lt;/li&gt;
&lt;li&gt;app gateway 3个节点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;client1连接了：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/consul-note/client1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;client2连接了：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/consul-note/client1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;421-根据节点健康状态获取节点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#421-%E6%A0%B9%E6%8D%AE%E8%8A%82%E7%82%B9%E5%81%A5%E5%BA%B7%E7%8A%B6%E6%80%81%E8%8E%B7%E5%8F%96%E8%8A%82%E7%82%B9&quot; aria-label=&quot;421 根据节点健康状态获取节点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.1 根据节点健康状态获取节点&lt;/h3&gt;
&lt;p&gt;文档：&lt;a href=&quot;https://www.consul.io/api/health.html#list-checks-in-state&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;List Checks in State&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个接口可以有效过滤掉已经失效的节点。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; http://127.0.0.1:18500/v1/health/state/any &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;serfHealth&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Serf Health Status&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Agent alive and reachable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;service:1fw20gk4kq30tk&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Service &apos;server&apos; check&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTP GET http://fullstack_server2:50052/health: 200 OK Output: OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20gk4kq30tk&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;29&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;service:1fw20gk4kq35py&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Service &apos;gateway&apos; check&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTP GET http://fullstack_gateway3:3000/health: 200 OK Output: OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20gk4kq35py&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gateway&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;service:1fw20hk4kq5i2h&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Service &apos;gateway&apos; check&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTP GET http://fullstack_gateway1:3000/health: 200 OK Output: OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20hk4kq5i2h&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gateway&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;49&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;serfHealth&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Serf Health Status&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Agent alive and reachable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;service:1fw20hk4kq30n8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Service &apos;server&apos; check&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTP GET http://fullstack_server3:50052/health: 200 OK Output: OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20hk4kq30n8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;service:1fw20ik4kq35th&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Service &apos;gateway&apos; check&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTP GET http://fullstack_gateway2:3000/health: 200 OK Output: OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20ik4kq35th&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gateway&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;31&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;34&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;service:eewk9hk4kq2uvy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Service &apos;server&apos; check&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;HTTP GET http://fullstack_server1:50052/health: 200 OK Output: OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;eewk9hk4kq2uvy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;23&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-server1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;serfHealth&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Serf Health Status&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Agent alive and reachable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-server2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;serfHealth&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Serf Health Status&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Agent alive and reachable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-server3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CheckID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;serfHealth&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Serf Health Status&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;passing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Notes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Output&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Agent alive and reachable&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Definition&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;any可以更换成其他状态：&lt;code class=&quot;language-text&quot;&gt;any, passing, warning, or critical&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&quot;422-获取所有服务&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#422-%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E6%9C%8D%E5%8A%A1&quot; aria-label=&quot;422 获取所有服务 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.2 获取所有服务&lt;/h3&gt;
&lt;p&gt;文档：&lt;a href=&quot;https://www.consul.io/api/catalog.html#list-services&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;List Services&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; http://127.0.0.1:18500/v1/catalog/services &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;consul&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;gateway&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;The keys are the service names, and the array values provide all known tags for a given service.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;423-根据服务名获取所有对应的服务节点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#423-%E6%A0%B9%E6%8D%AE%E6%9C%8D%E5%8A%A1%E5%90%8D%E8%8E%B7%E5%8F%96%E6%89%80%E6%9C%89%E5%AF%B9%E5%BA%94%E7%9A%84%E6%9C%8D%E5%8A%A1%E8%8A%82%E7%82%B9&quot; aria-label=&quot;423 根据服务名获取所有对应的服务节点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.3 根据服务名获取所有对应的服务节点&lt;/h3&gt;
&lt;p&gt;文档：&lt;a href=&quot;https://www.consul.io/api/catalog.html#list-nodes-for-service&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;List Nodes for Service&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; http://127.0.0.1:18500/v1/catalog/service/:service_name &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;server&lt;/code&gt;的结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;f33332e4-3881-b975-d647-bc21a4ca41da&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Datacenter&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dc1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;TaggedAddresses&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;lan&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wan&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.8&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;NodeMeta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;consul-network-segment&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceKind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20gk4kq30tk&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceAddress&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fullstack_server2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceWeights&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Passing&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Warning&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceMeta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServicePort&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50051&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceEnableTagOverride&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceProxy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;MeshGateway&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceConnect&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;26&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;feaba61d-83ce-a7e6-3e99-f1b2fa889bf8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Datacenter&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dc1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;TaggedAddresses&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;lan&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wan&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.7&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;NodeMeta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;consul-network-segment&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceKind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20hk4kq30n8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceAddress&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fullstack_server3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceWeights&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Passing&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Warning&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceMeta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServicePort&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50051&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceEnableTagOverride&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceProxy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;MeshGateway&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceConnect&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;feaba61d-83ce-a7e6-3e99-f1b2fa889bf8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Node&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul-client2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Datacenter&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dc1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;TaggedAddresses&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;lan&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.7&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;wan&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;172.26.0.7&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;NodeMeta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;consul-network-segment&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceKind&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;eewk9hk4kq2uvy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceName&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceTags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceAddress&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fullstack_server1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceWeights&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Passing&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;Warning&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceMeta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServicePort&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50051&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceEnableTagOverride&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceProxy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;MeshGateway&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ServiceConnect&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;CreateIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;ModifyIndex&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;22&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;424-根据service-id获取具体信息&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#424-%E6%A0%B9%E6%8D%AEservice-id%E8%8E%B7%E5%8F%96%E5%85%B7%E4%BD%93%E4%BF%A1%E6%81%AF&quot; aria-label=&quot;424 根据service id获取具体信息 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.4 根据service id获取具体信息&lt;/h3&gt;
&lt;p&gt;文档：&lt;a href=&quot;https://www.consul.io/api/agent/service.html#get-service-configuration&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Get Service Configuration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;需要注意，这个操作只能获取所查询agent（某个client）上注册的服务的信息。下面举两个例子，刚才有说到&lt;code class=&quot;language-text&quot;&gt;fullstack_server2&lt;/code&gt;是注册在&lt;code class=&quot;language-text&quot;&gt;fullstack_consul_client1&lt;/code&gt;上的；而&lt;code class=&quot;language-text&quot;&gt;fullstack_server3&lt;/code&gt;是注册在&lt;code class=&quot;language-text&quot;&gt;fullstack_consul_client2&lt;/code&gt;上的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;fullstack_server2&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 首先需要登入到docker network中的某台机器上，因为client都没有向主机暴露端口&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# docker exec -it fullstack_consul_server1 /bin/sh&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; http://fullstack_consul_client1:8500/v1/agent/service/1fw20gk4kq30tk &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;ID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20gk4kq30tk&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Service&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Tags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Meta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Port&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50051&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fullstack_server2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Weights&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Passing&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Warning&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;EnableTagOverride&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;ContentHash&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;b13f5888fa84e5d&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;fullstack_server3&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# 首先需要登入到docker network中的某台机器上，因为client都没有向主机暴露端口&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# docker exec -it fullstack_consul_server1 /bin/sh&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; http://fullstack_consul_client2:8500/v1/agent/service/1fw20hk4kq30n8 &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;ID&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;1fw20hk4kq30n8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Service&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Tags&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Meta&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Port&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50051&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Address&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fullstack_server3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;Weights&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Passing&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;Warning&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;EnableTagOverride&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;ContentHash&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;120b74b874209fe8&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;425-删除某个服务的注册&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#425-%E5%88%A0%E9%99%A4%E6%9F%90%E4%B8%AA%E6%9C%8D%E5%8A%A1%E7%9A%84%E6%B3%A8%E5%86%8C&quot; aria-label=&quot;425 删除某个服务的注册 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.5 删除某个服务的注册&lt;/h3&gt;
&lt;p&gt;文档：&lt;a href=&quot;https://www.consul.io/api/agent/service.html#deregister-service&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deregister Service&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;做开发的时候，为了测试，有的时候需要手动删除某些服务，这时候就要用到这个接口了。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--request&lt;/span&gt; PUT http://127.0.0.1:18500/v1/agent/service/deregister/:service_id &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;43-ui&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-ui&quot; aria-label=&quot;43 ui permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 UI&lt;/h2&gt;
&lt;p&gt;访问：&lt;a href=&quot;http://127.0.0.1:18500%EF%BC%8C%E5%B0%B1%E4%BC%9A%E5%BC%80%E5%90%AF%E7%AE%A1%E7%90%86UI%E3%80%82&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://127.0.0.1:18500，就会开启管理UI。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/consul-note/ui.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;实际功能非常有限，主要是观察下集群及服务的状况。&lt;/p&gt;
&lt;h2 id=&quot;44-template&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-template&quot; aria-label=&quot;44 template permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 Template&lt;/h2&gt;
&lt;p&gt;Consul有一个非常好用的功能就是能把注册的服务，通过一个模板，生成配置文件并输出到指定的位置。最常见的使用案例就是consul配合nginx，多个业务服务跑在后台，注册到consul，通过consul将业务后台的信息生成成nginx配置文件。同时，任何业务后台的变动都会触发配置文件的重新生成。consul的template还可以指定一个外部命令，在刚才提到的例子中就可以触发nginx的reload，使改变的配置文件生效。&lt;/p&gt;
&lt;p&gt;template有单独的镜像：&lt;a href=&quot;https://hub.docker.com/r/hashicorp/consul-template/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;hashicorp/consul-template&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;范例nginx配置模板，文件位置：&lt;code class=&quot;language-text&quot;&gt;./vendor/consul/nginx&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;{{range services}} {{$name := .Name}} {{$service := service .Name}} {{ if eq $name &quot;gateway&quot; }}
upstream gateway {
    {{range $service}}server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;
    {{else}}server 127.0.0.1:65535; # force a 502{{end}}
} {{end}} {{end}}

server {
    listen 80;
    server_name localhost;

    access_log /var/log/nginx/fullstack.access.log;
    error_log /var/log/nginx/fullstack.error.log;

    root /usr/share/nginx/html;

    index index.html index.htm index.nginx-debian.html;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location / {
        proxy_set_header x-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header HOST $http_host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect http:// https://;
        proxy_connect_timeout 240;
        proxy_send_timeout 240;
        proxy_read_timeout 240;
        proxy_pass http://gateway;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;template启动：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; templateX &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; ./vendor/consul/nginx:/tmp/nginx.ctmpl &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 将模板配置文件映射到容器内&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /tmp/template:/consul-template/data &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;# 将主机的临时文件夹映射到容器内配置文件的生成位置，方便后续在主机上直接查看生成的配置文件&lt;/span&gt;
    hashicorp/consul-template:0.22.1-alpine &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-dry&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    -log-level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;debug &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    -consul-addr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;host.docker.internal:18500 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    -consul-retry &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    -consul-retry-attempts&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    -consul-retry-backoff&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;500ms &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-template&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/tmp/nginx.ctmpl:/consul-template/data/default.conf&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;查看生成的：&lt;code class=&quot;language-text&quot;&gt;/tmp/template/default.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;nginx&quot;&gt;&lt;pre class=&quot;language-nginx&quot;&gt;&lt;code class=&quot;language-nginx&quot;&gt;&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;upstream&lt;/span&gt; gateway&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt; fullstack_gateway3:3000 max_fails=3 fail_timeout=60 weight=1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt; fullstack_gateway1:3000 max_fails=3 fail_timeout=60 weight=1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt; fullstack_gateway2:3000 max_fails=3 fail_timeout=60 weight=1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;listen&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;server_name&lt;/span&gt; localhost&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;access_log&lt;/span&gt; /var/log/nginx/fullstack.access.log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;error_log&lt;/span&gt; /var/log/nginx/fullstack.error.log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;root&lt;/span&gt; /usr/share/nginx/html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;index&lt;/span&gt; index.html index.htm index.nginx-debian.html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;error_page&lt;/span&gt;   &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;502&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;503&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;504&lt;/span&gt;  /50x.html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; = /50x.html&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;root&lt;/span&gt;   /usr/share/nginx/html&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;location&lt;/span&gt; /&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; x-Forwarded-For &lt;span class=&quot;token variable&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; HOST &lt;span class=&quot;token variable&quot;&gt;$http_host&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_set_header&lt;/span&gt; X-Forwarded-Proto https&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_redirect&lt;/span&gt; http:// https://&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_connect_timeout&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;240&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_send_timeout&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;240&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_read_timeout&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;240&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token directive&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;proxy_pass&lt;/span&gt; http://gateway&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;45-dns&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#45-dns&quot; aria-label=&quot;45 dns permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5 DNS&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://www.consul.io/docs/agent/dns.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;DNS Interface&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;使用上应该说是非常简便了，而且基本上对业务没什么侵入性。我之前做的实验项目里没使用这个功能，主要是因为需要改动主机的DNS，比较麻烦。&lt;/p&gt;
&lt;h2 id=&quot;46-application&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#46-application&quot; aria-label=&quot;46 application permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.6 Application&lt;/h2&gt;
&lt;p&gt;Consul有不少语言对应的客户端，我的实验项目用过node.js的：&lt;a href=&quot;https://www.npmjs.com/package/consul&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Consul&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;注册服务：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Consul &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consul&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; exitHook &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;async-exit-hook&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; serviceId&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;uniqid&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; consul &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Consul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    host&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CONSUL_HOST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// fullstack_consul_client2&lt;/span&gt;
    port&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CONSUL_PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 8500&lt;/span&gt;
    promisify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;register&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; serverConf &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getRaw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; consul&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;agent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;service&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; serverConf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;serviceName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// server&lt;/span&gt;
        id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; serviceId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        address&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SERVICE_HOST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;// fullstack_server3&lt;/span&gt;
        port&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; serverConf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;servicePort&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 50051&lt;/span&gt;
        check&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            http&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;http://&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;SERVICE_HOST&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;serverConf&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;webPort&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;/health&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// http://fullstack_server3:50052/health&lt;/span&gt;
            interval&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            ttl&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;cleanup&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    consul&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;agent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;service&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deregister&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;serviceId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;cleanup done&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// exit&lt;/span&gt;
exitHook&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forceExitTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// wait 0.5s before force exit&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;exitHook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Process::exitHook - Got exit signal&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;cleanup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;done&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// start&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;startServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;startWeb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在服务启动的时候进行注册，并且记得要&lt;code class=&quot;language-text&quot;&gt;处理程序退出&lt;/code&gt;，退出的时候需要将注册信息删除，否则即便应用程序退出了，在consul里那个服务还是存在的。&lt;/p&gt;
&lt;p&gt;客户端获取&lt;code class=&quot;language-text&quot;&gt;可用节点&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; consul &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Consul&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    host&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CONSUL_HOST&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    port&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CONSUL_PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    promisify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; servers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; consul&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;health&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    service&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CONFIG&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getRaw&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;serviceName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// server&lt;/span&gt;
    passing&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;                               &lt;span class=&quot;token comment&quot;&gt;// get only living nodes&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; IResHealthService&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;47-health-check&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#47-health-check&quot; aria-label=&quot;47 health check permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.7 Health Check&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://www.consul.io/docs/agent/checks.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Checks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在4.6的范例里也提到了，在注册服务的时候可以提供当前注册进consul的应用程序的健康检查设置，consul会使用HTTP请求来检查该URL，只要是200返回就表示该服务仍旧存活。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/consul-note/living_node.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;appendix&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#appendix&quot; aria-label=&quot;appendix permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Appendix&lt;/h1&gt;
&lt;h2 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://my.oschina.net/qiangmzsx/blog/1634206&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;consul服务注册与服务发现的巨坑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/5d2d0c736fb9a07eb67dc156&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Node.js + Consul 实现服务注册、健康检查、配置中心&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.hi-linux.com/posts/36431.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;通过 Consul-Template 实现动态配置服务&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;consul-agent---help-id_app_agent_help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#consul-agent---help-id_app_agent_help&quot; aria-label=&quot;consul agent   help id_app_agent_help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;consul agent —help {#ID_APP_AGENT_HELP}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; consul:1.6.1 agent &lt;span class=&quot;token parameter variable&quot;&gt;--help&lt;/span&gt;
Usage: consul agent &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

  Starts the Consul agent and runs &lt;span class=&quot;token keyword&quot;&gt;until&lt;/span&gt; an interrupt is received. The
  agent represents a single &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; a cluster.

HTTP API Options

  &lt;span class=&quot;token parameter variable&quot;&gt;-datacenter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Datacenter of the agent.

Command Options

  &lt;span class=&quot;token parameter variable&quot;&gt;-advertise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the advertise address to use.

  -advertise-wan&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets address to advertise on WAN instead of &lt;span class=&quot;token parameter variable&quot;&gt;-advertise&lt;/span&gt; address.

  -allow-write-http-from&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Only allow &lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt; endpoint calls from given network. CIDR format,
     can be specified multiple times.

  -alt-domain&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Alternate domain to use &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; DNS interface.

  &lt;span class=&quot;token parameter variable&quot;&gt;-bind&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the &lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; address &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; cluster communication.

  &lt;span class=&quot;token parameter variable&quot;&gt;-bootstrap&lt;/span&gt;
     Sets server to bootstrap mode.

  -bootstrap-expect&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets server to &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt; bootstrap mode.

  &lt;span class=&quot;token parameter variable&quot;&gt;-check_output_max_size&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the maximum output size &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; checks on this agent

  &lt;span class=&quot;token parameter variable&quot;&gt;-client&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the address to &lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; client access. This includes RPC, DNS,
     HTTP, HTTPS and gRPC &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;if configured&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;.

  -config-dir&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Path to a directory to &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; configuration files from. This
     will &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; every &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; ending &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.json&apos;&lt;/span&gt; as configuration &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; this
     directory &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; alphabetical order. Can be specified multiple times.

  -config-file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Path to a &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; JSON or HCL &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt; with a matching &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;
     extension. Can be specified multiple times.

  -config-format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Config files are &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; this &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt; irrespective of their extension.
     Must be &lt;span class=&quot;token string&quot;&gt;&apos;hcl&apos;&lt;/span&gt; or &lt;span class=&quot;token string&quot;&gt;&apos;json&apos;&lt;/span&gt;

  -data-dir&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Path to a data directory to store agent state.

  &lt;span class=&quot;token parameter variable&quot;&gt;-dev&lt;/span&gt;
     Starts the agent &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; development mode.

  -disable-host-node-id
     Setting this to &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; will prevent Consul from using information
     from the &lt;span class=&quot;token function&quot;&gt;host&lt;/span&gt; to generate a &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; ID, and will cause Consul to
     generate a random &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; ID instead.

  -disable-keyring-file
     Disables the backing up of the keyring to a file.

  -dns-port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     DNS port to use.

  &lt;span class=&quot;token parameter variable&quot;&gt;-domain&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Domain to use &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; DNS interface.

  -enable-local-script-checks
     Enables health check scripts from configuration file.

  -enable-script-checks
     Enables health check scripts.

  &lt;span class=&quot;token parameter variable&quot;&gt;-encrypt&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Provides the gossip encryption key.

  -grpc-port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the gRPC API port to listen on &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currently needed &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; Envoy xDS
     only&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;.

  &lt;span class=&quot;token parameter variable&quot;&gt;-hcl&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     hcl config fragment. Can be specified multiple times.

  -http-port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the HTTP API port to listen on.

  &lt;span class=&quot;token parameter variable&quot;&gt;-join&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Address of an agent to &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; at start time. Can be specified
     multiple times.

  -join-wan&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Address of an agent to &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-wan&lt;/span&gt; at start time. Can be specified
     multiple times.

  -log-file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Path to the &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; the logs get written to

  -log-level&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Log level of the agent.

  -log-rotate-bytes&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Maximum number of bytes that should be written to a log &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt;

  -log-rotate-duration&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Time after &lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; log rotation needs to be performed

  -log-rotate-max-files&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Maximum number of log &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; archives to keep

  &lt;span class=&quot;token parameter variable&quot;&gt;-node&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Name of this node. Must be unique &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; the cluster.

  -node-id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     A unique ID &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; this &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; across space and time. Defaults to a
     randomly-generated ID that persists &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; the data-dir.

  -node-meta&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;key:value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     An arbitrary metadata key/value pair &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; this node, of the &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt;
     &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;key:value&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;.&lt;/span&gt; Can be specified multiple times.

  -non-voting-server
     &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Enterprise-only&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; This flag is used to &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt; the server not
     participate &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; the Raft quorum, and have it only receive the data
     replication stream. This can be used to &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; scalability to
     a cluster &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; cases where a high volume of reads to servers are
     needed.

  -pid-file&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Path to &lt;span class=&quot;token function&quot;&gt;file&lt;/span&gt; to store agent PID.

  &lt;span class=&quot;token parameter variable&quot;&gt;-protocol&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the protocol version. Defaults to latest.

  -raft-protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the Raft protocol version. Defaults to latest.

  &lt;span class=&quot;token parameter variable&quot;&gt;-recursor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Address of an upstream DNS server. Can be specified multiple times.

  &lt;span class=&quot;token parameter variable&quot;&gt;-rejoin&lt;/span&gt;
     Ignores a previous leave and attempts to rejoin the cluster.

  -retry-interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Time to &lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt; between &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; attempts.

  -retry-interval-wan&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Time to &lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt; between &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-wan&lt;/span&gt; attempts.

  -retry-join&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Address of an agent to &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; at start &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt; with retries enabled. Can
     be specified multiple times.

  -retry-join-wan&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Address of an agent to &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-wan&lt;/span&gt; at start &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt; with retries
     enabled. Can be specified multiple times.

  -retry-max&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Maximum number of &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; attempts. Defaults to &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; will retry
     indefinitely.

  -retry-max-wan&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Maximum number of &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-wan&lt;/span&gt; attempts. Defaults to &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;, &lt;span class=&quot;token function&quot;&gt;which&lt;/span&gt; will
     retry indefinitely.

  &lt;span class=&quot;token parameter variable&quot;&gt;-segment&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Enterprise-only&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; Sets the network segment to join.

  -serf-lan-bind&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Address to &lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; Serf LAN listeners to.

  -serf-lan-port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the Serf LAN port to listen on.

  -serf-wan-bind&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Address to &lt;span class=&quot;token builtin class-name&quot;&gt;bind&lt;/span&gt; Serf WAN listeners to.

  -serf-wan-port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the Serf WAN port to listen on.

  &lt;span class=&quot;token parameter variable&quot;&gt;-server&lt;/span&gt;
     Switches agent to server mode.

  -server-port&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the server port to listen on.

  &lt;span class=&quot;token parameter variable&quot;&gt;-syslog&lt;/span&gt;
     Enables logging to syslog.

  &lt;span class=&quot;token parameter variable&quot;&gt;-ui&lt;/span&gt;
     Enables the built-in static web UI server.

  -ui-content-path&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Sets the external UI path to a string. Defaults to: /ui/

  -ui-dir&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;value&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
     Path to directory containing the web UI resources.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;consul---help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#consul---help&quot; aria-label=&quot;consul   help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;consul —help&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; consul:1.6.1 &lt;span class=&quot;token parameter variable&quot;&gt;--help&lt;/span&gt;
Usage: consul &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;--version&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;--help&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;command&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;args&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

Available commands are:
    acl            Interact with Consul&lt;span class=&quot;token string&quot;&gt;&apos;s ACLs
    agent          Runs a Consul agent
    catalog        Interact with the catalog
    config         Interact with Consul&apos;&lt;/span&gt;s Centralized Configurations
    connect        Interact with Consul Connect
    debug          Records a debugging archive &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; operators
    event          Fire a new event
    &lt;span class=&quot;token builtin class-name&quot;&gt;exec&lt;/span&gt;           Executes a &lt;span class=&quot;token builtin class-name&quot;&gt;command&lt;/span&gt; on Consul nodes
    force-leave    Forces a member of the cluster to enter the &lt;span class=&quot;token string&quot;&gt;&quot;left&quot;&lt;/span&gt; state
    info           Provides debugging information &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; operators.
    intention      Interact with Connect &lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt; intentions
    &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;           Tell Consul agent to &lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt; cluster
    keygen         Generates a new encryption key
    keyring        Manages gossip layer encryption keys
    kv             Interact with the key-value store
    leave          Gracefully leaves the Consul cluster and shuts down
    lock           Execute a &lt;span class=&quot;token builtin class-name&quot;&gt;command&lt;/span&gt; holding a lock
    login          Login to Consul using an auth method
    &lt;span class=&quot;token builtin class-name&quot;&gt;logout&lt;/span&gt;         Destroy a Consul token created with login
    maint          Controls &lt;span class=&quot;token function&quot;&gt;node&lt;/span&gt; or &lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt; maintenance mode
    members        Lists the members of a Consul cluster
    monitor        Stream logs from a Consul agent
    operator       Provides cluster-level tools &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; Consul operators
    reload         Triggers the agent to reload configuration files
    rtt            Estimates network round trip &lt;span class=&quot;token function&quot;&gt;time&lt;/span&gt; between nodes
    services       Interact with services
    snapshot       Saves, restores and inspects snapshots of Consul server state
    tls            Builtin helpers &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; creating CAs and certificates
    validate       Validate config files/directories
    version        Prints the Consul version
    &lt;span class=&quot;token function&quot;&gt;watch&lt;/span&gt;          Watch &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token for-or-select variable&quot;&gt;changes&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; Consul&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[使用Drone进行CI支持]]></title><link>https://xenojoshua.com/posts/2019/12/drone-ci</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/12/drone-ci</guid><pubDate>Mon, 23 Dec 2019 02:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%A6%82%E5%BF%B5&quot;&gt;2. 概念&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-pipeline&quot;&gt;2.1 pipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-step&quot;&gt;2.2 step&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-workspace&quot;&gt;2.3 workspace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#24-trigger&quot;&gt;2.4 trigger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#25-condition&quot;&gt;2.5 condition&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E6%9E%B6%E6%9E%84--multiple-pipeline--parallelism&quot;&gt;3. 架构 &amp;#x26; Multiple Pipeline &amp;#x26; Parallelism&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E6%9E%B6%E6%9E%84&quot;&gt;3.1 架构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-multiple-pipeline&quot;&gt;3.2 Multiple Pipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-parallelism&quot;&gt;3.3 Parallelism&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8&quot;&gt;4. 使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-server%E5%AE%89%E8%A3%85--%E8%BF%90%E8%A1%8C&quot;&gt;4.1 Server：安装 &amp;#x26; 运行&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#411-oauth2%E5%87%86%E5%A4%87&quot;&gt;4.1.1 OAuth2准备&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#412-%E5%90%AF%E5%8A%A8drone&quot;&gt;4.1.2 启动drone&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#413-oauth2%E6%8E%88%E6%9D%83&quot;&gt;4.1.3 OAuth2授权&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#414-ui%E5%90%8C%E6%AD%A5--%E6%BF%80%E6%B4%BB%E4%BB%A3%E7%A0%81%E5%BA%93&quot;&gt;4.1.4 UI同步 &amp;#x26; 激活代码库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#415-api%E7%A7%98%E9%92%A5&quot;&gt;4.1.5 API秘钥&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-runner%E5%AE%89%E8%A3%85--%E8%BF%90%E8%A1%8C&quot;&gt;4.2 Runner：安装 &amp;#x26; 运行&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#421-%E5%AE%89%E8%A3%85&quot;&gt;4.2.1 安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#422-%E8%BF%90%E8%A1%8C&quot;&gt;4.2.2 运行&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-ui%E7%A7%98%E9%92%A5%E8%AE%BE%E7%BD%AE&quot;&gt;4.3 UI秘钥设置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E7%A7%81%E6%9C%89registry&quot;&gt;4.4 私有Registry&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#45-%E9%83%A8%E7%BD%B2--%E5%A4%9A%E7%82%B9%E4%BA%8B%E4%BB%B6%E8%A7%A6%E5%8F%91&quot;&gt;4.5 部署 &amp;#x26; 多点事件触发&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#451-drone-api--drone-cli&quot;&gt;4.5.1 drone api | drone cli&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#452-plugin&quot;&gt;4.5.2 plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#453-webhook-plugin&quot;&gt;4.5.3 webhook plugin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#454-webhook-fake&quot;&gt;4.5.4 webhook fake&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#455-waiting-hack&quot;&gt;4.5.5 waiting hack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Drone是一个Golang技术栈的CI解决方案，功能和Jenkins之类的CI工具类似。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Golang编写，分发及搭建非常容易（镜像体积很小）&lt;/li&gt;
&lt;li&gt;Golang编写，运行时占用资源极小（特指和Java栈的一系列工具比较）&lt;/li&gt;
&lt;li&gt;构建运行时以镜像优先，保证在不同平台的构建结果一致&lt;/li&gt;
&lt;li&gt;优秀的设计，支持插件化提供强大的功能支持&lt;/li&gt;
&lt;li&gt;现代化的UI，开箱即用，甩开Jenkins之类有历史包袱的工具几条街&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;较年轻，文档工作需要强化&lt;/li&gt;
&lt;li&gt;插件的数量和质量，以及插件的文档支持需要强化&lt;/li&gt;
&lt;li&gt;功能尚不能说强大，和Jenkins之类的老牌CI相比差距较大&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;简单选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Drone：
&lt;ul&gt;
&lt;li&gt;小型团队，对新技术适应能力较强的团队&lt;/li&gt;
&lt;li&gt;对功能的丰富性要求并不是很高，但要求性能强大功能稳定&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Jenkins：
&lt;ul&gt;
&lt;li&gt;对功能的丰富性要求较高，要求任何情况任何需求都能快速应对&lt;/li&gt;
&lt;li&gt;运维人员对Jenkins非常熟悉可以很快上手使用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;相关资源：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官方站点：&lt;a href=&quot;https://drone.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;drone.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;文档站点：&lt;a href=&quot;https://docs.drone.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;docs.drone.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;官方论坛：&lt;a href=&quot;https://discourse.drone.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;discourse.drone.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;2 概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 概念&lt;/h1&gt;
&lt;h2 id=&quot;21-pipeline&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-pipeline&quot; aria-label=&quot;21 pipeline permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 &lt;a href=&quot;https://docs.drone.io/configure/pipeline/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pipeline&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;pipeline是drone的核心概念&lt;/li&gt;
&lt;li&gt;pipeline一般负责完成一个&lt;code class=&quot;language-text&quot;&gt;任务&lt;/code&gt;：构建、发布、部署，其内部会有多个行为共同组成一个pipeline&lt;/li&gt;
&lt;li&gt;pipeline在drone里是进行分类的，按类型有多种种类，常用的有：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docker-runner.docs.drone.io/configuration/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;docker&lt;/a&gt;：所有的构建行为都在临时docker容器内进行，跨平台保证行为一致
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://exec-runner.docs.drone.io/configuration/variables/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://exec-runner.docs.drone.io/configuration/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;exec&lt;/a&gt;：所有的构建行为都在runner所在主机上进行，一般用在某些不方便放在容器内运行的工作，e.g xcode项目的构建
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docker-runner.docs.drone.io/configuration/environment/variables/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://ssh-runner.docs.drone.io/configuration/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ssh&lt;/a&gt;：构建行为通过ssh执行远程命令进行
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ssh-runner.docs.drone.io/configuration/variables/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;22-step&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-step&quot; aria-label=&quot;22 step permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 &lt;a href=&quot;https://docker-runner.docs.drone.io/configuration/steps/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;step&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;pipeline里的每一个操作被称为&lt;code class=&quot;language-text&quot;&gt;step&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;组织多个&lt;code class=&quot;language-text&quot;&gt;step&lt;/code&gt;可以完成一个特定的pipeline，e.g
&lt;ul&gt;
&lt;li&gt;构建pipeline：clone、安装依赖、单元测试、打包、制作镜像、推送镜像&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;23-workspace&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-workspace&quot; aria-label=&quot;23 workspace permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 &lt;a href=&quot;https://docker-runner.docs.drone.io/configuration/workspace/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;workspace&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;构建运行的工作空间，在不同的环境下其位置会有所不同&lt;/li&gt;
&lt;li&gt;Posix系统（含docker容器），工作空间在：&lt;code class=&quot;language-text&quot;&gt;/tmp/drone-${RANDOM}/drone/src&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;OSX系统，工作空间在：&lt;code class=&quot;language-text&quot;&gt;/private/var/folders/...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Win系统，工作空间在：&lt;code class=&quot;language-text&quot;&gt;C:\windows\drone-%RANDOM%\drone\src&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;有一点要强调下，如果在bash脚本中访问当前pipeline的&lt;code class=&quot;language-text&quot;&gt;~&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;$HOME&lt;/code&gt;，获得的地址就是workspace的根目录，而&lt;code class=&quot;language-text&quot;&gt;不是&lt;/code&gt;当前runner的用户home&lt;/li&gt;
&lt;li&gt;此外，workspace是临时的，会在pipeline创建的时候产生，并在完成的时候被销毁&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;24-trigger&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#24-trigger&quot; aria-label=&quot;24 trigger permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4 &lt;a href=&quot;https://docker-runner.docs.drone.io/configuration/trigger/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;trigger&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;trigger决定当前的&lt;code class=&quot;language-text&quot;&gt;pipeline&lt;/code&gt;是否要&lt;code class=&quot;language-text&quot;&gt;触发&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;trigger有很多类型：
&lt;ul&gt;
&lt;li&gt;根据分支：e.g 是否dev分支&lt;/li&gt;
&lt;li&gt;根据事件：e.g 是否tag事件（注意，tag和分支trigger不能同时存在，因为tag是不区分分支的）&lt;/li&gt;
&lt;li&gt;根据reference：e.g refs/tags/**&lt;/li&gt;
&lt;li&gt;根据代码库：e.g octocat/hello-world&lt;/li&gt;
&lt;li&gt;根据runner实例：e.g drone.instance1.com&lt;/li&gt;
&lt;li&gt;根据状态触发：e.g failure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;25-condition&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#25-condition&quot; aria-label=&quot;25 condition permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.5 &lt;a href=&quot;https://docker-runner.docs.drone.io/configuration/conditions/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;condition&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;condition决定当前的&lt;code class=&quot;language-text&quot;&gt;step&lt;/code&gt;是否要&lt;code class=&quot;language-text&quot;&gt;触发&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;condition有很多类型：
&lt;ul&gt;
&lt;li&gt;根据分支：e.g 是否dev分支&lt;/li&gt;
&lt;li&gt;根据事件：e.g 是否tag事件（注意，tag和分支condition不能同时存在，因为tag是不区分分支的）&lt;/li&gt;
&lt;li&gt;根据reference：e.g refs/tags/**&lt;/li&gt;
&lt;li&gt;根据代码库：e.g octocat/hello-world&lt;/li&gt;
&lt;li&gt;根据runner实例：e.g drone.instance1.com&lt;/li&gt;
&lt;li&gt;根据状态触发：e.g failure&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-架构--multiple-pipeline--parallelism&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E6%9E%B6%E6%9E%84--multiple-pipeline--parallelism&quot; aria-label=&quot;3 架构  multiple pipeline  parallelism permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 架构 &amp;#x26; Multiple Pipeline &amp;#x26; Parallelism&lt;/h1&gt;
&lt;h2 id=&quot;31-架构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E6%9E%B6%E6%9E%84&quot; aria-label=&quot;31 架构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 架构&lt;/h2&gt;
&lt;p&gt;Drone这个CI其实很简单，也说不上什么架构。一般Drone会有一个单点Server，在git工具上注册好webhook接收事件，然后启动多个Runner来处理Server上产生的任务。这些Runner可以在同一台主机上，也可以分散在多台不同的主机上，官方文档的指引中要求不要将runner和server放在同一台主机上。&lt;/p&gt;
&lt;h2 id=&quot;32-multiple-pipeline&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-multiple-pipeline&quot; aria-label=&quot;32 multiple pipeline permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 Multiple Pipeline&lt;/h2&gt;
&lt;p&gt;官方说明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Drone supports configuring and orchestrating multiple pipelines. This is useful when you need to fan-out and distribute your build tasks across multiple machines to reduce build times, or to execute your build tasks across multiple platforms (e.g. amd64 and arm64).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;用途1：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在处理大型项目任务的时候，将任务拆散，分散到不同的物理机上进行并行处理，加速整个构建进程。如果是不同主机的话，需要用到&lt;code class=&quot;language-text&quot;&gt;2.4&lt;/code&gt;提到的pipeline trigger，将不同的pipeline设定好自己的运行目标主机。保证同一个repo在不同主机上触发的时候，只有当前主机（runner）应该执行的pipeline得到执行。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;用途2：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;确定pipeline之间的先后顺序，通过在pipeline一级定义&lt;code class=&quot;language-text&quot;&gt;depends_on&lt;/code&gt;来申明相互之间的依赖关系。这里特别需要注意的是：pipeline之间是不共享workspace的。所以每一步都需要单独做类似于依赖安装之类的工作，这需要特别小心。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; p3

&lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; notify
  &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; p1
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; p2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;33-parallelism&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-parallelism&quot; aria-label=&quot;33 parallelism permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 Parallelism&lt;/h2&gt;
&lt;p&gt;这部分内容与 Multiple Pipeline 的关系，和之前讲过的 trigger 与 condition 的关系一样。Multiple Pipeline 是pipeline级别的，而Parallelism则是step级别的，本质上仍旧是并行运行。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; s3
  &lt;span class=&quot;token key atrule&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; s1
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; s2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;4 使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 使用&lt;/h1&gt;
&lt;h2 id=&quot;41-server安装--运行&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-server%E5%AE%89%E8%A3%85--%E8%BF%90%E8%A1%8C&quot; aria-label=&quot;41 server安装  运行 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 Server：安装 &amp;#x26; 运行&lt;/h2&gt;
&lt;h3 id=&quot;411-oauth2准备&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#411-oauth2%E5%87%86%E5%A4%87&quot; aria-label=&quot;411 oauth2准备 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.1 OAuth2准备&lt;/h3&gt;
&lt;p&gt;需要在git repo软件上申请一个OAuth应用。这里我使用的是Gitea，就拿它来做演示：&lt;/p&gt;
&lt;p&gt;点击：&lt;code class=&quot;language-text&quot;&gt;右上角头像 &gt; 设置（下拉菜单） &gt; 应用（页面中间）&lt;/code&gt;，打开的页面是管理用户级别的&lt;code class=&quot;language-text&quot;&gt;Access Tokens&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;OAuth2应用&lt;/code&gt;的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/oauth1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;找到：&lt;code class=&quot;language-text&quot;&gt;创建新的 OAuth2 应用程序&lt;/code&gt;这一栏，输入：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;应用名称：这名字后面用不到，填可理解的内容即可&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;重定向 URI&lt;/code&gt;：http://&lt;code class=&quot;language-text&quot;&gt;${drone_host}:${drone_ip}&lt;/code&gt;/login&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/oauth2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;点击&lt;code class=&quot;language-text&quot;&gt;创建应用&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;在打开的页面上显示了OAuth2应用的相关信息，这里需要记下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;客户端ID&lt;/li&gt;
&lt;li&gt;客户端秘钥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/oauth3.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;412-启动drone&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#412-%E5%90%AF%E5%8A%A8drone&quot; aria-label=&quot;412 启动drone permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.2 启动drone&lt;/h3&gt;
&lt;p&gt;Golang应用程序，使用上最容易的方式仍旧是镜像：&lt;a href=&quot;https://hub.docker.com/r/drone/drone&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;drone/drone&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;drone服务器启动时的环境变量文档在：&lt;a href=&quot;https://docs.drone.io/installation/reference/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Drone Documentation &gt; Installation &gt; Reference&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; drone-server &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18980&lt;/span&gt;:80 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    --log-driver&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;json-file &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    --log-opt max-size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;512m &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; /tmp/drone/data:/data &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# sqlite db file&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_LOGS_DEBUG&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_LOGS_COLOR&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_LOGS_PRETTY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_LOGS_TRACE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_AGENTS_ENABLED&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                                              &lt;span class=&quot;token comment&quot;&gt;# drone server running with no agents, start runners manually&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_GITEA_SKIP_VERIFY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                                           &lt;span class=&quot;token comment&quot;&gt;# gitea: use http protocol&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_GITEA_SERVER&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://host.docker.internal:13000 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                   &lt;span class=&quot;token comment&quot;&gt;# gitea: server address with protocol&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_GITEA_CLIENT_ID&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;fd023edb-7976-4d50-a92f-b16612683240 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;             &lt;span class=&quot;token comment&quot;&gt;# gitea: oauth client id&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_GITEA_CLIENT_SECRET&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;S4Q6PktE3dKNHPUzZrTdyNJsTThwal4doUWf6jf4eRA&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# gitea: oauth client secret &lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_RPC_SECRET&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;d9856af41ffe31f5e8025be020e981be &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                      &lt;span class=&quot;token comment&quot;&gt;# drone: runner shall connect server with this secret&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_SERVER_HOST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;host.docker.internal:18980 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                           &lt;span class=&quot;token comment&quot;&gt;# drone: server address without protocol&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_SERVER_PROTO&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                                                &lt;span class=&quot;token comment&quot;&gt;# drone: server with http protocol&lt;/span&gt;
    drone/drone:1.6.3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;413-oauth2授权&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#413-oauth2%E6%8E%88%E6%9D%83&quot; aria-label=&quot;413 oauth2授权 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.3 OAuth2授权&lt;/h3&gt;
&lt;p&gt;访问drone的地址：&lt;code class=&quot;language-text&quot;&gt;http://host.docker.internal:18980&lt;/code&gt;，会跳转到gitea进行授权，授权完成后会跳转回drone。这时应该就已经以刚才制作OAuth2应用的用户身份登录drone了。&lt;/p&gt;
&lt;p&gt;这里说明下，因为gitea和drone都运行在容器内，他们之间相互访问是通过容器名来进行的，而host主机访问这两者都是通过loopback地址，两者之间存在差异，会导致OAuth的过程失败。因此这里统一使用docker MAC desktop版本的&lt;code class=&quot;language-text&quot;&gt;host.docker.internal&lt;/code&gt;域名来贯通内部和外部。但需要额外修改host主机的&lt;code class=&quot;language-text&quot;&gt;/etc/hosts&lt;/code&gt;配置，把这个host解析为loopback地址。&lt;/p&gt;
&lt;h3 id=&quot;414-ui同步--激活代码库&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#414-ui%E5%90%8C%E6%AD%A5--%E6%BF%80%E6%B4%BB%E4%BB%A3%E7%A0%81%E5%BA%93&quot; aria-label=&quot;414 ui同步  激活代码库 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.4 UI同步 &amp;#x26; 激活代码库&lt;/h3&gt;
&lt;p&gt;刚完成授权的账户是没有任何代码库的，打开drone首页发现是空列表（即便当前通过OAuth2授权的账号在gitea内有代码库）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/drone1.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;点击右上角的&lt;code class=&quot;language-text&quot;&gt;SYNC&lt;/code&gt;就会开始和gitea同步账户的代码库数据，完成后即可获得所有当前账号在gitea内所拥有的代码库列表：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/drone2.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;这时候账号下的drone项目都是&lt;code class=&quot;language-text&quot;&gt;未激活&lt;/code&gt;状态，需要点击面板上项目右边的&lt;code class=&quot;language-text&quot;&gt;ACTIVATE&lt;/code&gt;进行激活：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/drone3.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2019/12/drone-ci/drone4.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;点击&lt;code class=&quot;language-text&quot;&gt;SAVE&lt;/code&gt;保存即可。经过这几个操作，drone即激活了对这几个代码库的webhook事件监听。&lt;/p&gt;
&lt;p&gt;至此为止drone本体的安装基本上完成了，后续还需要配置下runner。&lt;/p&gt;
&lt;h3 id=&quot;415-api秘钥&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#415-api%E7%A7%98%E9%92%A5&quot; aria-label=&quot;415 api秘钥 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.5 API秘钥&lt;/h3&gt;
&lt;p&gt;点击右上角的用户头像，然后点击&lt;code class=&quot;language-text&quot;&gt;User settings&lt;/code&gt;会打开用户的设置页面。在这个页面上能找到用户的token。如果有需要使用drone API的话（或者是cli命令行工具），这个token是必须的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/drone7.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;42-runner安装--运行&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-runner%E5%AE%89%E8%A3%85--%E8%BF%90%E8%A1%8C&quot; aria-label=&quot;42 runner安装  运行 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 Runner：安装 &amp;#x26; 运行&lt;/h2&gt;
&lt;h3 id=&quot;421-安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#421-%E5%AE%89%E8%A3%85&quot; aria-label=&quot;421 安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.1 安装&lt;/h3&gt;
&lt;p&gt;服务器设置完成后，如果没有单独安装和运行runner，服务器上所有触发的事件都会是&lt;code class=&quot;language-text&quot;&gt;Pending&lt;/code&gt;状态，而且没有任何日志。&lt;/p&gt;
&lt;p&gt;关于Pending的debug，可以看下官方的一篇帖子：&lt;a href=&quot;https://discourse.drone.io/t/builds-are-stuck-in-pending-status/4437&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Builds are Stuck in Pending Status&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Runner的安装见官方文档：&lt;a href=&quot;https://docs.drone.io/installation/runners/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Drone Documentation &gt; Installation &gt; Runners&lt;/a&gt;。Runner也分不同的类型，一般常用的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.drone.io/installation/runners/exec/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Exec Runner&lt;/a&gt;：直接运行在主机上的runner&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.drone.io/installation/runners/docker/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Docker Runner&lt;/a&gt;：运行在docker容器内的runner&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Runner的类型和pipeline的类型并不要求一致，runner只是pipeline的运行者，不管是什么类型的pipeline，都可以在任何类型的runner上运作。举例来说，一个docker类型的pipeline，在exec runner上就会在主机上启动docker容器并运行，而docker runner则是直接在docker容器内运行。&lt;/p&gt;
&lt;h3 id=&quot;422-运行&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#422-%E8%BF%90%E8%A1%8C&quot; aria-label=&quot;422 运行 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.2 运行&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Exec Runner&lt;/strong&gt;&lt;br&gt;
Exec Runner需要手动在&lt;code class=&quot;language-text&quot;&gt;~/.drone-runner-exec/config&lt;/code&gt;创建一个配置文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_DEBUG&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_LOG_FILE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/tmp/drone-runner-exec.txt
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_LOG_FILE_MAX_SIZE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_RPC_DUMP_HTTP&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_RPC_DUMP_HTTP_BODY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_RPC_PROTO&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_RPC_HOST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;host.docker.internal:18980
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_RPC_SECRET&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;d9856af41ffe31f5e8025be020e981be
&lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_RUNNER_PATH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.yarn/bin:&lt;span class=&quot;token environment constant&quot;&gt;$HOME&lt;/span&gt;/.config/yarn/global/node_modules/.bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;更多的配置项可以查阅官方文档：&lt;a href=&quot;https://exec-runner.docs.drone.io/installation/reference/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Exec Runner &gt; Installation &gt; Configuration Reference&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;配置文件里最重要的是&lt;code class=&quot;language-text&quot;&gt;DRONE_RPC_HOST``DRONE_RPC_SECRET&lt;/code&gt;这两项。修改完成后记得重启runner：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ drone-runner-exec &lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt; stop &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; drone-runner-exec &lt;span class=&quot;token function&quot;&gt;service&lt;/span&gt; start&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Runner在执行pipeline操作时候的用户即是runner启动时的用户，这需要非常小心，否则会搞错用户导致权限错误。此外，在2.3 workspace的时候也提到过了，在runner执行pipeline的时候，&lt;code class=&quot;language-text&quot;&gt;~&lt;/code&gt;指向的是workspace的根目录，而不是用户的home，这点要非常小心。&lt;/p&gt;
&lt;p&gt;举例来说，存放在&lt;code class=&quot;language-text&quot;&gt;$HOME/.docker&lt;/code&gt;下的凭证在exec runner运行的时候是不可访问的（&lt;code class=&quot;language-text&quot;&gt;~&lt;/code&gt;会定位到workspace而不是&lt;code class=&quot;language-text&quot;&gt;$HOME&lt;/code&gt;），这会导致私有registry的访问失败。同样的，pipeline运行时的PATH也不同于用户自身的PATH，需要在配置文件中设置好&lt;code class=&quot;language-text&quot;&gt;DRONE_RUNNER_PATH&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docker Runner&lt;/strong&gt;&lt;br&gt;
这部分就非常简单了，无非就是一个docker容器，直接使用对应的官方镜像即可：&lt;a href=&quot;https://hub.docker.com/r/drone/drone-runner-docker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;drone/drone-runner-docker&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;相关配置项可以查阅官方文档：&lt;a href=&quot;https://docker-runner.docs.drone.io/installation/reference/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Docker Runner &gt; Installation &gt; Configuration Reference&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;43-ui秘钥设置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-ui%E7%A7%98%E9%92%A5%E8%AE%BE%E7%BD%AE&quot; aria-label=&quot;43 ui秘钥设置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 UI秘钥设置&lt;/h2&gt;
&lt;p&gt;在执行pipeline的时候不可避免需要访问一些密码秘钥之类的信息，而构建过程中，理论上runner只能访问代码库里的内容。这就造成了问题，因为代码库并不是安全的存放秘钥的地方。针对这样的问题，drone有对应的解决方案。&lt;/p&gt;
&lt;p&gt;在drone ui仓库的设置中，有一处：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/drone5.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;设置完成后，就会保存在drone系统中：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/drone6.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;后续在pipeline可以如下的形式进行访问：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; default

&lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; build
  &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; alpine
  &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;USERNAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;from_secret&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; docker_username
    &lt;span class=&quot;token key atrule&quot;&gt;PASSWORD&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;from_secret&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; docker_password&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;更多关于secret的设置及访问，可以参见官方文档：&lt;a href=&quot;https://docs.drone.io/configure/secrets/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Drone Documentation &gt; Configuration &gt; Secrets&lt;/a&gt;。在这方面，drone支持得非常全面，甚至外部的加密设施也可以支持访问。&lt;/p&gt;
&lt;h2 id=&quot;44-私有registry&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E7%A7%81%E6%9C%89registry&quot; aria-label=&quot;44 私有registry permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 私有Registry&lt;/h2&gt;
&lt;p&gt;在pipeline应用的过程中，比较常见的问题是对于私有registry的访问。毕竟现在的CI基本上都围绕着镜像打转，抓取镜像进行部署或者构建镜像向上推送都是常见需求。&lt;/p&gt;
&lt;p&gt;官方对此也有解决方案：&lt;a href=&quot;https://discourse.drone.io/t/how-to-pull-private-images-with-1-0/3155&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to pull private images with 1.0&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;45-部署--多点事件触发&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#45-%E9%83%A8%E7%BD%B2--%E5%A4%9A%E7%82%B9%E4%BA%8B%E4%BB%B6%E8%A7%A6%E5%8F%91&quot; aria-label=&quot;45 部署  多点事件触发 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5 部署 &amp;#x26; 多点事件触发&lt;/h2&gt;
&lt;p&gt;上述的内容基本上把CI的最基础的应用都讲到了，如果只是简单的&lt;code class=&quot;language-text&quot;&gt;提交代码 &gt; 触发webhook &gt; drone pipeline&lt;/code&gt;这个流程的话，是没有问题的。&lt;/p&gt;
&lt;p&gt;那么接下来就可以考虑下稍微复杂点的需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目的构建和部署需要分开&lt;/li&gt;
&lt;li&gt;构建定义为一个pipeline&lt;/li&gt;
&lt;li&gt;部署定义为一个pipeline&lt;/li&gt;
&lt;li&gt;部署pipeline应该由构建pipeline异步触发&lt;/li&gt;
&lt;li&gt;部署pipeline应该和构建pipeline解耦，两者可能发生在完全隔离的两个物理机的runner上&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然后我简单说下结论：在当前的版本（drone/drone:1.6.3），这个需求&lt;code class=&quot;language-text&quot;&gt;做不到&lt;/code&gt;，如果是按官方的API和功能的话。而使用一些非官方的hacking思路，则可以做到&lt;code class=&quot;language-text&quot;&gt;基本上一致的效果&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;根据一开始说的，如果单独只是一个构建pipeline，很简单就能做到。而如果要实现刚才列出的需求，就需要在构建pipeline完成并退出之前触发一个额外的事件，只要能触发额外的事件，再配合上：trigger &amp;#x26; condition，保证代码库的pipeline启动的时候，只有部署pipeline进入工作，且只有正确的runner实例进入工作，那一切就通了。&lt;/p&gt;
&lt;p&gt;那么，能不能手动触发一个部署呢？研究了下官方的资料，发现正常途径基本上做不到，只有一些非正常的思路才可以做到。下面说下思路。&lt;/p&gt;
&lt;h3 id=&quot;451-drone-api--drone-cli&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#451-drone-api--drone-cli&quot; aria-label=&quot;451 drone api  drone cli permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.1 drone api | drone cli&lt;/h3&gt;
&lt;p&gt;首先想到的是看看官方的API中有没有可用的命令（cli实际上就是官方API的封装）：&lt;a href=&quot;https://docs.drone.io/api/overview/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;API文档&lt;/a&gt;、&lt;a href=&quot;https://docs.drone.io/cli/install/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CLI文档&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;发现官方有一个命令：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ drone build promote &lt;span class=&quot;token parameter variable&quot;&gt;--help&lt;/span&gt;
  NAME:
     drone build promote - promote a build
  
  USAGE:
     drone build promote &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;command options&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;repo/name&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;build&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;environment&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  
  OPTIONS:
     &lt;span class=&quot;token parameter variable&quot;&gt;--param&lt;/span&gt; value, &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; value  custom parameters to be injected into the job environment. Format: &lt;span class=&quot;token assign-left variable&quot;&gt;KEY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;value
     &lt;span class=&quot;token parameter variable&quot;&gt;--format&lt;/span&gt; value           &lt;span class=&quot;token function&quot;&gt;format&lt;/span&gt; output &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;default: &lt;span class=&quot;token string&quot;&gt;&quot;...&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结合&lt;code class=&quot;language-text&quot;&gt;.drone.yml&lt;/code&gt;使用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; exec
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; test

&lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; darwin
  &lt;span class=&quot;token key atrule&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; amd64

&lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; test
    &lt;span class=&quot;token key atrule&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; echo &quot;tested&quot;
    &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; tag

&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; exec
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; build

&lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; darwin
  &lt;span class=&quot;token key atrule&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; amd64

&lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; build
    &lt;span class=&quot;token key atrule&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; echo &quot;built&quot;
    &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; tag

&lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; test

&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; exec
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; notify

&lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; darwin
  &lt;span class=&quot;token key atrule&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; amd64

&lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; notify
    &lt;span class=&quot;token key atrule&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; drone build promote fullstack/gateway 100 production
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;DRONE_SERVER&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//host.docker.internal&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;18980&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;DRONE_TOKEN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; K5i8g6PMlLM3tWaPDRagigPkBrl1YKGu
    &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; tag

&lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; build

&lt;span class=&quot;token punctuation&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; pipeline
&lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; exec
&lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; deploy

&lt;span class=&quot;token key atrule&quot;&gt;platform&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; darwin
  &lt;span class=&quot;token key atrule&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; amd64

&lt;span class=&quot;token key atrule&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; deploy
    &lt;span class=&quot;token key atrule&quot;&gt;commands&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; echo &quot;deployed&quot;
    &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; promote
      &lt;span class=&quot;token key atrule&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; production&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;测试后发现，如果&lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;参数给的是已经存在的构建的话，则会重复之前的构建流程；而如果给的是一个很大的不存在该build的值（比如上面举例的100），则构建在notify这一步失败，并报错：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;+ drone build promote fullstack/gateway &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; production
client error &lt;span class=&quot;token number&quot;&gt;404&lt;/span&gt;: &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sql: no rows in result set&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;查找了下相关资料，并没有找到官方文档，仅在论坛中找到几篇讨论：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://discourse.drone.io/t/manually-trigger-a-build/874/8&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Manually trigger a build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://discourse.drone.io/t/promoting-a-build-by-branch/4755&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Promoting a build by branch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/drone/drone/issues/2679#issue-435262568&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Trigger build for Branch, Commit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根据官方人员的解释：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When you deploy, you are essentially “promoting” a build, which means you need to provide the build number you are promoting, and the environment you are promoting to. For example:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;drone deploy octocat/hello-world 42 production&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In the above example, you are promoting build 42 to production. This will execute a deployment event in the system with environment name production.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也就是说你只能对&lt;code class=&quot;language-text&quot;&gt;已经存在&lt;/code&gt;的build进行触发让这个&lt;code class=&quot;language-text&quot;&gt;已经测试构建完成的&lt;/code&gt;build进行部署，而不能从头创建一个新的build。也就是说，上述的工具能大致满足上面提出的那串需求，但本质上还是不同的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;测试构建等必须是一个单独的行为，需要先行做完，并形成一个完成的build&lt;/li&gt;
&lt;li&gt;需要手动触发（因为你需要确认build号，所以这个行为必然是手动的，不可能自动化）这个完成的build，让yaml中配置为promote的event触发，进行部署&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;452-plugin&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#452-plugin&quot; aria-label=&quot;452 plugin permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.2 plugin&lt;/h3&gt;
&lt;p&gt;官方有一个插件叫：&lt;a href=&quot;http://plugins.drone.io/drone-plugins/drone-downstream/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Downstream Build&lt;/a&gt;。乍看之下貌似是满足需求的，但我实际扒了下源码，发现这个插件的本质其实就是封装了下官方的API。所以实际上和4.5.1一样，不行。&lt;/p&gt;
&lt;h3 id=&quot;453-webhook-plugin&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#453-webhook-plugin&quot; aria-label=&quot;453 webhook plugin permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.3 webhook plugin&lt;/h3&gt;
&lt;p&gt;后续的思路是尝试使用webhook插件，在构建pipeline完成之后用webhook触发一个构建：&lt;a href=&quot;http://plugins.drone.io/drone-plugins/drone-webhook/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Webhook&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;文档工作总是半吊子，参数有几个根本不知道具体应该填什么，只能随便尝试下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;PLUGIN_URLS&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://host.docker.internal:18980/hook &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;PLUGIN_USERNAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;root &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;PLUGIN_PASSWORD&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;Abcd1234_ &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;PLUGIN_DEBUG&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;PLUGIN_SKIP_VERIFY&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;true &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_REPO_OWNER&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;fullstack &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_REPO_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;gateway &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_COMMIT_SHA&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;2087d78f48 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_COMMIT_BRANCH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;master &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;DRONE_BUILD_EVENT&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;deployment &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
          plugins/webhook:latest
Webhook &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
  URL: http://host.docker.internal:18980/hook
  METHOD: POST
  HEADERS: map&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Authorization:&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Basic &lt;span class=&quot;token assign-left variable&quot;&gt;cm9vdDpBYmNkMTIzNF8&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; Content-Type:&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;application/json&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  REQUEST BODY: &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;repo&quot;&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;owner&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fullstack&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;gateway&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;build&quot;&lt;/span&gt;:&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tag&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;deployment&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;number&quot;&lt;/span&gt;:0,&lt;span class=&quot;token string&quot;&gt;&quot;commit&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2087d78f48&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;ref&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;refs/heads/master&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;branch&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;master&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;status&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;success&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;link&quot;&lt;/span&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;,&lt;span class=&quot;token string&quot;&gt;&quot;started&quot;&lt;/span&gt;:0,&lt;span class=&quot;token string&quot;&gt;&quot;created&quot;&lt;/span&gt;:0&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  RESPONSE STATUS: &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; OK
  RESPONSE BODY:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;返回结果是200，正常，但结果本身为&lt;code class=&quot;language-text&quot;&gt;空&lt;/code&gt;。查看drone的UI发现实际上没有任何build被触发。这就很无奈了，这里的问题可能出在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;操作者：给的参数不正确&lt;/li&gt;
&lt;li&gt;webhook插件：没有发送正确的webhook请求&lt;/li&gt;
&lt;li&gt;drone服务器：忽略了不正确的webhook请求&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;无论如何，后续如果要继续的话就需要看源码了，插件的以及服务器的源码。&lt;/p&gt;
&lt;h3 id=&quot;454-webhook-fake&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#454-webhook-fake&quot; aria-label=&quot;454 webhook fake permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.4 webhook fake&lt;/h3&gt;
&lt;p&gt;到这里就是非正常思路了。&lt;/p&gt;
&lt;p&gt;因为gitea可以正常触发drone的webhook，思路就是使用curl仿造gitea的请求，发送到drone。其实drone官方也有对webhook的描述：&lt;a href=&quot;https://discourse.drone.io/t/how-to-use-global-webhooks/3755&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to use Global Webhooks&lt;/a&gt;，但实在是没什么正式的支持，API之类的易用性的工具都没有，只有这篇文章。&lt;/p&gt;
&lt;p&gt;gitea官方有webhook相关的文档：&lt;a href=&quot;https://docs.gitea.io/en-us/webhooks/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Webhooks&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;gitea的钩子可以在这里找到，点击下面的链接可以查看请求细节：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/12/drone-ci/gitea1.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2019/12/drone-ci/gitea2.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2019/12/drone-ci/gitea3.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;当然这也非常麻烦，而且gitea发送出去的webhook请求里有非常多repo详细信息，如果要做到自动化的话，这块的获取也是很麻烦的一件事情。&lt;/p&gt;
&lt;h3 id=&quot;455-waiting-hack&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#455-waiting-hack&quot; aria-label=&quot;455 waiting hack permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.5 waiting hack&lt;/h3&gt;
&lt;p&gt;另一个非正常思路就是定义一个pipeline，仅在指定的runner上运行，然后命令中执行脚本，查询私有registry，看目标仓库（镜像）的目标tag是否存在，存在的话就进行部署。而在其他的runner上进行构建和镜像推送操作。&lt;/p&gt;
&lt;p&gt;这样就能做到一开始提的需求，虽然恶心了点。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[在Docker中使用Node]]></title><link>https://xenojoshua.com/posts/2019/12/node-in-docker</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/12/node-in-docker</guid><pubDate>Wed, 11 Dec 2019 02:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E9%95%9C%E5%83%8F%E5%88%B6%E4%BD%9C&quot;&gt;2. 镜像制作&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-npm&quot;&gt;2.1 npm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E9%95%9C%E5%83%8F%E5%88%B6%E4%BD%9C&quot;&gt;2.2 镜像制作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-%E9%95%9C%E5%83%8Fstage&quot;&gt;2.3 镜像stage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E9%9B%86%E7%BE%A4%E5%A4%84%E7%90%86%E5%8F%8A%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86&quot;&gt;3. 集群处理及反向代理&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-pm2--nginx&quot;&gt;3.1 pm2 + nginx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-docker-compose--nginx&quot;&gt;3.2 docker-compose + nginx&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E5%81%A5%E5%BA%B7%E6%A3%80%E6%9F%A5&quot;&gt;4. 健康检查&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;在Docker中使用Node，中间遇到了相当多的问题，这里就简单记录下，以防忘记。下述的所有范例都是使用typescript进行逻辑编写的，并在Docker中进行编译制作镜像的，周知。&lt;/p&gt;
&lt;h1 id=&quot;2-镜像制作&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E9%95%9C%E5%83%8F%E5%88%B6%E4%BD%9C&quot; aria-label=&quot;2 镜像制作 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 镜像制作&lt;/h1&gt;
&lt;h2 id=&quot;21-npm&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-npm&quot; aria-label=&quot;21 npm permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 npm&lt;/h2&gt;
&lt;p&gt;在Dockerfile里的npm安装记得要加上&lt;code class=&quot;language-text&quot;&gt;--unsafe-perm&lt;/code&gt;，具体可以看：&lt;a href=&quot;https://github.com/grpc/grpc-node/issues/604&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc/grpc-node#604&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;22-镜像制作&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E9%95%9C%E5%83%8F%E5%88%B6%E4%BD%9C&quot; aria-label=&quot;22 镜像制作 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 镜像制作&lt;/h2&gt;
&lt;p&gt;Docker的&lt;code class=&quot;language-text&quot;&gt;COPY&lt;/code&gt;命令是将命令对应的文件夹&lt;code class=&quot;language-text&quot;&gt;下&lt;/code&gt;的所有内容拷贝到目标位置，而不包含命令中的文件夹本身，这是必须先了解的基础。&lt;/p&gt;
&lt;p&gt;一般来说node项目的资源都会比较多比较散，不会像go应用程序一样build完成之后就是一个binary文件，node会有很多零碎的文件和代码都必须拷贝到镜像里。这里就需要先制作一个context。&lt;/p&gt;
&lt;p&gt;假设项目的文件夹结构如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/- 
 | bash /-              # bash脚本
 |       | compose.sh   # 制作compose配置文件的脚本
 |       | docker.sh    # 制作镜像的脚本
 | build                # 编译完成的js文件
 | node_modules         # npm包
 | schema               # sql文件
 | src                  # typescript源码
 | .gitignore
 | Dockerfile
 | package.json
 | config.yml
 | README.md
 | tsconfig.json
 | tslint.json
 | yarn.lock&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;则可以使用如下脚本制作一个context子集，并进行镜像制作：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;FULLPATH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$( cd &quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dirname&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$0&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;pwd&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
cd &lt;span class=&quot;token variable&quot;&gt;${FULLPATH}&lt;/span&gt;/..

VERSION=&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; ./package.json &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.version&apos;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;

# prepare docker context
rm -rf ./docker                 # 删除之前的context，如果有的话
mkdir -p ./docker/context       # 制作context文件夹
mkdir -p ./docker/context/pm2   # 制作PM2日志文件夹，后面会说到
cp -r \                         # 拷贝制作镜像需要的资源到context内
    src \
    config.yml \
    package.json \
    tsconfig.json \
    tslint.json \
    yarn.lock \
    ./docker/context

# build image
docker build \
    --no-cache \
    --tag your_app_name:&lt;span class=&quot;token variable&quot;&gt;${VERSION}&lt;/span&gt; \
    --file ./Dockerfile \
    ./docker

# remove images without tags
docker rmi &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; images &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/^&amp;lt;none&gt;/ {print $3}&apos;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;  # 当制作tag重复的镜像时，这个命令就很有用

# remove tmp file
rm -rf ./docker

# push image
ORIGIN_TAG=&quot;&lt;/span&gt;you_app_name:&lt;span class=&quot;token variable&quot;&gt;${VERSION}&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
TARGET_TAG=&quot;&lt;/span&gt;your_dockerhub_account/you_app_name:&lt;span class=&quot;token variable&quot;&gt;${VERSION}&lt;/span&gt;&quot;
&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; tag &lt;span class=&quot;token variable&quot;&gt;${ORIGIN_TAG}&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${TARGET_TAG}&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; push &lt;span class=&quot;token variable&quot;&gt;${TARGET_TAG}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;23-镜像stage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-%E9%95%9C%E5%83%8Fstage&quot; aria-label=&quot;23 镜像stage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 镜像stage&lt;/h2&gt;
&lt;p&gt;node的镜像在制作过程中，需要一些命令进行辅助，而这些命令在基准的node镜像上是不存在的，因此就需要在Dockerfile中先npm安装它们。比如说typescript、yarn等。而这些安装行为都会显著增大镜像的体积，因此这里就需要使用到按stage进行构建的技术。&lt;/p&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://docs.docker.com/develop/develop-images/multistage-build/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Use multi-stage builds&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;先放一个例子：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;docker&quot;&gt;&lt;pre class=&quot;language-docker&quot;&gt;&lt;code class=&quot;language-docker&quot;&gt;&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; node:10.16.3-alpine &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; builder&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /opt&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; ./context ./&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;RUN&lt;/span&gt; npm i typescript -g --unsafe-perm &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    npm i --only=prod --unsafe-perm --loglevel verbose &amp;amp;&amp;amp; &lt;span class=&quot;token operator&quot;&gt;\&lt;/span&gt;
    tsc&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; node:10.16.3-alpine&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;WORKDIR&lt;/span&gt; /app&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;COPY&lt;/span&gt; &lt;span class=&quot;token options&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;builder&lt;/span&gt;&lt;/span&gt; /opt .&lt;/span&gt;

&lt;span class=&quot;token instruction&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;ENTRYPOINT&lt;/span&gt; [&lt;span class=&quot;token string&quot;&gt;&quot;node&quot;&lt;/span&gt;, &lt;span class=&quot;token string&quot;&gt;&quot;./build/index.js&quot;&lt;/span&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该Dockerfile的上半部分将&lt;code class=&quot;language-text&quot;&gt;./context&lt;/code&gt;下的所有内容拷贝到&lt;code class=&quot;language-text&quot;&gt;/opt&lt;/code&gt;这个工作路径下。然后安装了typescript，并根据&lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt;的内容进行npm包的安装。接下来使用刚才安装好的typescript命令&lt;code class=&quot;language-text&quot;&gt;tsc&lt;/code&gt;根据&lt;code class=&quot;language-text&quot;&gt;tsconfig.json&lt;/code&gt;的配置将src文件夹下的源码编译为&lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt;文件夹下的js源码。&lt;/p&gt;
&lt;p&gt;从下半部分的&lt;code class=&quot;language-text&quot;&gt;FROM node:10.16.3-alpine&lt;/code&gt;开始，起了一个干净的node镜像，并将&lt;code class=&quot;language-text&quot;&gt;builder&lt;/code&gt;这个阶段做好的内容从builder阶段的&lt;code class=&quot;language-text&quot;&gt;/opt&lt;/code&gt;文件夹下拷贝到&lt;code class=&quot;language-text&quot;&gt;/app&lt;/code&gt;下。这里仍旧需要注意&lt;code class=&quot;language-text&quot;&gt;COPY&lt;/code&gt;命令是不会拷贝目标文件夹自身的，只会拷贝文件夹下的内容。这样制作完成的镜像中就不会包含之前安装的typescript了。&lt;/p&gt;
&lt;p&gt;这个例子简单了点，只有一个typescript，如果在构建过程中还要用到一些其他东西的话，效果（体积变化）就会非常明显。&lt;/p&gt;
&lt;h1 id=&quot;3-集群处理及反向代理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E9%9B%86%E7%BE%A4%E5%A4%84%E7%90%86%E5%8F%8A%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86&quot; aria-label=&quot;3 集群处理及反向代理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 集群处理及反向代理&lt;/h1&gt;
&lt;p&gt;node作为一个单进程单线程的应用程序，在利用CPU上实在是不行，所以就需要一些外部程序的辅助来充分利用物理CPU。一般有两个解决方案。下述解决方案中的Nginx跑在容器里或跑在主机上都是可以的，没有任何区别。&lt;/p&gt;
&lt;h2 id=&quot;31-pm2--nginx&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-pm2--nginx&quot; aria-label=&quot;31 pm2  nginx permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 pm2 + nginx&lt;/h2&gt;
&lt;p&gt;这个解决方案只需要启动一个应用程序容器，在容器内使用PM2对应用程序进行cluster化，由PM2监听单个端口并转发所有的进入请求。在应用程序容器之外，由Nginx处理所有到达主机的请求。&lt;/p&gt;
&lt;p&gt;这里就涉及到在容器内使用PM2。首先需要安装PM2，需要在之前范例中的Dockerfile中的&lt;code class=&quot;language-text&quot;&gt;COPY --from=builder /opt .&lt;/code&gt;之后添加一行：&lt;code class=&quot;language-text&quot;&gt;RUN npm i pm2 -g --unsafe-perm --loglevel verbose&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;然后在容器运行的&lt;code class=&quot;language-text&quot;&gt;ENTRYPOINT&lt;/code&gt;上，需要修改成：&lt;code class=&quot;language-text&quot;&gt;ENTRYPOINT [&quot;pm2-runtime&quot;, &quot;start&quot;, &quot;./build/index.js&quot;]&lt;/code&gt;。这里注意，启动命令中使用的不是&lt;code class=&quot;language-text&quot;&gt;pm2&lt;/code&gt;而是&lt;code class=&quot;language-text&quot;&gt;pm2-runtime&lt;/code&gt;。这个命令是为了在容器内使用而专门特化出来的，普通的pm2命令在启动后就会转后台，导致容器退出。&lt;/p&gt;
&lt;p&gt;此外，在使用时可以附加一些参数：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; your_app_name &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;:3000 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-v&lt;/span&gt; dir_of_host:/app/pm2 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                       &lt;span class=&quot;token comment&quot;&gt;# 映射到主机上的日志文件路径&lt;/span&gt;
    your_app_name:version &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;your_app_name_in_pm2 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--instances&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;max &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;                               &lt;span class=&quot;token comment&quot;&gt;# 以cluster模式启动pm2，并按CPU数量启动node应用的进程&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--output&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/app/pm2/your_app_name.stdout.log &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;    &lt;span class=&quot;token comment&quot;&gt;# 输出日志到pm2文件夹下，也就是之前在做context时特地做出来的文件夹&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;/app/pm2/your_app_name.stderr.log &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;32-docker-compose--nginx&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-docker-compose--nginx&quot; aria-label=&quot;32 docker compose  nginx permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 docker-compose + nginx&lt;/h2&gt;
&lt;p&gt;这个方案比较粗暴，之前提到的Dockerfile不需要改动，容器仍旧只有一个进程一个线程，容器本身并不做任何改动。而是使用docker-compose命令启动多个容器，然后在Nginx中配置upstream来进行反向代理负载均衡。&lt;/p&gt;
&lt;p&gt;使用如下bash脚本来生成compose配置文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token shebang important&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;token assign-left variable&quot;&gt;FULLPATH&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;$( cd &quot;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dirname&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token variable&quot;&gt;$0&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token builtin class-name&quot;&gt;pwd&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-P&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
cd &lt;span class=&quot;token variable&quot;&gt;${FULLPATH}&lt;/span&gt;/..

VERSION=&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; ./package.json &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; jq &lt;span class=&quot;token parameter variable&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.version&apos;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;

CONF=&lt;span class=&quot;token variable&quot;&gt;${FULLPATH}&lt;/span&gt;/../compose.yml

PROCESS_COUNT=8

PORT_BASE=3000

COMPOSE_TEMPLATE=&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;EOC
version: &quot;2.1&quot;

networks:
  net:
    driver: bridge

services:
EOC&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

function generate_compose() {
    OUTPUT=&lt;span class=&quot;token variable&quot;&gt;${COMPOSE_TEMPLATE}&lt;/span&gt;

    for &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;((&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt;${PROCESS_COUNT}&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
    do
        ID=&lt;span class=&quot;token variable&quot;&gt;${i}&lt;/span&gt;
        PORT=&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$((&lt;/span&gt;PORT_BASE &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; ID&lt;span class=&quot;token variable&quot;&gt;))&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

        SERVICE_TEMPLATE=&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cat&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;EOS
  you_app_name_&lt;span class=&quot;token variable&quot;&gt;${ID}&lt;/span&gt;:
    image: your_dockerhub_account/you_app_name:&lt;span class=&quot;token variable&quot;&gt;${VERSION}&lt;/span&gt;
    container_name: you_app_name_&lt;span class=&quot;token variable&quot;&gt;${ID}&lt;/span&gt;
    hostname: you_app_name_&lt;span class=&quot;token variable&quot;&gt;${ID}&lt;/span&gt;
    networks:
      - net
    ports:
      - &lt;span class=&quot;token variable&quot;&gt;${PORT}&lt;/span&gt;:3000
    logging:
      driver: json-file
      options:
        max-size: 512m
    restart: always
    volumes:
      - dir_of_host:/app/pm2
    command: [
      &quot;--name=your_app_name_in_pm2_&lt;span class=&quot;token variable&quot;&gt;${ID}&lt;/span&gt;&quot;,
      &quot;--instances=max&quot;,
      &quot;--output=/app/pm2/your_app_name_&lt;span class=&quot;token variable&quot;&gt;${ID}&lt;/span&gt;.stdout.log&quot;,
      &quot;--error=/app/pm2/your_app_name_&lt;span class=&quot;token variable&quot;&gt;${ID}&lt;/span&gt;.stderr.log&quot;
    ]
EOS&lt;/span&gt;
&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;

        NL=$&apos;&lt;span class=&quot;token entity&quot; title=&quot;\n&quot;&gt;\n&lt;/span&gt;&apos;
        OUTPUT=&quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${OUTPUT}&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${NL}&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${SERVICE_TEMPLATE}&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;
    done

    echo &quot;&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;${OUTPUT}&lt;/span&gt;&quot; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${CONF}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

generate_compose&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;当然也可以编写一个脚本来制作nginx的配置文件，这里就简略点，直接改了：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;upstream upstream_node &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3001 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3002 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3003 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3004 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3005 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3006 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3007 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    server &lt;span class=&quot;token number&quot;&gt;127.0&lt;/span&gt;.0.1:3008 &lt;span class=&quot;token assign-left variable&quot;&gt;max_fails&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;fail_timeout&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;weight&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

server &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    listen &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    listen &lt;span class=&quot;token number&quot;&gt;443&lt;/span&gt; ssl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ssl_prefer_server_ciphers on&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    ssl_certificate         cert/yourapp.youhost.com.key.pem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ssl_certificate_key     cert/yourapp.youhost.com.key&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    ssl_dhparam             cert/dhparam.pem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    access_log /var/log/nginx/yourapp.youhost.com.access.log&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    error_log /var/log/nginx/yourapp.youhost.com.error.log&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    root /usr/share/nginx/html&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    index index.html index.htm&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    server_name yourapp.youhost.com&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    location / &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        proxy_set_header x-Forwarded-For &lt;span class=&quot;token variable&quot;&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_set_header HOST &lt;span class=&quot;token variable&quot;&gt;$http_host&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_set_header X-Forwarded-Proto https&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_redirect http:// https://&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_connect_timeout &lt;span class=&quot;token number&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_send_timeout &lt;span class=&quot;token number&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_read_timeout &lt;span class=&quot;token number&quot;&gt;240&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        proxy_pass http://upstream_node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-健康检查&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E5%81%A5%E5%BA%B7%E6%A3%80%E6%9F%A5&quot; aria-label=&quot;4 健康检查 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 健康检查&lt;/h1&gt;
&lt;p&gt;在容器内运行的node程序，可以设置一个专门用来进行健康检查的端点，然后在运行时进行配置，这样docker就可以了解程序是否存活。在配合consul等服务发现程序使用时，也可以使用该端点。&lt;/p&gt;
&lt;p&gt;应用程序代码改动：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;app&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Koa&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; next&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;path &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/health&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;OK&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Docker compose yml改动：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; always
&lt;span class=&quot;token key atrule&quot;&gt;healthcheck&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; wget http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//127.0.0.1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;3000/health &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;q &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;O &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt; /dev/null 2&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token important&quot;&gt;&amp;amp;1&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;interval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 10s
  &lt;span class=&quot;token key atrule&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 20s
  &lt;span class=&quot;token key atrule&quot;&gt;retries&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[在VirtualBox中安装Tor]]></title><link>https://xenojoshua.com/posts/2019/09/virtualbox-tor</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/09/virtualbox-tor</guid><pubDate>Fri, 20 Sep 2019 02:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-virtualbox&quot;&gt;2. VirtualBox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-linux&quot;&gt;3. Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-tor&quot;&gt;4. Tor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;就是一篇简单的笔记。&lt;/p&gt;
&lt;h1 id=&quot;2-virtualbox&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-virtualbox&quot; aria-label=&quot;2 virtualbox permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. VirtualBox&lt;/h1&gt;
&lt;p&gt;这块不需要很详细的讲解，基本上只要从官网下载binary直接使用即可。镜像需要提前下载好，VirtualBox安装比较奇怪的一点是，虚拟机的创建和操作系统的安装是分开的，会先创建出虚拟机实例，然后才是加载镜像进行虚拟机操作系统的安装。这点有点和其他的虚拟机不太相同。&lt;/p&gt;
&lt;p&gt;VirtualBox虚拟机的显示自适应需要额外设置，比较麻烦。显示设置的屏幕里，需要把显卡控制器改成：&lt;code class=&quot;language-text&quot;&gt;VBoxSVGA&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;3-linux&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-linux&quot; aria-label=&quot;3 linux permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Linux&lt;/h1&gt;
&lt;p&gt;这里使用的是Ubuntu Desktop版本，因为后续安装和使用Tor最简单的做法就是直接使用官方的Tor Browser，也正因此需要桌面版本的操作系统。如果对安全有更高的要求，可以使用FreeBSD操作系统。&lt;/p&gt;
&lt;p&gt;软件安装：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; build-essential
$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;vim&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;安装virtualbox的辅助程序&lt;code class=&quot;language-text&quot;&gt;Devices &gt; Insert Guest Additions CD Image&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;按个人喜好，可选安装：&lt;a href=&quot;https://linuxize.com/post/how-to-install-sublime-text-3-on-ubuntu-18-04/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;sublime text3&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;安装privoxy，用来给需要HTTP代理的应用程序做前置入口，将这些HTTP流量转为socks5流量，进入到tor：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; privoxy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;修改配置文件&lt;code class=&quot;language-text&quot;&gt;/etc/privoxy/config&lt;/code&gt;：添加&lt;code class=&quot;language-text&quot;&gt;forward-socks5 / localhost:9150 .&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;后续可以在命令行下设置：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;http_proxy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://127.0.0.1:8118
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;https_proxy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://127.0.0.1:8118&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;命令行流量就全走tor了。命令行下，可以使用&lt;code class=&quot;language-text&quot;&gt;curl ipinfo.io&lt;/code&gt;来查看当前IP的位置。&lt;/p&gt;
&lt;p&gt;在tor安装成功之前，虚拟机肯定也是需要代理的，否则tor软件根本下不下来。可以通过Linux操作系统&lt;code class=&quot;language-text&quot;&gt;网络配置&lt;/code&gt;设置代理：&lt;/p&gt;
&lt;p&gt;将所有的HTTP(s)代理设置成：192.168.xx.xx:xxxx，socks设置成192.168.xx.xx:xxxx。&lt;/p&gt;
&lt;p&gt;命令行下则：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;http_proxy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://192.168.xx.xx:xxxx
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;https_proxy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://192.168.xx.xx:xxxx&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-tor&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-tor&quot; aria-label=&quot;4 tor permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Tor&lt;/h1&gt;
&lt;p&gt;安装就直接从官网上下载Tor Browser，解压即可使用。配置文件位置：&lt;code class=&quot;language-text&quot;&gt;Browser/TorBrowser/Data/Tor/torrc&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;国内使用的时候必须使用网桥，按软件提示直接选一个可用的网桥，或从数据库申请一个网桥即可。注意，从数据库申请下来的网桥不一定就是可用的，还是需要连接测试。如果有条件的话，可以在Tor Browser之前再自己做一个跳板，这样效果会好很多，无论是从隐匿性上来说，还是从可用性上来说。&lt;/p&gt;
&lt;p&gt;Tor Browser在连接完成之后，会在本地打开一个端口&lt;code class=&quot;language-text&quot;&gt;9150&lt;/code&gt;，提供本地的socks5连接。但软件并不提供HTTP和HTTPS代理，需要之前提到过的privoxy软件进行转换即可。&lt;/p&gt;
&lt;p&gt;对Tor的节点进行限制，直接在之前提到的配置文件里添加内容即可，注意不要修改网桥相关的配置内容，那些是软件自动生成添加的：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;## 以下为排除的节点(StrictNodes 1为坚决执行)&lt;/span&gt;
ExcludeNodes &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cn&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;hk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;mo&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kp&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ir&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cu&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;vn&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ru&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sd&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kz&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;uz&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;pk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kg&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tj&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tm&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tr&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sy&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sg&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;th&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ph&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;my&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;lk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
ExcludeExitNodes &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cn&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;hk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;mo&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kp&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ir&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cu&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;vn&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ru&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;by&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sd&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kz&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;uz&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;pk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kg&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tj&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tm&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tr&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sy&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sg&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;th&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ph&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;my&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;lk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#ExcludeNodes 是指排除节点，即把括号中的国家的节点从tor链路上除去&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#ExcludeExitNodes 是指“排除“出口”节点”，即tor的出口节点要排除括号中的国家的节点&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;## 指定出口节点：&lt;/span&gt;
StrictNodes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
ExitNodes &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;us&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#这里us是指限定美国的ip为出口ip，你可以改为任何国家，国家代码请参考：https://zh.wikipedia.org/zh-cn/ISO_3166-1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;轻量级过滤：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;ExcludeNodes &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cn&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;hk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;mo&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
ExcludeExitNodes &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cn&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;hk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;mo&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;kp&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ir&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cu&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;vn&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sd&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;pk&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;,&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sy&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
StrictNodes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[分布式系统实战]]></title><link>https://xenojoshua.com/posts/2019/07/dist-system-practice</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/07/dist-system-practice</guid><pubDate>Sat, 13 Jul 2019 07:36:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#11-%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90%E6%B8%85%E5%8D%95&quot;&gt;1.1 相关资源清单&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#111-%E5%AE%9E%E8%B7%B5%E4%BB%A3%E7%A0%81-practice_code&quot;&gt;1.1.1 实践代码 {#PRACTICE_CODE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#112-%E7%BB%84%E4%BB%B6%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81&quot;&gt;1.1.2 组件实验代码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#113-go%E8%AF%AD%E8%A8%80%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81&quot;&gt;1.1.3 go语言实验代码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#114-%E7%BB%84%E4%BB%B6%E4%B8%93%E9%A2%98&quot;&gt;1.1.4 组件专题&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E7%BB%84%E4%BB%B6%E6%B8%85%E5%8D%95-component_list&quot;&gt;2. 组件清单 {#COMPONENT_LIST}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E6%9E%B6%E6%9E%84&quot;&gt;3. 架构&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E7%BB%84%E4%BB%B6%E5%88%97%E8%A1%A8&quot;&gt;3.1 组件列表&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#311-%E9%83%A8%E5%88%86%E6%9C%AA%E5%AE%9E%E8%B7%B5%E7%BB%84%E4%BB%B6&quot;&gt;3.1.1 部分未实践组件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B&quot;&gt;3.2 数据模型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E4%B8%9A%E5%8A%A1%E6%B5%81%E7%A8%8B&quot;&gt;3.3 业务流程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84&quot;&gt;3.4 系统架构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-%E9%83%A8%E7%BD%B2%E6%8B%93%E6%89%91&quot;&gt;3.5 部署拓扑&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E6%B5%8B%E8%AF%95&quot;&gt;4. 测试&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E6%B5%8B%E8%AF%95%E7%9B%AE%E6%A0%87-test_target&quot;&gt;4.1 测试目标 {#TEST_TARGET}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E6%B5%8B%E8%AF%95%E7%A1%AC%E4%BB%B6&quot;&gt;4.2 测试硬件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E6%B5%8B%E8%AF%95%E8%A7%84%E5%88%92&quot;&gt;4.3 测试规划&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E7%9B%91%E6%8E%A7%E6%B8%85%E5%8D%95&quot;&gt;4.4 监控清单&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#45-%E9%83%A8%E7%BD%B2%E5%B7%A5%E7%A8%8B&quot;&gt;4.5 部署工程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#46-%E6%B5%8B%E8%AF%95%E6%89%A7%E8%A1%8C--%E6%8A%A5%E5%91%8A%E5%88%B6%E4%BD%9C&quot;&gt;4.6 测试执行 &amp;#x26; 报告制作&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#461-%E8%8E%B7%E5%8F%96elasticsearchkibana%E6%95%B0%E6%8D%AE&quot;&gt;4.6.1 获取Elasticsearch（Kibana）数据&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#462-%E8%8E%B7%E5%8F%96jaeger%E6%95%B0%E6%8D%AE&quot;&gt;4.6.2 获取Jaeger数据&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E6%8A%A5%E5%91%8A&quot;&gt;5. 报告&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-%E7%AC%AC%E4%B8%80%E6%AC%A1%E6%B5%8B%E8%AF%95&quot;&gt;5.1 第一次测试&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E7%AC%AC%E4%BA%8C%E6%AC%A1%E6%B5%8B%E8%AF%95&quot;&gt;5.2 第二次测试&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#appendix&quot;&gt;Appendix&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%9B%91%E6%8E%A7%E6%B8%85%E5%8D%95-monitoring_list&quot;&gt;监控清单 {#MONITORING_LIST}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#host&quot;&gt;Host&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#container&quot;&gt;Container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#memcached&quot;&gt;Memcached&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#mysql&quot;&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prometheus&quot;&gt;Prometheus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#kafka-jmx&quot;&gt;Kafka JMX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#kafka-exporter&quot;&gt;Kafka Exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-agent&quot;&gt;Jaeger Agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-collector&quot;&gt;Jaeger Collector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#filebeat&quot;&gt;Filebeat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#elasticsearch&quot;&gt;Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#golang&quot;&gt;Golang&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;分布式系统因其使用的组件较多，复杂度较高，较难掌握。常说，写出一个能跑的东西很简单，但要全面掌握一门技术，并能够在任何情况下解决其发生的问题，则要难得多得多。分布式系统的难，更多的在于使用的组件多，每一个组件如果都需要掌握其从设计到运行的一系列技术细节就非常困难。此外，分布式系统的监控和分析也很难，也是因其组件多造成的，一个请求流转于多个组件之间，就很难定位当问题发生的时候其源头何在。&lt;/p&gt;
&lt;p&gt;在长期的工作中，一直都没有实地进行实践的机会（公司体量、投入、团队管理等各种因素），因此就萌生了自己做一个实践项目，然后在云服务器上部署进行测试实验的念头。在此付诸实行。&lt;/p&gt;
&lt;h2 id=&quot;11-相关资源清单&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#11-%E7%9B%B8%E5%85%B3%E8%B5%84%E6%BA%90%E6%B8%85%E5%8D%95&quot; aria-label=&quot;11 相关资源清单 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.1 相关资源清单&lt;/h2&gt;
&lt;p&gt;下面将大量资料进行清单整理，方便后续取用。&lt;/p&gt;
&lt;h3 id=&quot;111-实践代码-practice_code&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#111-%E5%AE%9E%E8%B7%B5%E4%BB%A3%E7%A0%81-practice_code&quot; aria-label=&quot;111 实践代码 practice_code permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.1.1 实践代码 {#PRACTICE_CODE}&lt;/h3&gt;
&lt;p&gt;该项目的实际实践代码在：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/dist-system-practice&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/dist-system-practice/&lt;/a&gt;。该处的README主要提供了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;应用程序（Web、Service、Consumer）的环境变量清单&lt;/li&gt;
&lt;li&gt;开发环境的组件清单及端口描述&lt;/li&gt;
&lt;li&gt;开发环境的部署及启动命令&lt;/li&gt;
&lt;li&gt;代码文件结构描述&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;线上环境的部署、启动、测试、导出数据等功能的相关实现在脚本：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/bash/prod/cluster/src/index.ts&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;cluster/src/index.ts&lt;/a&gt;。其功能及使用描述在：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/bash/prod/cluster/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;README.md&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;线上服务器拓扑及服务网格相关的配置在：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/bash/prod/cluster/src/index.ts#L22&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;index.ts#L22&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Grafana数据导出相关配置在：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/bash/prod/cluster/src/index.ts#L151&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;index.ts#L151&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;112-组件实验代码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#112-%E7%BB%84%E4%BB%B6%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81&quot; aria-label=&quot;112 组件实验代码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.1.2 组件实验代码&lt;/h3&gt;
&lt;p&gt;部分组件的简单实验代码在：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/experiment&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/experiment/&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;113-go语言实验代码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#113-go%E8%AF%AD%E8%A8%80%E5%AE%9E%E9%AA%8C%E4%BB%A3%E7%A0%81&quot; aria-label=&quot;113 go语言实验代码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.1.3 go语言实验代码&lt;/h3&gt;
&lt;p&gt;go语言的简单实验代码在：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/experiment&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/experiment/&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;114-组件专题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#114-%E7%BB%84%E4%BB%B6%E4%B8%93%E9%A2%98&quot; aria-label=&quot;114 组件专题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.1.4 组件专题&lt;/h3&gt;
&lt;p&gt;对于项目中使用到的一系列组件，我这里都做过比较深入的使用测试及调研，并制作了一系列的专题博文。可以参见列表：&lt;a href=&quot;#COMPONENT_LIST&quot;&gt;2. 组件清单&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;2-组件清单-component_list&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E7%BB%84%E4%BB%B6%E6%B8%85%E5%8D%95-component_list&quot; aria-label=&quot;2 组件清单 component_list permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 组件清单 {#COMPONENT_LIST}&lt;/h1&gt;
&lt;p&gt;实践项目中（计划）使用到了如下组件：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;组件&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;角色&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;专题&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Golang&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;应用程序&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/02/golang-note/&quot;&gt;Golang Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;MySQL&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;数据库&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Draft&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Memcached&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;缓存&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/05/memcached-note/&quot;&gt;Memcached Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Docker&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;底层容器&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/01/docker-note/&quot;&gt;Docker Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Envoy&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;代理入口&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/05/envoy-note/&quot;&gt;Envoy Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;gRPC&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;组件通讯&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/05/grpc-note/&quot;&gt;gRPC Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Kafka&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;消息队列&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/04/kafka-note/&quot;&gt;Kafka Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Prometheus&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;监控系统&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/04/prometheus-note/&quot;&gt;Prometheus Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Grafana&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;监控UI&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/04/grafana-note/&quot;&gt;Grafana Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Jaeger&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;链路追踪&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/04/jaeger-note/&quot;&gt;Jaeger Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Cassandra&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;数据库&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Draft&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Elasticsearch&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;聚合分析&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;/2019/04/elasticsearch-note/&quot;&gt;Elasticsearch Notes&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Kubernetes&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;容器管理&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;TODO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Istio&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;服务编排&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;TODO&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;Linux&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;操作系统&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Draft&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;201902之前，Golang、Docker、Kafka、Elasticsearch、Grafana、Prometheus、Jaeger于我的相关积累基本为0，基本上完全没直接接触过（实践），而到了6月底，我已经可以很熟练启动、使用这些组件，更重要的是完全理解它们的设计、架构，以及性能和部分调优手段。&lt;/p&gt;
&lt;p&gt;对于”程序”的理解，以及超快的学习速度和学习能力，才是程序员能够在软件行业一直活下去的关键，我一直如此深信。&lt;/p&gt;
&lt;h1 id=&quot;3-架构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E6%9E%B6%E6%9E%84&quot; aria-label=&quot;3 架构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 架构&lt;/h1&gt;
&lt;p&gt;因为是一个实验性项目，应用程序的逻辑和架构做的非常简单。&lt;/p&gt;
&lt;h2 id=&quot;31-组件列表&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E7%BB%84%E4%BB%B6%E5%88%97%E8%A1%A8&quot; aria-label=&quot;31 组件列表 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 组件列表&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Web：go语言编写的web服务器，整个集群的入口&lt;/li&gt;
&lt;li&gt;Service：go语言编写的gRPC服务器，web收到请求后不进行任何业务实际处理，直接通过gRPC发到Service，由Service处理完成后返回&lt;/li&gt;
&lt;li&gt;Consumer：go语言编写的Kafka消费者，处理部分Service安排到Kafka的异步任务&lt;/li&gt;
&lt;li&gt;Kafka：负责将部分Service的运算进行消息入队，并分发给Consumer处理（异步、解耦）&lt;/li&gt;
&lt;li&gt;MySQL：应用程序的存储服务&lt;/li&gt;
&lt;li&gt;Memcached：应用程序的缓存服务&lt;/li&gt;
&lt;li&gt;Filebeat：负责将Web、Service、Consumer产生的有用日志（过滤）上传到Elasticsearch集群&lt;/li&gt;
&lt;li&gt;Elasticsearch、Kibana：负责将Web、Service、Consumer产生的业务日志索引入库，以便后续查询&lt;/li&gt;
&lt;li&gt;Cassandra：Jaeger Tracing的存储服务&lt;/li&gt;
&lt;li&gt;Jaeger（Agent、Collector、Query）：负责接收Web、Service、Consumer发出的Span、Trace数据，入库以便后续查询&lt;/li&gt;
&lt;li&gt;*Exporter：负责将各组件的状态以HTTP的方式输出出来&lt;/li&gt;
&lt;li&gt;Prometheus：将 *Exporter 输出的数据采集，并录入到时序数据库中，以便后续查询&lt;/li&gt;
&lt;li&gt;Grafana：负责将各组件的观察需求固定化，对Prometheus时序数据库进行查询，绘制图表&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;311-部分未实践组件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#311-%E9%83%A8%E5%88%86%E6%9C%AA%E5%AE%9E%E8%B7%B5%E7%BB%84%E4%BB%B6&quot; aria-label=&quot;311 部分未实践组件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1.1 部分未实践组件&lt;/h2&gt;
&lt;p&gt;部分列在&lt;a href=&quot;#COMPONENT_LIST&quot;&gt;2. 组件清单&lt;/a&gt;中的组件实际上并未实际使用。因时间和精力的原因，只能割舍掉了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Envoy：整体业务过于简单，不存在在Web服务器之前架设Envoy的必要性；而内部架构也过于简单，不存在架设Envoy作为内部流量控制入口的必要性&lt;/li&gt;
&lt;li&gt;Kubernetes：实践复杂度过高，因精力原因放弃&lt;/li&gt;
&lt;li&gt;Istio：实践复杂度过高，因精力原因放弃&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;32-数据模型&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B&quot; aria-label=&quot;32 数据模型 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 数据模型&lt;/h2&gt;
&lt;p&gt;整个业务流程中只涉及到一个数据模型：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Work &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	Id            &lt;span class=&quot;token builtin&quot;&gt;uint32&lt;/span&gt;
	Viewed        &lt;span class=&quot;token builtin&quot;&gt;uint32&lt;/span&gt;
	AchievedCount &lt;span class=&quot;token builtin&quot;&gt;uint32&lt;/span&gt;
	Achievement   &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;
	IsPlanned     &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;
	PlannedAt     time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Time
	AchievedAt    time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Time
	Created       time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Time
	Updated       time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Time
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Id：自增长主键，每一条Work数据唯一&lt;/li&gt;
&lt;li&gt;Viewed：是一个累加的int型，每次&lt;code class=&quot;language-text&quot;&gt;/viewed&lt;/code&gt;API访问，该值+1&lt;/li&gt;
&lt;li&gt;AchievedCount：是一个累加的int型，每次完成&lt;code class=&quot;language-text&quot;&gt;/plan&lt;/code&gt;API的任务推送及Consumer的achievement更新之后，该值+1&lt;/li&gt;
&lt;li&gt;Achievement：该值由Service的&lt;code class=&quot;language-text&quot;&gt;/plan&lt;/code&gt;API推送任务到Kafka，然后由Consumer获取任务之后进行运算并更新&lt;/li&gt;
&lt;li&gt;IsPlanned：状态标识，当&lt;code class=&quot;language-text&quot;&gt;/plan&lt;/code&gt;API完成之后标记为true，当Consumer运算并更新完成后标记为false&lt;/li&gt;
&lt;li&gt;PlannedAt：时间&lt;/li&gt;
&lt;li&gt;AchievedAt：时间&lt;/li&gt;
&lt;li&gt;Created：时间&lt;/li&gt;
&lt;li&gt;Updated：时间&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;33-业务流程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E4%B8%9A%E5%8A%A1%E6%B5%81%E7%A8%8B&quot; aria-label=&quot;33 业务流程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 业务流程&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Web服务器&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;应用程序的入口为go语言编写的web服务器（Web），提供5个API（所有的API都不要求提供WorkId，会在API内部自行随机一个WorkId进行处理，方便后续自动化测试）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/work&lt;/code&gt;：获取Work数据，并返回&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/viewed&lt;/code&gt;：获取Work数据，并返回Viewed值&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/achievement&lt;/code&gt;：获取Work数据，并返回Achievement值&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/plan&lt;/code&gt;：获取Work数据，并将任务安排到Kafka队列，更新IsPlanned以及PlannedAt字段的值&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;/api&lt;/code&gt;：根据设置好的概率（可配置）抽取上述4个接口中的一个进行执行，实际上的性能测试入口&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Consumer消费者&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Kafka的消费者为go语言编写的服务器，对消息进行处理：从Kafka中获取任务，根据Id获取Work数据，根据计算因子计算出Achievement字符串值，更新IsPlanned、AchievedAt、Achievement字段的值。&lt;/p&gt;
&lt;h2 id=&quot;34-系统架构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-%E7%B3%BB%E7%BB%9F%E6%9E%B6%E6%9E%84&quot; aria-label=&quot;34 系统架构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 系统架构&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/07/dist-system-practice/logic_flow.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;*Exporter&lt;/code&gt;这部分比较简略，因为基本上每个组件都有自己的Exporter，要详实还原实际的架构这图就没法看了。因此就只简单列出了go app相关的几条线。&lt;/p&gt;
&lt;h2 id=&quot;35-部署拓扑&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#35-%E9%83%A8%E7%BD%B2%E6%8B%93%E6%89%91&quot; aria-label=&quot;35 部署拓扑 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.5 部署拓扑&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/07/dist-system-practice/topology.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;因预算关系，Elasticsearch和Kafka集群的分布并不是特别理想，不过也只能这样了。此外，图中还少了一个&lt;code class=&quot;language-text&quot;&gt;Client&lt;/code&gt;节点，专门用来运行Vegeta压测客户端的，因比较简单这里就没有绘制上去。&lt;/p&gt;
&lt;h1 id=&quot;4-测试&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E6%B5%8B%E8%AF%95&quot; aria-label=&quot;4 测试 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 测试&lt;/h1&gt;
&lt;h2 id=&quot;41-测试目标-test_target&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E6%B5%8B%E8%AF%95%E7%9B%AE%E6%A0%87-test_target&quot; aria-label=&quot;41 测试目标 test_target permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 测试目标 {#TEST_TARGET}&lt;/h2&gt;
&lt;p&gt;制定测试目标一般需要以下步骤：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;固定拓扑架构：尽量按线上真实情景的拓扑架构进行测试，如果规模过大的话，可以按比缩小（虽然会失真）&lt;/li&gt;
&lt;li&gt;设定业务指标：同时在线100万、PV10亿等&lt;/li&gt;
&lt;li&gt;将业务指标转化为可测试的程序指标：QPS、DB Transaction/s&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样就可以针对可测试的程序指标进行测试了。&lt;/p&gt;
&lt;p&gt;而更进一步的测试目标可以细分为两类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;测试指标达标：当前系统可以负载起目标需求，在此基础上还可以找出系统的最高负载瓶颈点，并提出优化方案&lt;/li&gt;
&lt;li&gt;测试指标未达标：当前系统未可以负载起目标需求，需要找出系统的瓶颈，并提出优化方案；后续需要多轮测试以验证优化的执行情况&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就当前的项目来说，因为是纯粹的模拟测试项目，所以不存在真实的业务需求和业务指标，因此无法设定具体的程序指标，也就无从谈起是否达标的问题。只能说通过测试慢慢摸索当前架构的性能峰值，以及瓶颈点：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在固定硬件规格、程序拓扑架构之后，逐步提升客户端的QPS，查看系统负载的上升情况，找出系统最高负载值，并找出系统整体的瓶颈点&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;42-测试硬件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-%E6%B5%8B%E8%AF%95%E7%A1%AC%E4%BB%B6&quot; aria-label=&quot;42 测试硬件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 测试硬件&lt;/h2&gt;
&lt;p&gt;这次的测试选用的是Linode的云服务器，在选择的时候首先考虑的当然是国内的服务商，但发现像我这样只需要短期使用资源的客户（几个小时到1天左右）国内的服务商的付费方式太糟糕了。一般来说国内的服务商都是按月付费，所谓的按时收费其单价换算下来要比按月付费高得多得多，因此实际上是不可用的。&lt;/p&gt;
&lt;p&gt;海外服务商一开始考虑使用Vultr，毕竟性价比是最高的，但后来发现Vultr对客户有非常严格的限制，如果需要租用大量机器或高性能机器的话，需要发Ticket进行人工审核。不出意外，我这样短期租用的客户被拒了。最后只能选用Linode，Linode在这方面倒是没有额外的限制，随开随用。&lt;/p&gt;
&lt;p&gt;实际使用的是Linode的16G机型：6 CPU、16G RAM、320G Storage。简单Benchmark结果如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;wget&lt;/span&gt; -qO- bench.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;

----------------------------------------------------------------------
CPU model            &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; AMD EPYC &lt;span class=&quot;token number&quot;&gt;7601&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;-Core Processor
Number of cores      &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;
CPU frequency        &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2199.996&lt;/span&gt; MHz
Total size of Disk   &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;315.0&lt;/span&gt; GB &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2.2&lt;/span&gt; GB Used&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
Total amount of Mem  &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16040&lt;/span&gt; MB &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt; MB Used&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
Total amount of Swap &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;511&lt;/span&gt; MB &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; MB Used&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
System &lt;span class=&quot;token function&quot;&gt;uptime&lt;/span&gt;        &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; days, &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; hour &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; min
Load average         &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.29&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;0.22&lt;/span&gt;, &lt;span class=&quot;token number&quot;&gt;0.09&lt;/span&gt;
OS                   &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; Ubuntu &lt;span class=&quot;token number&quot;&gt;18.04&lt;/span&gt;.2 LTS
Arch                 &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; x86_64 &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt; Bit&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
Kernel               &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4.15&lt;/span&gt;.0-50-generic
----------------------------------------------------------------------
I/O speed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1st run&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;892&lt;/span&gt; MB/s
I/O speed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;2nd run&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.1&lt;/span&gt; GB/s
I/O speed&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;3rd run&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt; GB/s
Average I/O speed    &lt;span class=&quot;token builtin class-name&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1014.1&lt;/span&gt; MB/s
----------------------------------------------------------------------
Node Name                       IPv4 address            Download Speed
CacheFly                        &lt;span class=&quot;token number&quot;&gt;205.234&lt;/span&gt;.175.175         144MB/s
Linode, Tokyo, JP               &lt;span class=&quot;token number&quot;&gt;106.187&lt;/span&gt;.96.148          &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;.7MB/s
Linode, Singapore, SG           &lt;span class=&quot;token number&quot;&gt;139.162&lt;/span&gt;.23.4            &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;.48MB/s
Linode, London, UK              &lt;span class=&quot;token number&quot;&gt;176.58&lt;/span&gt;.107.39           &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;.71MB/s
Linode, Frankfurt, DE           &lt;span class=&quot;token number&quot;&gt;139.162&lt;/span&gt;.130.8           &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;.4MB/s
Linode, Fremont, CA             &lt;span class=&quot;token number&quot;&gt;50.116&lt;/span&gt;.14.9             205MB/s
Softlayer, Dallas, TX           &lt;span class=&quot;token number&quot;&gt;173.192&lt;/span&gt;.68.18           &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt;.9MB/s
Softlayer, Seattle, WA          &lt;span class=&quot;token number&quot;&gt;67.228&lt;/span&gt;.112.250          &lt;span class=&quot;token number&quot;&gt;44&lt;/span&gt;.8MB/s
Softlayer, Frankfurt, DE        &lt;span class=&quot;token number&quot;&gt;159.122&lt;/span&gt;.69.4            &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.92MB/s
Softlayer, Singapore, SG        &lt;span class=&quot;token number&quot;&gt;119.81&lt;/span&gt;.28.170           &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;.21MB/s
Softlayer, HongKong, CN         &lt;span class=&quot;token number&quot;&gt;119.81&lt;/span&gt;.130.170          &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;.4MB/s
----------------------------------------------------------------------
Node Name                       IPv6 address            Download Speed
Linode, Atlanta, GA             &lt;span class=&quot;token number&quot;&gt;2600&lt;/span&gt;:3c02::4b           &lt;span class=&quot;token number&quot;&gt;39&lt;/span&gt;.3MB/s
Linode, Dallas, TX              &lt;span class=&quot;token number&quot;&gt;2600&lt;/span&gt;:3c00::4b           &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt;.9MB/s
Linode, Newark, NJ              &lt;span class=&quot;token number&quot;&gt;2600&lt;/span&gt;:3c03::4b           &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;.3MB/s
Linode, Singapore, SG           &lt;span class=&quot;token number&quot;&gt;2400&lt;/span&gt;:8901::4b           &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;.36MB/s
Linode, Tokyo, JP               &lt;span class=&quot;token number&quot;&gt;2400&lt;/span&gt;:8900::4b           &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;.5MB/s
Softlayer, San Jose, CA         &lt;span class=&quot;token number&quot;&gt;2607&lt;/span&gt;:f0d0:2601:2a::4    &lt;span class=&quot;token number&quot;&gt;95&lt;/span&gt;.4MB/s
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
----------------------------------------------------------------------&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;curl &lt;span class=&quot;token parameter variable&quot;&gt;-s&lt;/span&gt; wget.racing/nench.sh &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;2&lt;/span&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token file-descriptor important&quot;&gt;&amp;amp;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tee&lt;/span&gt; nench.log

-------------------------------------------------
nench.sh v2019.06.29 -- https://git.io/nench.sh
benchmark timestamp:    &lt;span class=&quot;token number&quot;&gt;2019&lt;/span&gt;-07-12 05:48:17 UTC
-------------------------------------------------

Processor:    AMD EPYC &lt;span class=&quot;token number&quot;&gt;7601&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;-Core Processor
CPU cores:    &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;
Frequency:    &lt;span class=&quot;token number&quot;&gt;2199.996&lt;/span&gt; MHz
RAM:          15G
Swap:         511M
Kernel:       Linux &lt;span class=&quot;token number&quot;&gt;4.15&lt;/span&gt;.0-50-generic x86_64

Disks:
sda  &lt;span class=&quot;token number&quot;&gt;319&lt;/span&gt;.5G  HDD
sdb    512M  HDD

CPU: SHA256-hashing &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt; MB
&lt;span class=&quot;token number&quot;&gt;2.962&lt;/span&gt; seconds
CPU: bzip2-compressing &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt; MB
&lt;span class=&quot;token number&quot;&gt;6.310&lt;/span&gt; seconds
CPU: AES-encrypting &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt; MB
&lt;span class=&quot;token number&quot;&gt;1.362&lt;/span&gt; seconds

ioping: seek rate
min/avg/max/mdev &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;62.2&lt;/span&gt; us / &lt;span class=&quot;token number&quot;&gt;112.5&lt;/span&gt; us / &lt;span class=&quot;token number&quot;&gt;2.94&lt;/span&gt; ms / &lt;span class=&quot;token number&quot;&gt;75.5&lt;/span&gt; us
ioping: sequential &lt;span class=&quot;token builtin class-name&quot;&gt;read&lt;/span&gt; speed
generated &lt;span class=&quot;token number&quot;&gt;16.5&lt;/span&gt; k requests &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5.00&lt;/span&gt; s, &lt;span class=&quot;token number&quot;&gt;4.03&lt;/span&gt; GiB, &lt;span class=&quot;token number&quot;&gt;3.30&lt;/span&gt; k iops, &lt;span class=&quot;token number&quot;&gt;824.3&lt;/span&gt; MiB/s

dd: sequential &lt;span class=&quot;token function&quot;&gt;write&lt;/span&gt; speed
1st run:    &lt;span class=&quot;token number&quot;&gt;855.45&lt;/span&gt; MiB/s
2nd run:    &lt;span class=&quot;token number&quot;&gt;1049.04&lt;/span&gt; MiB/s
3rd run:    &lt;span class=&quot;token number&quot;&gt;1049.04&lt;/span&gt; MiB/s
average:    &lt;span class=&quot;token number&quot;&gt;984.51&lt;/span&gt; MiB/s

IPv4 speedtests
your IPv4:    &lt;span class=&quot;token number&quot;&gt;173.255&lt;/span&gt;.252.xxxx

Cachefly CDN:         &lt;span class=&quot;token number&quot;&gt;175.13&lt;/span&gt; MiB/s
Leaseweb &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;NL&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:        &lt;span class=&quot;token number&quot;&gt;13.85&lt;/span&gt; MiB/s
Softlayer DAL &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;US&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;38.74&lt;/span&gt; MiB/s
Online.net &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FR&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:      &lt;span class=&quot;token number&quot;&gt;11.06&lt;/span&gt; MiB/s
OVH BHS &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;CA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:         &lt;span class=&quot;token number&quot;&gt;16.75&lt;/span&gt; MiB/s

IPv6 speedtests
your IPv6:    &lt;span class=&quot;token number&quot;&gt;2600&lt;/span&gt;:3c01::xxxx

Leaseweb &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;NL&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:        &lt;span class=&quot;token number&quot;&gt;7.77&lt;/span&gt; MiB/s
Softlayer DAL &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;US&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:   &lt;span class=&quot;token number&quot;&gt;0.00&lt;/span&gt; MiB/s
Online.net &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FR&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:      &lt;span class=&quot;token number&quot;&gt;8.44&lt;/span&gt; MiB/s
OVH BHS &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;CA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;:         &lt;span class=&quot;token number&quot;&gt;17.60&lt;/span&gt; MiB/s
-------------------------------------------------&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;我是很想把CPU上到至少8个核，但囿于预算，还是降了一档。&lt;/p&gt;
&lt;h2 id=&quot;43-测试规划&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E6%B5%8B%E8%AF%95%E8%A7%84%E5%88%92&quot; aria-label=&quot;43 测试规划 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 测试规划&lt;/h2&gt;
&lt;p&gt;上面在&lt;a href=&quot;#TEST_TARGET&quot;&gt;4.1 测试目标&lt;/a&gt;的时候提到了设定目标需要固定程序拓扑架构，但即便在程序架构固定的情况下，仍旧有大量细节（参数、配置）是可以微调变动的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;客户端连接数量：最大连接数，越大的最大连接数意味着越高的并发请求可能，而提升并发意味着负载的显著上升&lt;/li&gt;
&lt;li&gt;客户端请求速率：同时到达服务器的请求数量，即并发请求数量，并发数量的上升最终体现在这个指标的提升上&lt;/li&gt;
&lt;li&gt;数据库表量级：不同数据量的数据库表，其性能也会显著不同，因此在测试的时候也可以变动下表数据量再进行测试&lt;/li&gt;
&lt;li&gt;数据库连接：少量的连接不足以处理请求，但过大的连接数也会显著降低性能，这方面也是一个测试点&lt;/li&gt;
&lt;li&gt;gRPC连接池容量：虽然gRPC的Go客户端对于并发的处理非常好，但连接池仍旧在某些情况下有其作用，如何找出合理的并发池容量也是可选的测试条目之一&lt;/li&gt;
&lt;li&gt;Kafka目标Topic的分片数量：提升分片数量会降低写入的性能，但更多的分片意味着更多的消费者，消息的处理速度会上升&lt;/li&gt;
&lt;li&gt;Elasticsearch集群的Node数量：提升节点会降低写入性能，但会提升查询性能&lt;/li&gt;
&lt;li&gt;JVM设置：各个用到JVM的软件一般都需要很精细地对JVM进行配置和调优，才能很好地发挥性能，而这方面的配置变化对测试的影响也很大&lt;/li&gt;
&lt;li&gt;消费者计算因子：随着因子数值的调大，计算量会显著上升，最终会体现在Consumer角色的负载上升，以及Kafka队列的堆积不能及时消费等&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试的规划制定需要固定大部分的变量、配置，仅修改少部分，然后进行多次测试，横向比较性能的变化，就可以找出当前架构的最佳性能表现设置。&lt;/p&gt;
&lt;h2 id=&quot;44-监控清单&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E7%9B%91%E6%8E%A7%E6%B8%85%E5%8D%95&quot; aria-label=&quot;44 监控清单 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 监控清单&lt;/h2&gt;
&lt;p&gt;下面是一份当前程序架构中需要进行重点监控的程序指标清单。这部分太长了，我放到最后的&lt;a href=&quot;#MONITORING_LIST&quot;&gt;Appendix &gt; 监控清单&lt;/a&gt;里，以便不影响下文的阅读。&lt;/p&gt;
&lt;h2 id=&quot;45-部署工程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#45-%E9%83%A8%E7%BD%B2%E5%B7%A5%E7%A8%8B&quot; aria-label=&quot;45 部署工程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5 部署工程&lt;/h2&gt;
&lt;p&gt;部署工作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Linode服务商这里申请开服务器&lt;/li&gt;
&lt;li&gt;因Linode不支持在开服务器的时候直接部署SSH Key，需要使用命令来部署：ssh-copy-id -i ~/.ssh/id_rsa.pub &lt;a href=&quot;mailto:root@xxx.xxx.xxx.xxx&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;root@xxx.xxx.xxx.xxx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;使用&lt;a href=&quot;#PRACTICE_CODE&quot;&gt;1.1.1 实践代码&lt;/a&gt;提到的线上部署脚本进行部署：
&lt;ul&gt;
&lt;li&gt;./cluster.sh —machine&lt;/li&gt;
&lt;li&gt;./cluster.sh —image&lt;/li&gt;
&lt;li&gt;./cluster.sh —deploy —machine-type=all&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;使用 ./cluster.sh —docker-ps —machine-type=all 来观察是否启动正常&lt;/li&gt;
&lt;li&gt;打开 MONITER_IP:9090 来查看是否所有的监控节点都正常在线&lt;/li&gt;
&lt;li&gt;打开 MONITER_IP:5601 来设置ES内的Index Pattern&lt;/li&gt;
&lt;li&gt;使用 curl -v http://WEB_IP:8000/work 等入口测试是否正常运行&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;46-测试执行--报告制作&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#46-%E6%B5%8B%E8%AF%95%E6%89%A7%E8%A1%8C--%E6%8A%A5%E5%91%8A%E5%88%B6%E4%BD%9C&quot; aria-label=&quot;46 测试执行  报告制作 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.6 测试执行 &amp;#x26; 报告制作&lt;/h2&gt;
&lt;p&gt;部署完成之后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;记录测试开始时间&lt;/li&gt;
&lt;li&gt;修改cluster.sh内相关配置&lt;/li&gt;
&lt;li&gt;运行 ./cluster.sh —stress —machine-type=all 获得测试命令&lt;/li&gt;
&lt;li&gt;在Client Host上执行测试命令开始测试，并观察实时报表中的报错数及响应时长变化（如有大量错误和大量超时，需要中断测试，并查找原因）&lt;/li&gt;
&lt;li&gt;打开 MONITER_IP:9090 观察监控节点是否正常在线&lt;/li&gt;
&lt;li&gt;打开 MONITER_IP:3000 观察监控指标变化&lt;/li&gt;
&lt;li&gt;在测试完成前，使用pprof获取30秒间隔的两份堆内存dump（Web、Service、Consumer都需要）：
&lt;ul&gt;
&lt;li&gt;go tool pprof &lt;a href=&quot;http://HOST:PORT/debug/pprof/heap&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://HOST:PORT/debug/pprof/heap&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Saved profile in /Users/XXX/pprof/pprof.web.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;go tool pprof -png /Users/XXX/pprof/pprof.web.alloc_objects.alloc_space.inuse_objects.inuse_space.001.pb.gz &gt; web_heap.png&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;在测试完成之前，使用pprof获取30秒的CPU dump（Web、Service、Consumer都需要）：
&lt;ul&gt;
&lt;li&gt;go tool pprof &lt;a href=&quot;http://HOST:PORT/debug/pprof/profile?seconds=30&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://HOST:PORT/debug/pprof/profile?seconds=30&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Saved profile in /Users/XXX/pprof/pprof.web.samples.cpu.001.pb.gz&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;go tool pprof -png /Users/XXX/pprof/pprof.web.samples.cpu.001.pb.gz &gt; web_cpu.png&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试完成后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;记录测试结束时间&lt;/li&gt;
&lt;li&gt;修改cluster.sh内相关配置&lt;/li&gt;
&lt;li&gt;使用 ./cluster.sh —report 导出测试结果数据&lt;/li&gt;
&lt;li&gt;手动获取Elasticsearch数据，并填入到报表模板中
&lt;ul&gt;
&lt;li&gt;获取时间段内所有Web请求数量，与客户端报表中数值进行比对是否匹配&lt;/li&gt;
&lt;li&gt;获取时间段内所有的Consumer请求数量，与Web请求中的 /plan 数量进行比对是否匹配&lt;/li&gt;
&lt;li&gt;获取时间段内所有Web请求API类型的配比，与配置项中的数值进行比对是否匹配&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;手动获取Jaeger数据，并填入到报表模板中
&lt;ul&gt;
&lt;li&gt;时间段内各Web API的耗时图表&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;将压测执行客户端的报表数据填入到报表模板中&lt;/li&gt;
&lt;li&gt;将之前导出的CPU和堆内存Profiling数据以图片形式导出，并填入到报表模板中&lt;/li&gt;
&lt;li&gt;修改导出的报表模板，添加测试实际配置数据，并编写结论板块内容&lt;/li&gt;
&lt;li&gt;将完工的所有内容提交到代码库中：
&lt;ul&gt;
&lt;li&gt;cluster/report/XXXXX/images&lt;/li&gt;
&lt;li&gt;cluster/report/XXXXX/report_XXXXX.md&lt;/li&gt;
&lt;li&gt;cluster/report/XXXXX/pprof/* 导出的CPU和堆内存dump&lt;/li&gt;
&lt;li&gt;cluster/output/*&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;461-获取elasticsearchkibana数据&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#461-%E8%8E%B7%E5%8F%96elasticsearchkibana%E6%95%B0%E6%8D%AE&quot; aria-label=&quot;461 获取elasticsearchkibana数据 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.6.1 获取Elasticsearch（Kibana）数据&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;获取所有Web请求数：
&lt;ul&gt;
&lt;li&gt;打开Discover &gt; dist-web-web-7.0.0-*&lt;/li&gt;
&lt;li&gt;调整时间成绝对时间&lt;/li&gt;
&lt;li&gt;查看左上角的Hit数：1,552 hits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取所有Consumer请求数：
&lt;ul&gt;
&lt;li&gt;打开Discover &gt; dist-consumer-consumer-7.0.0-*&lt;/li&gt;
&lt;li&gt;调整时间成绝对时间&lt;/li&gt;
&lt;li&gt;查看左上角的Hit数：81 hits&lt;/li&gt;
&lt;li&gt;比率验证：81 / 1552 = 5.21%；OK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取API GetWork请求数：
&lt;ul&gt;
&lt;li&gt;打开Discover &gt; dist-web-web-7.0.0-*&lt;/li&gt;
&lt;li&gt;调整时间成绝对时间&lt;/li&gt;
&lt;li&gt;在Filter中输入：&lt;code class=&quot;language-text&quot;&gt;api: apiGetWork&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看左上角的Hit数：704 hits&lt;/li&gt;
&lt;li&gt;比率验证：704 / 1552 = 45.36%；OK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取API UpdateViewed请求数：
&lt;ul&gt;
&lt;li&gt;打开Discover &gt; dist-web-web-7.0.0-*&lt;/li&gt;
&lt;li&gt;调整时间成绝对时间&lt;/li&gt;
&lt;li&gt;在Filter中输入：&lt;code class=&quot;language-text&quot;&gt;api: apiUpdateViewed&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看左上角的Hit数：364 hits&lt;/li&gt;
&lt;li&gt;比率验证：364 / 1552 = 23.45%；OK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取API GetAchievement请求数：
&lt;ul&gt;
&lt;li&gt;打开Discover &gt; dist-web-web-7.0.0-*&lt;/li&gt;
&lt;li&gt;调整时间成绝对时间&lt;/li&gt;
&lt;li&gt;在Filter中输入：&lt;code class=&quot;language-text&quot;&gt;api: apiGetAchievement&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看左上角的Hit数：403 hits&lt;/li&gt;
&lt;li&gt;比率验证：403 / 1552 = 25.96%；OK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;获取API PlanWork请求数：
&lt;ul&gt;
&lt;li&gt;打开Discover &gt; dist-web-web-7.0.0-*&lt;/li&gt;
&lt;li&gt;调整时间成绝对时间&lt;/li&gt;
&lt;li&gt;在Filter中输入：&lt;code class=&quot;language-text&quot;&gt;api: apiPlanWork&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;查看左上角的Hit数：81 hits&lt;/li&gt;
&lt;li&gt;数量验证：与Consumer计数匹配；OK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;P.S 使用&lt;code class=&quot;language-text&quot;&gt;level: error&lt;/code&gt;过滤条件查找错误日志，如果是没有上传日志的service服务等，则需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;docker-machine ssh service&lt;/li&gt;
&lt;li&gt;docker logs —tail 1000 app_service | grep ERROR&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;462-获取jaeger数据&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#462-%E8%8E%B7%E5%8F%96jaeger%E6%95%B0%E6%8D%AE&quot; aria-label=&quot;462 获取jaeger数据 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.6.2 获取Jaeger数据&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;打开Jaeger Query&lt;/li&gt;
&lt;li&gt;将Lookback设置为：Custom Time Range&lt;/li&gt;
&lt;li&gt;设置Start Time和End Time&lt;/li&gt;
&lt;li&gt;设置Service为：app.web&lt;/li&gt;
&lt;li&gt;设置Operation为：
&lt;ul&gt;
&lt;li&gt;Web.HandleApi.apiGetWork&lt;/li&gt;
&lt;li&gt;Web.HandleApi.apiUpdateViewed&lt;/li&gt;
&lt;li&gt;Web.HandleApi.apiGetAchievement&lt;/li&gt;
&lt;li&gt;Web.HandleApi.apiPlanWork&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;设置Limit Results为最大值1500&lt;/li&gt;
&lt;li&gt;查看右上角的耗时分布图以及查询数&lt;/li&gt;
&lt;li&gt;选择几个耗时比较大的个例，点击观察原因&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;5-报告&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E6%8A%A5%E5%91%8A&quot; aria-label=&quot;5 报告 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 报告&lt;/h1&gt;
&lt;p&gt;经过实机测试，报告如下，有兴趣的可以打开看看：&lt;/p&gt;
&lt;h2 id=&quot;51-第一次测试&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-%E7%AC%AC%E4%B8%80%E6%AC%A1%E6%B5%8B%E8%AF%95&quot; aria-label=&quot;51 第一次测试 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 第一次测试&lt;/h2&gt;
&lt;p&gt;1000qps测试发现瓶颈点（预设瓶颈，意料之中）Consumer CPU消耗过于剧烈。&lt;/p&gt;
&lt;h2 id=&quot;52-第二次测试&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E7%AC%AC%E4%BA%8C%E6%AC%A1%E6%B5%8B%E8%AF%95&quot; aria-label=&quot;52 第二次测试 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 第二次测试&lt;/h2&gt;
&lt;p&gt;解决Consumer的瓶颈问题，并对其进行验证。&lt;/p&gt;
&lt;p&gt;因预算和时间等原因，后续并没有展开更多的测试，仅两次，一次演示问题的发现，一次演示问题的解决和验证。&lt;/p&gt;
&lt;h1 id=&quot;appendix&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#appendix&quot; aria-label=&quot;appendix permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Appendix&lt;/h1&gt;
&lt;h2 id=&quot;监控清单-monitoring_list&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%9B%91%E6%8E%A7%E6%B8%85%E5%8D%95-monitoring_list&quot; aria-label=&quot;监控清单 monitoring_list permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;监控清单 {#MONITORING_LIST}&lt;/h2&gt;
&lt;h3 id=&quot;host&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#host&quot; aria-label=&quot;host permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Host&lt;/h3&gt;
&lt;p&gt;Dashboard uid: 9CWBz0bik&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-interval=5s 调整图表的采样间隔，最低5s&lt;/li&gt;
&lt;li&gt;var-env=All 固定值&lt;/li&gt;
&lt;li&gt;var-name=All 固定值&lt;/li&gt;
&lt;li&gt;var-node=192.168.3.111%3A9100 label_values(node_exporter_build_info,instance)&lt;/li&gt;
&lt;li&gt;var-maxmount= 固定值&lt;/li&gt;
&lt;li&gt;panelId=13 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/9CWBz0bik/nodes?orgId=1&amp;#x26;var-interval=5s&amp;#x26;var-env=All&amp;#x26;var-name=All&amp;#x26;var-node=192.168.3.111%3A9100&amp;#x26;var-maxmount=&amp;#x26;from=1562202150372&amp;#x26;to=1562205750372&amp;#x26;panelId=13&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;系统运行时间
&lt;ul&gt;
&lt;li&gt;panelId=15&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU 核数
&lt;ul&gt;
&lt;li&gt;panelId=14&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;内存总量
&lt;ul&gt;
&lt;li&gt;panelId=75&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU使用率（5m）
&lt;ul&gt;
&lt;li&gt;panelId=167&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU iowait（5m）
&lt;ul&gt;
&lt;li&gt;panelId=20&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;内存使用率
&lt;ul&gt;
&lt;li&gt;panelId=172&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;当前打开的文件描述符
&lt;ul&gt;
&lt;li&gt;panelId=16&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;根分区使用率
&lt;ul&gt;
&lt;li&gt;panelId=166&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;系统平均负载
&lt;ul&gt;
&lt;li&gt;panelId=13&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;磁盘总空间
&lt;ul&gt;
&lt;li&gt;panelId=171&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;各分区可用空间
&lt;ul&gt;
&lt;li&gt;panelId=164&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU使用率、磁盘每秒的I/O操作耗费时间（%）
&lt;ul&gt;
&lt;li&gt;panelId=7&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;内存信息
&lt;ul&gt;
&lt;li&gt;panelId=156&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;磁盘读写速率（IOPS）
&lt;ul&gt;
&lt;li&gt;panelId=161&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;磁盘读写容量大小
&lt;ul&gt;
&lt;li&gt;panelId=168&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;磁盘IO读写时间
&lt;ul&gt;
&lt;li&gt;panelId=160&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;网络流量
&lt;ul&gt;
&lt;li&gt;panelId=157&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;TCP 连接情况
&lt;ul&gt;
&lt;li&gt;panelId=158&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;container&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#container&quot; aria-label=&quot;container permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Container&lt;/h3&gt;
&lt;p&gt;Dashboard uid: PV1XyHnWz&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;refresh=30s 不生效，但建议保留&lt;/li&gt;
&lt;li&gt;var-containergroup=All 固定值&lt;/li&gt;
&lt;li&gt;var-interval=30s 调整图表的采样间隔，最低30s&lt;/li&gt;
&lt;li&gt;var-server=192.168.3.111 label_values(node_boot_time_seconds, instance) /([^:]+):.*/ 去掉了instance的port&lt;/li&gt;
&lt;li&gt;var-name=prometheus 容器名&lt;/li&gt;
&lt;li&gt;panelId=8 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/PV1XyHnWz/docker-and-system-monitoring?orgId=1&amp;#x26;from=1562200204905&amp;#x26;to=1562203804906&amp;#x26;refresh=30s&amp;#x26;var-containergroup=All&amp;#x26;var-interval=30s&amp;#x26;var-server=192.168.3.111&amp;#x26;var-name=prometheus&amp;#x26;panelId=8&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Received Network Traffic per Container
&lt;ul&gt;
&lt;li&gt;容器收到的网络流量&lt;/li&gt;
&lt;li&gt;panelId=8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Sent Network Traffic per Container
&lt;ul&gt;
&lt;li&gt;容器发送的网络流量&lt;/li&gt;
&lt;li&gt;panelId=9&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU Usage per Container
&lt;ul&gt;
&lt;li&gt;容器消耗的CPU&lt;/li&gt;
&lt;li&gt;panelId=1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Memory Usage per Container
&lt;ul&gt;
&lt;li&gt;容器消耗的内存&lt;/li&gt;
&lt;li&gt;panelId=10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Memory Swap per Container
&lt;ul&gt;
&lt;li&gt;容器的交换内存&lt;/li&gt;
&lt;li&gt;panelId=34&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;memcached&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#memcached&quot; aria-label=&quot;memcached permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Memcached&lt;/h3&gt;
&lt;p&gt;Dashboard uid: NgzwcO7Zz&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-node=memcached-exporter%3A9150 label_values(memcached_up, instance)&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/NgzwcO7Zz/prometheus-memcached?orgId=1&amp;#x26;from=1562203120775&amp;#x26;to=1562206720775&amp;#x26;var-node=memcached-exporter%3A9150&amp;#x26;panelId=1&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;% Hit ratio
&lt;ul&gt;
&lt;li&gt;命中率&lt;/li&gt;
&lt;li&gt;panelId=1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Connections
&lt;ul&gt;
&lt;li&gt;连接数&lt;/li&gt;
&lt;li&gt;panelId=4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Get / Set ratio
&lt;ul&gt;
&lt;li&gt;Get Set比率&lt;/li&gt;
&lt;li&gt;panelId=3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Commands
&lt;ul&gt;
&lt;li&gt;按种类显示命令执行的数量&lt;/li&gt;
&lt;li&gt;panelId=2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;evicts / reclaims
&lt;ul&gt;
&lt;li&gt;Key驱逐数量&lt;/li&gt;
&lt;li&gt;panelId=8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Read / written bytes
&lt;ul&gt;
&lt;li&gt;网络流量&lt;/li&gt;
&lt;li&gt;panelId=6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Total memory usage
&lt;ul&gt;
&lt;li&gt;内存使用率&lt;/li&gt;
&lt;li&gt;panelId=7&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Items in cache
&lt;ul&gt;
&lt;li&gt;内存中Key数量&lt;/li&gt;
&lt;li&gt;panelId=5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;mysql&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#mysql&quot; aria-label=&quot;mysql permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;MySQL&lt;/h3&gt;
&lt;p&gt;Dashboard uid: MQWgroiiz&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-interval=1m 调整图表的采样间隔，最低1s&lt;/li&gt;
&lt;li&gt;var-host=mysqld-exporter%3A9104 label_values(mysql_up, instance)&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/MQWgroiiz/mysql-overview?orgId=1&amp;#x26;from=1562165395404&amp;#x26;to=1562208595404&amp;#x26;var-interval=1m&amp;#x26;var-host=mysqld-exporter%3A9104&amp;#x26;panelId=92&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MySQL Connections
&lt;ul&gt;
&lt;li&gt;连接状态&lt;/li&gt;
&lt;li&gt;panelId=92&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Aborted Connections
&lt;ul&gt;
&lt;li&gt;退出的连接统计&lt;/li&gt;
&lt;li&gt;panelId=47&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Client Thread Activity
&lt;ul&gt;
&lt;li&gt;线程活动状态&lt;/li&gt;
&lt;li&gt;panelId=10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Thread Cache
&lt;ul&gt;
&lt;li&gt;线程池状态&lt;/li&gt;
&lt;li&gt;panelId=11&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Questions
&lt;ul&gt;
&lt;li&gt;查询数量&lt;/li&gt;
&lt;li&gt;panelId=53&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Slow Queries
&lt;ul&gt;
&lt;li&gt;慢查询数量&lt;/li&gt;
&lt;li&gt;panelId=48&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Table Locks
&lt;ul&gt;
&lt;li&gt;表锁状态&lt;/li&gt;
&lt;li&gt;panelId=32&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Network Traffic
&lt;ul&gt;
&lt;li&gt;网络流量统计&lt;/li&gt;
&lt;li&gt;panelId=9&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Network Usage Hourly
&lt;ul&gt;
&lt;li&gt;网络流量统计/小时&lt;/li&gt;
&lt;li&gt;panelId=381&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Internal Memory Overview
&lt;ul&gt;
&lt;li&gt;内部内存使用状态&lt;/li&gt;
&lt;li&gt;panelId=50&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Top Command Counters
&lt;ul&gt;
&lt;li&gt;执行命令按种类分类数量&lt;/li&gt;
&lt;li&gt;panelId=14&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Top Command Counters Hourly
&lt;ul&gt;
&lt;li&gt;命令数量/小时&lt;/li&gt;
&lt;li&gt;panelId=39&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Query Cache Memory
&lt;ul&gt;
&lt;li&gt;缓存使用量&lt;/li&gt;
&lt;li&gt;panelId=46&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Query Cache Activity
&lt;ul&gt;
&lt;li&gt;缓存命中状态&lt;/li&gt;
&lt;li&gt;panelId=45&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL File Openings
&lt;ul&gt;
&lt;li&gt;实时打开的文件数量&lt;/li&gt;
&lt;li&gt;panelId=43&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MySQL Open Files
&lt;ul&gt;
&lt;li&gt;打开文件统计&lt;/li&gt;
&lt;li&gt;panelId=41&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;prometheus&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheus&quot; aria-label=&quot;prometheus permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Prometheus&lt;/h3&gt;
&lt;p&gt;Dashboard uid: 54e7hO7Wk&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-job=prometheus 固定值&lt;/li&gt;
&lt;li&gt;var-instance=prometheus 固定值&lt;/li&gt;
&lt;li&gt;var-interval=1h 调整图表的采样间隔，最低1h&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/54e7hO7Wk/prometheus-2-0-overview?orgId=1&amp;#x26;panelId=33&amp;#x26;var-job=prometheus&amp;#x26;var-instance=prometheus%3A9090&amp;#x26;var-interval=1h&amp;#x26;from=1562307966107&amp;#x26;to=1562311566107&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Series Count
&lt;ul&gt;
&lt;li&gt;时序数量&lt;/li&gt;
&lt;li&gt;panelId=3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Failures and Errors
&lt;ul&gt;
&lt;li&gt;采样出错&lt;/li&gt;
&lt;li&gt;panelId=33&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Appended Samples per Second
&lt;ul&gt;
&lt;li&gt;每秒采样数量&lt;/li&gt;
&lt;li&gt;panelId=4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Scrape Duration
&lt;ul&gt;
&lt;li&gt;采样耗时&lt;/li&gt;
&lt;li&gt;panelId=29&lt;/li&gt;
&lt;li&gt;该图表按instance进行显示，因此如果需要查询某个特定服务的采样抓取耗时，需要调整该参数，不能固定使用prometheus&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Prometheus Engine Query Duration Seconds
&lt;ul&gt;
&lt;li&gt;查询耗时情况&lt;/li&gt;
&lt;li&gt;panelId=15&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;kafka-jmx&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#kafka-jmx&quot; aria-label=&quot;kafka jmx permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Kafka JMX&lt;/h3&gt;
&lt;p&gt;Dashboard uid: chanjarster-jvm-dashboard&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-datasource=Prometheus 固定值&lt;/li&gt;
&lt;li&gt;var-job=kafka 固定值&lt;/li&gt;
&lt;li&gt;var-instance=kafka_1%3A7071 label_values(jvm_info{job=“$job”},instance)&lt;/li&gt;
&lt;li&gt;var-mempool=All 固定值&lt;/li&gt;
&lt;li&gt;var-memarea=All 固定值&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/chanjarster-jvm-dashboard/kafka-jmx-dashboard?orgId=1&amp;#x26;panelId=29&amp;#x26;from=1562309167160&amp;#x26;to=1562312767160&amp;#x26;var-datasource=Prometheus&amp;#x26;var-job=kafka&amp;#x26;var-instance=kafka_1%3A7071&amp;#x26;var-mempool=All&amp;#x26;var-memarea=All&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open file descriptors
&lt;ul&gt;
&lt;li&gt;文件打开情况&lt;/li&gt;
&lt;li&gt;panelId=38&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU load
&lt;ul&gt;
&lt;li&gt;CPU使用情况，含JVM的统计区分&lt;/li&gt;
&lt;li&gt;panelId=29&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Memory area [heap]
&lt;ul&gt;
&lt;li&gt;堆内存使用情况&lt;/li&gt;
&lt;li&gt;panelId=8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Memory area [nonheap]
&lt;ul&gt;
&lt;li&gt;堆外内存使用情况&lt;/li&gt;
&lt;li&gt;panelId=45&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GC count increase
&lt;ul&gt;
&lt;li&gt;GC数量&lt;/li&gt;
&lt;li&gt;panelId=6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GC time
&lt;ul&gt;
&lt;li&gt;GC耗时&lt;/li&gt;
&lt;li&gt;panelId=5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Threads used
&lt;ul&gt;
&lt;li&gt;线程数量&lt;/li&gt;
&lt;li&gt;panelId=3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Physical memory
&lt;ul&gt;
&lt;li&gt;物理内存情况&lt;/li&gt;
&lt;li&gt;panelId=44&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;kafka-exporter&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#kafka-exporter&quot; aria-label=&quot;kafka exporter permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Kafka Exporter&lt;/h3&gt;
&lt;p&gt;Dashboard uid: jwPKIsniz&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-job=kafka-exporter 固定值&lt;/li&gt;
&lt;li&gt;var-instance=kafka_exporter%3A9308 label_values(kafka_consumergroup_current_offset{job=~“$job”}, instance)&lt;/li&gt;
&lt;li&gt;var-topic=All 固定值，可调整&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/jwPKIsniz/kafka-exporter-overview?orgId=1&amp;#x26;panelId=14&amp;#x26;from=1562309984557&amp;#x26;to=1562313584557&amp;#x26;var-job=kafka-exporter&amp;#x26;var-instance=kafka_exporter%3A9308&amp;#x26;var-topic=All&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Message in per second
&lt;ul&gt;
&lt;li&gt;每秒消息数量&lt;/li&gt;
&lt;li&gt;panelId=14&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Lag by Consumer Group
&lt;ul&gt;
&lt;li&gt;消费组延迟&lt;/li&gt;
&lt;li&gt;panelId=12&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Message in per minute
&lt;ul&gt;
&lt;li&gt;每分钟消息数量&lt;/li&gt;
&lt;li&gt;panelId=16&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Message consume per minute
&lt;ul&gt;
&lt;li&gt;每分钟消息消费&lt;/li&gt;
&lt;li&gt;panelId=18&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;jaeger-agent&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-agent&quot; aria-label=&quot;jaeger agent permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Jaeger Agent&lt;/h3&gt;
&lt;p&gt;Dashboard uid: Z8ieXpnWk&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-node=jagent_web%3A5778 label_values(jaeger_agent_thrift_udp_server_queue_size, instance)&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/Z8ieXpnWk/jaeger-agent?tab=advanced&amp;#x26;orgId=1&amp;#x26;panelId=6&amp;#x26;from=1562311474404&amp;#x26;to=1562315074404&amp;#x26;var-node=jagent_web%3A5778&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Reporter batches submitted
&lt;ul&gt;
&lt;li&gt;Reporter批量提交数（提交至collector）&lt;/li&gt;
&lt;li&gt;panelId=6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reporter batches failures
&lt;ul&gt;
&lt;li&gt;Reporter批量提交失败数&lt;/li&gt;
&lt;li&gt;panelId=8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reporter spans submitted
&lt;ul&gt;
&lt;li&gt;Reporter span提交数量&lt;/li&gt;
&lt;li&gt;panelId=10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reporter spans failures
&lt;ul&gt;
&lt;li&gt;Reporter span提交失败数&lt;/li&gt;
&lt;li&gt;panelId=12&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Queue size
&lt;ul&gt;
&lt;li&gt;Receiver等待队列（从app过来）&lt;/li&gt;
&lt;li&gt;panelId=24&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Read errors
&lt;ul&gt;
&lt;li&gt;ReceiverUDP读取错误数&lt;/li&gt;
&lt;li&gt;panelId=26&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Packets processed
&lt;ul&gt;
&lt;li&gt;Receiver处理的包数量&lt;/li&gt;
&lt;li&gt;panelId=20&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Packets dropped
&lt;ul&gt;
&lt;li&gt;Receiver丢弃的包数量&lt;/li&gt;
&lt;li&gt;panelId=22&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;jaeger-collector&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-collector&quot; aria-label=&quot;jaeger collector permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Jaeger Collector&lt;/h3&gt;
&lt;p&gt;Dashboard uid: mb6-JR5iz&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-node=jcollector_1%3A14268 label_values(jaeger_collector_queue_length, instance)&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/mb6-JR5iz/jaeger-collector?orgId=1&amp;#x26;var-node=jcollector_1%3A14268&amp;#x26;from=1562312765270&amp;#x26;to=1562316365270&amp;#x26;panelId=20&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Traces received
&lt;ul&gt;
&lt;li&gt;收到的trace数量&lt;/li&gt;
&lt;li&gt;panelId=20&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Traces rejected
&lt;ul&gt;
&lt;li&gt;拒绝的trace数量&lt;/li&gt;
&lt;li&gt;panelId=22&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Spans received
&lt;ul&gt;
&lt;li&gt;收到的span数量&lt;/li&gt;
&lt;li&gt;panelId=18&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Spans dropped
&lt;ul&gt;
&lt;li&gt;丢弃的span数量&lt;/li&gt;
&lt;li&gt;panelId=4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Spans rejected
&lt;ul&gt;
&lt;li&gt;拒绝的span数量&lt;/li&gt;
&lt;li&gt;panelId=24&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Queue length
&lt;ul&gt;
&lt;li&gt;队列长度&lt;/li&gt;
&lt;li&gt;panelId=2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Span queue latency - 95 percentile
&lt;ul&gt;
&lt;li&gt;span处理时长 95%&lt;/li&gt;
&lt;li&gt;panelId=10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Save latency - 95 percentile
&lt;ul&gt;
&lt;li&gt;数据库存储时长 95%&lt;/li&gt;
&lt;li&gt;panelId=26&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cassandra attempts
&lt;ul&gt;
&lt;li&gt;cassandra数据库请求数量&lt;/li&gt;
&lt;li&gt;panelId=16&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cassandra errors
&lt;ul&gt;
&lt;li&gt;cassandra数据库报错&lt;/li&gt;
&lt;li&gt;panelId=12&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;filebeat&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#filebeat&quot; aria-label=&quot;filebeat permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Filebeat&lt;/h3&gt;
&lt;p&gt;Dashboard uid: oF_Qr14Zz&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-node=filebeat_exporter%3A9479 label_values(filebeat_uptime_seconds, instance)&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/oF_Qr14Zz/filebeat?orgId=1&amp;#x26;from=1562313566558&amp;#x26;to=1562317166558&amp;#x26;var-node=filebeat_exporter%3A9479&amp;#x26;panelId=2&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Harvester
&lt;ul&gt;
&lt;li&gt;追踪文件的状态&lt;/li&gt;
&lt;li&gt;panelId=2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IO errors
&lt;ul&gt;
&lt;li&gt;IO错误&lt;/li&gt;
&lt;li&gt;panelId=8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Filebeat events
&lt;ul&gt;
&lt;li&gt;filebeat事件&lt;/li&gt;
&lt;li&gt;panelId=4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Output events
&lt;ul&gt;
&lt;li&gt;输出事件&lt;/li&gt;
&lt;li&gt;panelId=6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pipeline events
&lt;ul&gt;
&lt;li&gt;管线事件&lt;/li&gt;
&lt;li&gt;panelId=10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pipeline queue
&lt;ul&gt;
&lt;li&gt;管线队列&lt;/li&gt;
&lt;li&gt;panelId=12&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;elasticsearch&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#elasticsearch&quot; aria-label=&quot;elasticsearch permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Elasticsearch&lt;/h3&gt;
&lt;p&gt;Dashboard uid: FNysokSWk&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-interval=5m 调整图表的采样间隔，最低5m&lt;/li&gt;
&lt;li&gt;var-cluster=es_cluster 固定值&lt;/li&gt;
&lt;li&gt;var-name=es_1 label_values(elasticsearch_indices_docs{cluster=“$cluster”, name!=&quot;&quot;},name)&lt;/li&gt;
&lt;li&gt;var-instance=es_exporter%3A9114 固定值&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/FNysokSWk/elasticsearch?orgId=1&amp;#x26;from=1562315066925&amp;#x26;to=1562318666925&amp;#x26;var-interval=5m&amp;#x26;var-cluster=docker-cluster&amp;#x26;var-name=es_1&amp;#x26;var-instance=es_exporter%3A9114&amp;#x26;panelId=50&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pending tasks
&lt;ul&gt;
&lt;li&gt;集群未完成工作数&lt;/li&gt;
&lt;li&gt;panelId=16&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Load average
&lt;ul&gt;
&lt;li&gt;节点负载&lt;/li&gt;
&lt;li&gt;panelId=30&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CPU usage
&lt;ul&gt;
&lt;li&gt;节点CPU使用&lt;/li&gt;
&lt;li&gt;panelId=88&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;JVM memory usage
&lt;ul&gt;
&lt;li&gt;节点内存使用&lt;/li&gt;
&lt;li&gt;panelId=31&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GC count
&lt;ul&gt;
&lt;li&gt;GC次数&lt;/li&gt;
&lt;li&gt;panelId=7&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GC time
&lt;ul&gt;
&lt;li&gt;GC耗时&lt;/li&gt;
&lt;li&gt;panelId=27&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Total translog operations
&lt;ul&gt;
&lt;li&gt;持久化操作数&lt;/li&gt;
&lt;li&gt;panelId=77&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Total translog size in bytes
&lt;ul&gt;
&lt;li&gt;持久化容量&lt;/li&gt;
&lt;li&gt;panelId=78&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tripped for breakers
&lt;ul&gt;
&lt;li&gt;断路器触发次数&lt;/li&gt;
&lt;li&gt;panelId=79&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Estimated size in bytes of breaker
&lt;ul&gt;
&lt;li&gt;断路器触发限制&lt;/li&gt;
&lt;li&gt;panelId=80&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disk usage
&lt;ul&gt;
&lt;li&gt;磁盘用量&lt;/li&gt;
&lt;li&gt;panelId=32&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Network usage
&lt;ul&gt;
&lt;li&gt;网络用量&lt;/li&gt;
&lt;li&gt;panelId=47&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Documents count on node
&lt;ul&gt;
&lt;li&gt;文档数量&lt;/li&gt;
&lt;li&gt;panelId=1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Documents indexed rate
&lt;ul&gt;
&lt;li&gt;文档索引数&lt;/li&gt;
&lt;li&gt;panelId=24&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Documents merged rate
&lt;ul&gt;
&lt;li&gt;文档合并率&lt;/li&gt;
&lt;li&gt;panelId=26&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Documents merged bytes
&lt;ul&gt;
&lt;li&gt;文档合并量&lt;/li&gt;
&lt;li&gt;panelId=52&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Query time
&lt;ul&gt;
&lt;li&gt;查询耗时&lt;/li&gt;
&lt;li&gt;panelId=33&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Indexing time
&lt;ul&gt;
&lt;li&gt;索引耗时&lt;/li&gt;
&lt;li&gt;panelId=5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Merging time
&lt;ul&gt;
&lt;li&gt;合并耗时&lt;/li&gt;
&lt;li&gt;panelId=3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Total Operations rate
&lt;ul&gt;
&lt;li&gt;所有操作速率&lt;/li&gt;
&lt;li&gt;panelId=48&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Total Operations time
&lt;ul&gt;
&lt;li&gt;所有操作耗时&lt;/li&gt;
&lt;li&gt;panelId=49&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;golang&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#golang&quot; aria-label=&quot;golang permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Golang&lt;/h3&gt;
&lt;p&gt;Dashboard uid: ypFZFgvmz&lt;/p&gt;
&lt;p&gt;Graph params:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;var-job=go-apps 固定值&lt;/li&gt;
&lt;li&gt;var-interval=1m 调整图表的采样间隔，最低1m&lt;/li&gt;
&lt;li&gt;var-node=192.168.3.111%3A8000 label_values(go_memstats_alloc_bytes, instance)&lt;/li&gt;
&lt;li&gt;panelId=1 根据图表，编号各自不同&lt;/li&gt;
&lt;li&gt;width=1000&amp;#x26;height=500 图表大小&lt;/li&gt;
&lt;li&gt;tz=Asia%2FShanghai 用户时区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sample graph link: &lt;a href=&quot;http://127.0.0.1:3000/render/d-solo/ypFZFgvmz/go-processes?orgId=1&amp;#x26;from=1562314327587&amp;#x26;to=1562317927587&amp;#x26;var-job=go-apps&amp;#x26;var-interval=1m&amp;#x26;var-node=192.168.3.111%3A8000&amp;#x26;panelId=1&amp;#x26;width=1000&amp;#x26;height=500&amp;#x26;tz=Asia%2FShanghai&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;link&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Monitoring items:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Heap memory
&lt;ul&gt;
&lt;li&gt;堆内存用量&lt;/li&gt;
&lt;li&gt;panelId=1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Heap memory trends
&lt;ul&gt;
&lt;li&gt;堆内存申请和释放情况&lt;/li&gt;
&lt;li&gt;panelId=4&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Heap objects
&lt;ul&gt;
&lt;li&gt;堆内存对象数量&lt;/li&gt;
&lt;li&gt;panelId=2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Heap system alloc
&lt;ul&gt;
&lt;li&gt;堆内存向系统申请和释放情况&lt;/li&gt;
&lt;li&gt;panelId=5&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GC rate
&lt;ul&gt;
&lt;li&gt;GC频次&lt;/li&gt;
&lt;li&gt;panelId=3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Next gc target
&lt;ul&gt;
&lt;li&gt;下次GC触发容量&lt;/li&gt;
&lt;li&gt;panelId=6&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GC duration quantiles
&lt;ul&gt;
&lt;li&gt;GC耗时情况，分25% 50% 90%三段&lt;/li&gt;
&lt;li&gt;panelId=8&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Goroutines count
&lt;ul&gt;
&lt;li&gt;goroutine数量&lt;/li&gt;
&lt;li&gt;panelId=7&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Threads count
&lt;ul&gt;
&lt;li&gt;线程数量&lt;/li&gt;
&lt;li&gt;panelId=10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Memcached Notes]]></title><link>https://xenojoshua.com/posts/2019/05/memcached-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/05/memcached-note</guid><pubDate>Sat, 11 May 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%B8%85%E5%8D%95&quot;&gt;2. 清单&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-mixi%E7%9A%84%E7%B3%BB%E5%88%97%E5%8D%9A%E6%96%87&quot;&gt;2.1 Mixi的系列博文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E8%87%AA%E6%92%B0%E7%9A%84%E7%B3%BB%E5%88%97%E5%8D%9A%E6%96%87&quot;&gt;2.2 自撰的系列博文&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;早年对memcached有过一系列非常深入的研究分析，并形成了大量的文字积累。memcached这个软件在那么多年中也并没有什么很大的变化，毕竟它要服务的功能相对来说还是非常稳定的，就那么一小块，做好就好了。&lt;/p&gt;
&lt;p&gt;因为文章年代都比较久远了，现在要找都需要到tag里去搜，就比较麻烦。因此在这里做一个综合，把所有的内容都罗列进来。&lt;/p&gt;
&lt;h1 id=&quot;2-清单&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%B8%85%E5%8D%95&quot; aria-label=&quot;2 清单 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 清单&lt;/h1&gt;
&lt;h2 id=&quot;21-mixi的系列博文&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-mixi%E7%9A%84%E7%B3%BB%E5%88%97%E5%8D%9A%E6%96%87&quot; aria-label=&quot;21 mixi的系列博文 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 Mixi的系列博文&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/memcached-anatomy-001/&quot;&gt;memcached完全剖析–1. memcached的基础&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/memcached-anatomy-002/&quot;&gt;memcached全面剖析–2.理解memcached的内存存储&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/memcached-anatomy-003/&quot;&gt;memcached全面剖析–3.memcached的删除机制和发展方向&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/memcached-anatomy-004/&quot;&gt;memcached全面剖析–4. memcached的分布式算法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/memcached-anatomy-005/&quot;&gt;memcached全面剖析–5. memcached的应用和兼容程序&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;22-自撰的系列博文&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E8%87%AA%E6%92%B0%E7%9A%84%E7%B3%BB%E5%88%97%E5%8D%9A%E6%96%87&quot; aria-label=&quot;22 自撰的系列博文 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 自撰的系列博文&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/deep-in-memcached-how-it-works/&quot;&gt;Memcached深入理解 - memcached究竟是如何运作的&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/deep-in-memcached-learning-official-protocol-stats/&quot;&gt;Memcached深入理解 – 理解官方protocol中的统计方法&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2011/04/deep-in-memcached-how-to-monitor/&quot;&gt;Memcached深入理解 - memcached的监控&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Pipeline]]></title><link>https://xenojoshua.com/posts/2019/05/golang-pipeline</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/05/golang-pipeline</guid><pubDate>Fri, 10 May 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-channel%E5%AE%9E%E9%AA%8C%E8%8C%83%E4%BE%8B&quot;&gt;2. Channel实验范例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-go-concurrency-patterns-pipelines-and-cancellation&quot;&gt;3. Go Concurrency Patterns: Pipelines and cancellation&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E4%BB%80%E4%B9%88%E6%98%AFpipeline&quot;&gt;3.1 什么是Pipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-cancel-channel-done&quot;&gt;3.2 Cancel: Channel Done&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-cancel-context&quot;&gt;3.3 Cancel: Context&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;学习一门新语言最简单的就是那些顺序执行的语言，会了PHP，换JAVA、Python、Ruby，无非就是语法更换下，上stackoverflow查下：“python字符串拼接”之类的，看下怎么写就完事了。难的是那些有特殊编程思维的语言，比如说JavaScript，异步原生，写代码要非常小心注意异步的返回如何处理，否则就会明明看着是先A后B，执行的时候却成了先B再A。就这方面来说，Go语言也属于后者，属于那种&lt;code class=&quot;language-text&quot;&gt;语法看会简单，实际学精很难&lt;/code&gt;的语言，而Golang难就难在goroutine以及channel带来的功能上。&lt;/p&gt;
&lt;p&gt;之前在查看Go语言的gRPC第三方库的时候，其代码对channel的运用非常灵活：&lt;a href=&quot;https://github.com/processout/grpc-go-pool/blob/master/pool.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-go-pool/pool.go&lt;/a&gt;。深感需要加深这块的理解。&lt;/p&gt;
&lt;p&gt;在学习的时候，找到了一篇官方之前的博客，时间比较早了（2014年），但还算有用：&lt;a href=&quot;https://blog.golang.org/pipelines&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Concurrency Patterns: Pipelines and cancellation&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;不过语言还是一直在发展的，目前在进行批量的routine控制以及退出触发的方面，最佳的解决方案是&lt;code class=&quot;language-text&quot;&gt;context&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;接下来，一点点开始。&lt;/p&gt;
&lt;h1 id=&quot;2-channel实验范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-channel%E5%AE%9E%E9%AA%8C%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;2 channel实验范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. Channel实验范例&lt;/h1&gt;
&lt;p&gt;在阅读官方博文之前，先自己着手做一些范例代码，加深对于&lt;a href=&quot;/2019/03/golang-basic/#ID_CHANNEL&quot;&gt;Golang Basic &gt; 2.4 通道 / 信道 channel&lt;/a&gt;的理解。&lt;/p&gt;
&lt;p&gt;我做了点简单的演示范例：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/experiment/channel&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/experiment/channel/&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;只需要结果的话，可以直接读README：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/experiment/channel/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/experiment/channel/README.md&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;当中有几点比较有意思：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;slice值进出channel之后，&lt;code class=&quot;language-text&quot;&gt;地址&lt;/code&gt;并&lt;code class=&quot;language-text&quot;&gt;没有改变&lt;/code&gt;，和pointer是一样的结果&lt;/li&gt;
&lt;li&gt;channel在无buffer的情况下，很容易就会阻塞，导致routine睡眠，必须小心处理&lt;/li&gt;
&lt;li&gt;带buffer的channel，在buffer耗尽之后也是同样的结果，实际上来说也必须小心阻塞&lt;/li&gt;
&lt;li&gt;虽然向关闭的通道写数据会引起panic，但向关闭的通道&lt;code class=&quot;language-text&quot;&gt;读数据&lt;/code&gt;却&lt;code class=&quot;language-text&quot;&gt;不会&lt;/code&gt;，只会获得通道类型的&lt;code class=&quot;language-text&quot;&gt;默认值&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有一张图，很好地将一系列状态以及操作结果整理了出来，可以参考：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/05/golang-pipeline/close_chan.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;3-go-concurrency-patterns-pipelines-and-cancellation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-go-concurrency-patterns-pipelines-and-cancellation&quot; aria-label=&quot;3 go concurrency patterns pipelines and cancellation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Go Concurrency Patterns: Pipelines and cancellation&lt;/h1&gt;
&lt;p&gt;这里并不会通篇翻译：&lt;a href=&quot;https://blog.golang.org/pipelines&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Concurrency Patterns: Pipelines and cancellation&lt;/a&gt;，有需要的可以看&lt;a href=&quot;https://imdiot.github.io/2016/01/01/Go%20Concurrency%20Patterns-Pipelines%20and%20cancellation.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;这篇&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;此外，本章后半也会涉及到&lt;code class=&quot;language-text&quot;&gt;context&lt;/code&gt;，毕竟这家伙才是现在的准标准。&lt;/p&gt;
&lt;h2 id=&quot;31-什么是pipeline&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E4%BB%80%E4%B9%88%E6%98%AFpipeline&quot; aria-label=&quot;31 什么是pipeline permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 什么是Pipeline&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;通过输入channel从&lt;code class=&quot;language-text&quot;&gt;上游&lt;/code&gt;接收值&lt;/li&gt;
&lt;li&gt;对这些数据执行某些函数，通常是生成一些新的值&lt;/li&gt;
&lt;li&gt;通过输出channel发送值到&lt;code class=&quot;language-text&quot;&gt;下游&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而在这一系列的交棒过程中，&lt;code class=&quot;language-text&quot;&gt;错误&lt;/code&gt;的发生和事务的&lt;code class=&quot;language-text&quot;&gt;取消&lt;/code&gt;是正常的情况，必须要进行&lt;code class=&quot;language-text&quot;&gt;处理&lt;/code&gt;，否则的话作为下游的routine可能会一直等待已经错误退出或取消事务的上游routine，导致&lt;code class=&quot;language-text&quot;&gt;资源泄露&lt;/code&gt;。使用的难点就在这里。&lt;/p&gt;
&lt;h2 id=&quot;32-cancel-channel-done&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-cancel-channel-done&quot; aria-label=&quot;32 cancel channel done permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 Cancel: Channel Done&lt;/h2&gt;
&lt;p&gt;官方博文中的代码范例写的非常散，因为有多处重复修改，这里提供一份完整拼接的版本：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/experiment/pipeline/pipeline.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;experiment/pipeline/pipeline.go&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;官方博文通篇都阅读了的话，撇开行文中的Dummy业务逻辑不谈，可以了解到该文主要还是谈了如何对出问题的routine进行退出通知。官方的博文中使用的方法是申明一个类型为&lt;code class=&quot;language-text&quot;&gt;struct{}&lt;/code&gt;的Dummy通道，关闭该通道来进行退出消息的传送。&lt;/p&gt;
&lt;p&gt;通过：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// HL&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;range&lt;/span&gt; nums &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; out &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt;done&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// HL&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;以这样的方式，监听&lt;code class=&quot;language-text&quot;&gt;done&lt;/code&gt;通道的关闭，退出routine函数，并设置defer函数，在routine函数退出的时候，清理对应的资源并关闭通道。这种编码解决方法确实能解决问题，但非常难看，也没有层级退出的概念。&lt;/p&gt;
&lt;h2 id=&quot;33-cancel-context&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-cancel-context&quot; aria-label=&quot;33 cancel context permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 Cancel: Context&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;done通道&lt;/code&gt;确实能在功能上达到要求，但尚欠缺了一些要素，因此后续就有&lt;code class=&quot;language-text&quot;&gt;context&lt;/code&gt;这个包的出现。相关的学习可以阅读：&lt;a href=&quot;https://deepzz.com/post/golang-context-package-notes.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;快速掌握 Golang context 包，简单示例&lt;/a&gt;。此外，还有官方博客：&lt;a href=&quot;https://blog.golang.org/context&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Concurrency Patterns: Context&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;一些概念和规范这里做下引用：&lt;/p&gt;
&lt;p&gt;Context 的调用应该是链式的，通过&lt;code class=&quot;language-text&quot;&gt;WithCancel&lt;/code&gt;，&lt;code class=&quot;language-text&quot;&gt;WithDeadline&lt;/code&gt;，&lt;code class=&quot;language-text&quot;&gt;WithTimeout&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;WithValue&lt;/code&gt;派生出新的 Context。当父 Context 被取消时，其派生的所有 Context 都将取消。&lt;/p&gt;
&lt;p&gt;通过&lt;code class=&quot;language-text&quot;&gt;context.WithXXX&lt;/code&gt;都将返回新的 Context 和 CancelFunc。调用 CancelFunc 将取消子代，移除父代对子代的引用，并且停止所有定时器。未能调用 CancelFunc 将泄漏子代，直到父代被取消或定时器触发。&lt;code class=&quot;language-text&quot;&gt;go vet&lt;/code&gt;工具检查所有流程控制路径上使用 CancelFuncs。&lt;/p&gt;
&lt;p&gt;遵循以下规则，以保持包之间的接口一致，并启用静态分析工具以检查上下文传播。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不要将 Contexts 放入结构体，相反&lt;code class=&quot;language-text&quot;&gt;context&lt;/code&gt;应该作为第一个参数传入，命名为ctx。&lt;code class=&quot;language-text&quot;&gt;func DoSomething（ctx context.Context，arg Arg）error { // ... use ctx ... }&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;即使函数允许，也不要传入&lt;code class=&quot;language-text&quot;&gt;nil&lt;/code&gt;的 Context。如果不知道用哪种 Context，可以使用&lt;code class=&quot;language-text&quot;&gt;context.TODO()&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;使用context的Value相关方法只应该用于在程序和接口中传递的和请求相关的元数据，不要用它来传递一些可选的参数&lt;/li&gt;
&lt;li&gt;相同的 Context 可以传递给在不同的&lt;code class=&quot;language-text&quot;&gt;goroutine&lt;/code&gt;；Context 是并发安全的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用法：&lt;/p&gt;
&lt;p&gt;Done函数会返回一个channel，用来进行close通知（本质上还是之前的那一套）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;gen &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Context&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;chan&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;-&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// returning not to leak the goroutine&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cancel &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithCancel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cancel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// cancel when we are finished consuming integers&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;此外，还有一篇老王的：&lt;a href=&quot;https://blog.huoding.com/2019/04/15/730&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang之Context的迷思&lt;/a&gt;，可以好好读下。&lt;/p&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/processout/grpc-go-pool/blob/master/pool.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-go-pool/pool.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/pipelines&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Concurrency Patterns: Pipelines and cancellation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://imdiot.github.io/2016/01/01/Go%20Concurrency%20Patterns-Pipelines%20and%20cancellation.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;『译』Go Concurrency Patterns: Pipelines and cancellation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://deepzz.com/post/golang-context-package-notes.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;快速掌握 Golang context 包，简单示例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.huoding.com/2019/04/15/730&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang之Context的迷思&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Envoy Notes]]></title><link>https://xenojoshua.com/posts/2019/05/envoy-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/05/envoy-note</guid><pubDate>Wed, 08 May 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E9%80%89%E5%9E%8B--%E6%AF%94%E8%BE%83&quot;&gt;2. 选型 &amp;#x26; 比较&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-benchmark&quot;&gt;3. Benchmark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E6%9E%B6%E6%9E%84&quot;&gt;4. 架构&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E4%BD%BF%E7%94%A8&quot;&gt;5. 使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-%E9%95%9C%E5%83%8F&quot;&gt;5.1 镜像&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E9%85%8D%E7%BD%AE&quot;&gt;5.2 配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#53-%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1front-proxy%E8%8C%83%E4%BE%8B&quot;&gt;5.3 负载均衡Front Proxy范例&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-admin-id_admin&quot;&gt;6. Admin {#ID_ADMIN}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-%E7%9B%91%E6%8E%A7&quot;&gt;7. 监控&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-todo&quot;&gt;8. TODO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#stats-prometheus-id_app_stats&quot;&gt;stats prometheus {#ID_APP_STATS}&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Envoy应该说是云原生这个概念起来之后的代理应用No.1。在当前的发展趋势下，使用Envoy来解决代理需求应该是最佳方案。&lt;/p&gt;
&lt;p&gt;中文手册：&lt;a href=&quot;http://www.servicemesher.com/envoy/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Envoy 官方文档中文版&lt;/a&gt;。当前（&lt;strong&gt;2019-05-07&lt;/strong&gt;）Envoy的最新版本是&lt;code class=&quot;language-text&quot;&gt;1.10&lt;/code&gt;，和中文的文档之间有几个小版本的跨度，需要注意。&lt;/p&gt;
&lt;h1 id=&quot;2-选型--比较&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E9%80%89%E5%9E%8B--%E6%AF%94%E8%BE%83&quot; aria-label=&quot;2 选型  比较 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 选型 &amp;#x26; 比较&lt;/h1&gt;
&lt;p&gt;作为新生代的代理应用，在使用之前必然会有一个为什么的疑问，为什么需要使用Envoy，它和Nginx以及HAProxy这类老牌代理应用相比，好在哪里。&lt;/p&gt;
&lt;p&gt;有一篇不错的博文可以阅读下：&lt;a href=&quot;https://blog.getambassador.io/envoy-vs-nginx-vs-haproxy-why-the-open-source-ambassador-api-gateway-chose-envoy-23826aed79ef&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Envoy vs NGINX vs HAProxy: Why the open source Ambassador API Gateway chose Envoy&lt;/a&gt;。作者最主要的Concern在于两点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nginx之类的其他软件，部分有商业版本和社区版本的区分，而社区版本普遍功能较为简陋，不能完全满足需求&lt;/li&gt;
&lt;li&gt;HAProxy之类的老牌软件，因为各种原因，功能演进都非常缓慢，不能跟上日益高速发展的云原生技术&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;说穿了就是功能不足，无论是商业原因还是研发原因还是资源原因。&lt;/p&gt;
&lt;p&gt;那么Envoy能提供什么功能：&lt;a href=&quot;http://www.servicemesher.com/envoy/intro/what_is_envoy.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Envoy 是什么？&lt;/a&gt;。可以看到Envoy提供的功能实在是太强大了，基本上现在主流的Proxy需求在Envoy身上都能得到满足。&lt;/p&gt;
&lt;p&gt;官方也有一篇横向比较：&lt;a href=&quot;http://www.servicemesher.com/envoy/intro/comparison.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;与类似系统比较&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;3-benchmark&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-benchmark&quot; aria-label=&quot;3 benchmark permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Benchmark&lt;/h1&gt;
&lt;p&gt;功能之后就是性能，那么和老牌的Nginx以及HAProxy等比较起来，Envoy的性能又如何呢。这里可以看下：&lt;a href=&quot;https://www.loggly.com/blog/benchmarking-5-popular-load-balancers-nginx-haproxy-envoy-traefik-and-alb/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Benchmarking 5 Popular Load Balancers: Nginx, HAProxy, Envoy, Traefik, and ALB&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Envoy came out as the overall winner in this benchmark. It had the highest throughput in terms of requests per second.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;文章发布时间是：&lt;code class=&quot;language-text&quot;&gt;10 Dec 2018&lt;/code&gt;，应该说还是非常具有时效性的。&lt;/p&gt;
&lt;img style=&quot;background-color:transparent;&quot; target=&quot;_blank&quot; src=&quot;/media/posts/2019/05/envoy-note/envoy-benchmark-01.png&quot;&gt;
&lt;img style=&quot;background-color:transparent;&quot; target=&quot;_blank&quot; src=&quot;/media/posts/2019/05/envoy-note/envoy-benchmark-02.png&quot;&gt;
&lt;img style=&quot;background-color:transparent;&quot; target=&quot;_blank&quot; src=&quot;/media/posts/2019/05/envoy-note/envoy-benchmark-03.png&quot;&gt;
&lt;img style=&quot;background-color:transparent;&quot; target=&quot;_blank&quot; src=&quot;/media/posts/2019/05/envoy-note/envoy-benchmark-04.png&quot;&gt;
&lt;h1 id=&quot;4-架构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E6%9E%B6%E6%9E%84&quot; aria-label=&quot;4 架构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 架构&lt;/h1&gt;
&lt;p&gt;除了在Nginx中比较常见的作为流量入口的代理模式之外，Envoy还介绍了一种作为服务网格总线的架构模式：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/05/envoy-note/arch-service-to-service.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;这种设计将Envoy作为面向服务架构（SOA）内部的所有流量的通信总线来使用。此设计将服务和服务之间的关系遮蔽了起来，服务集群只需要知道自己的Envoy在哪里即可，后续的流量就全部交给Envoy，而Envoy之间则通过服务发现将整个服务网格链接起来。&lt;/p&gt;
&lt;h1 id=&quot;5-使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;5 使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 使用&lt;/h1&gt;
&lt;h2 id=&quot;51-镜像&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-%E9%95%9C%E5%83%8F&quot; aria-label=&quot;51 镜像 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 镜像&lt;/h2&gt;
&lt;p&gt;一般使用镜像的方式进行安装：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;docker pull envoyproxy/envoy:v1.10.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;启动：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;docker run --rm -it -d \
    --name envoy-test \
    --network=envoy-test-net \
    -p 9901:9901 \
    -p 9988:9988 \
    -v ${PATH}/conf:/etc/envoy \
    -v ${PATH}/log:/tmp \
    envoyproxy/envoy:v1.10.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;镜像中配置文件的位置为：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;/etc/envoy/envoy.yaml&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以通过volume进行对应的配置文件覆盖。&lt;/p&gt;
&lt;h2 id=&quot;52-配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;52 配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 配置&lt;/h2&gt;
&lt;p&gt;因功能实在是太强大，Envoy的配置也就比较复杂，官方文档配置方面的总纲在：&lt;a href=&quot;http://www.servicemesher.com/envoy/configuration/configuration.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;配置参考&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;此外，因Envoy的消息都是通过Protobuf来进行设计的，因此可以查看源代码来阅读配置项：&lt;a href=&quot;https://github.com/envoyproxy/envoy/tree/v1.10.0/api/envoy/config&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;envoy/api/envoy/config/&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;另外，官方代码库也给了很多配置范例：&lt;a href=&quot;https://github.com/envoyproxy/envoy/tree/master/examples&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;envoy/examples/&lt;/a&gt;。以及：几个sandbox范例：&lt;a href=&quot;http://www.servicemesher.com/envoy/start/sandboxes.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Sandbox&lt;/a&gt;。最适合新手查看的应该是：&lt;a href=&quot;http://www.servicemesher.com/envoy/start/sandboxes/front_proxy.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;前端代理&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;有一篇&lt;a href=&quot;https://www.katacoda.com/envoyproxy/scenarios/migrating-from-nginx-to-envoy&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Migrating from NGINX to Envoy Proxy by envoyproxy&lt;/a&gt;相当不错。以范例的形式讲解了Nginx的配置如何翻译到Envoy。&lt;/p&gt;
&lt;p&gt;几个重要的配置项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/v1.10.0/operations/admin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Administration interface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/v1.10.0/api-v2/api/v2/lds.proto&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Listener&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/v1.10.0/api-v2/api/v2/listener/listener.proto#envoy-api-msg-listener-filter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;listener.Filter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/v1.10.0/api-v2/config/filter/network/http_connection_manager/v2/http_connection_manager.proto#envoy-api-msg-config-filter-network-http-connection-manager-v2-httpfilter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HttpFilter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/v1.10.0/api-v2/api/v2/cds.proto#cluster&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/v1.10.0/api-v2/api/v2/route/route.proto#envoy-api-msg-route-virtualhost&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;route.VirtualHost&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;细节这里就不展开了，实在是篇幅太大。简单的范例可以直接看官方给的例子。&lt;/p&gt;
&lt;h2 id=&quot;53-负载均衡front-proxy范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#53-%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1front-proxy%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;53 负载均衡front proxy范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3 负载均衡Front Proxy范例&lt;/h2&gt;
&lt;p&gt;简单的带负载均衡的Front Proxy范例可以看：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/experiment/envoy&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/experiment/envoy/&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;踩过的几个坑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;监听端的地址都必须是&lt;code class=&quot;language-text&quot;&gt;0.0.0.0&lt;/code&gt;，不能是127.0.0.1，否则在容器里收不到外部请求&lt;/li&gt;
&lt;li&gt;将其他的网络服务作为upstream使用时，必须与envoy连接在同一个docker network中&lt;/li&gt;
&lt;li&gt;clusters配置中的端点地址可以使用其他&lt;code class=&quot;language-text&quot;&gt;docker容器的名字&lt;/code&gt;作为address&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;6-admin-id_admin&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-admin-id_admin&quot; aria-label=&quot;6 admin id_admin permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Admin {#ID_ADMIN}&lt;/h1&gt;
&lt;p&gt;在Envoy的配置中有一个&lt;code class=&quot;language-text&quot;&gt;admin&lt;/code&gt;节点可以用来配置admin功能访问：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;admin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;access_log_path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/tmp/admin_access.log&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;profile_path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/tmp/envoy.prof&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;socket_address&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;address&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 127.0.0.1
      &lt;span class=&quot;token key atrule&quot;&gt;port_value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9901&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;提供一些admin相关功能，文档可以看：&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/v1.10.0/operations/admin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Administration interface&lt;/a&gt;。功能列表东西还真不少。&lt;/p&gt;
&lt;p&gt;需要注意：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;All mutations must be sent as HTTP POST operations. When a mutation is requested via GET, the request has no effect, and an HTTP 400 (Invalid Request) response is returned.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;7-监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;7 监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. 监控&lt;/h1&gt;
&lt;p&gt;监控一样可以使用Prometheus进行Metrics采集。Envoy在启动的时候必须配置&lt;a href=&quot;#ID_ADMIN&quot;&gt;6. Admin&lt;/a&gt;，然后就可以在&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:9901/stats/prometheus&lt;/code&gt;获取到Metrics。&lt;/p&gt;
&lt;p&gt;本文在最后的附录部分留了一份样例：&lt;a href=&quot;#ID_APP_STATS&quot;&gt;stats prometheus&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;8-todo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-todo&quot; aria-label=&quot;8 todo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. TODO&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Envoy的内部架构&lt;/li&gt;
&lt;li&gt;Envoy的高可用设计&lt;/li&gt;
&lt;li&gt;Envoy热加载的设计原理&lt;/li&gt;
&lt;li&gt;Envoy的集群使用&lt;/li&gt;
&lt;li&gt;Envoy的其他高级功能使用范例&lt;/li&gt;
&lt;li&gt;Envoy的Metrics理解&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2018/10/27/envoy-basics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Some Envoy basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.servicemesher.com/envoy/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Envoy 官方文档中文版&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.getambassador.io/envoy-vs-nginx-vs-haproxy-why-the-open-source-ambassador-api-gateway-chose-envoy-23826aed79ef&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Envoy vs NGINX vs HAProxy: Why the open source Ambassador API Gateway chose Envoy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.loggly.com/blog/benchmarking-5-popular-load-balancers-nginx-haproxy-envoy-traefik-and-alb/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Benchmarking 5 Popular Load Balancers: Nginx, HAProxy, Envoy, Traefik, and ALB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.katacoda.com/envoyproxy/scenarios/migrating-from-nginx-to-envoy&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Migrating from NGINX to Envoy Proxy by envoyproxy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;stats-prometheus-id_app_stats&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#stats-prometheus-id_app_stats&quot; aria-label=&quot;stats prometheus id_app_stats permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;stats prometheus {#ID_APP_STATS}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_http_downstream_rq_xx counter&lt;/span&gt;
envoy_listener_admin_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_listener_admin_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_downstream_cx_destroy counter&lt;/span&gt;
envoy_listener_admin_downstream_cx_destroy&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_downstream_cx_total counter&lt;/span&gt;
envoy_listener_admin_downstream_cx_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
envoy_listener_admin_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_downstream_pre_cx_timeout counter&lt;/span&gt;
envoy_listener_admin_downstream_pre_cx_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_http_downstream_rq_completed counter&lt;/span&gt;
envoy_listener_admin_http_downstream_rq_completed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_no_filter_chain_match counter&lt;/span&gt;
envoy_listener_admin_no_filter_chain_match&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_update_out_of_merge_window counter&lt;/span&gt;
envoy_cluster_manager_update_out_of_merge_window&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_flow_control_resumed_reading_total counter&lt;/span&gt;
envoy_http_downstream_flow_control_resumed_reading_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_http2_total counter&lt;/span&gt;
envoy_http_downstream_cx_http2_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_listener_added counter&lt;/span&gt;
envoy_listener_manager_listener_added&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_overload_close counter&lt;/span&gt;
envoy_http_downstream_rq_overload_close&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_listener_create_success counter&lt;/span&gt;
envoy_listener_manager_listener_create_success&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_http1_total counter&lt;/span&gt;
envoy_http_downstream_cx_http1_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_stats_overflow counter&lt;/span&gt;
envoy_stats_overflow&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_listener_create_failure counter&lt;/span&gt;
envoy_listener_manager_listener_create_failure&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_destroy_remote counter&lt;/span&gt;
envoy_http_downstream_cx_destroy_remote&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_non_relative_path counter&lt;/span&gt;
envoy_http_downstream_rq_non_relative_path&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_no_route counter&lt;/span&gt;
envoy_http_no_route&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;async-client&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_cluster_updated counter&lt;/span&gt;
envoy_cluster_manager_cluster_updated&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_rs_too_large counter&lt;/span&gt;
envoy_http_rs_too_large&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_tx_reset counter&lt;/span&gt;
envoy_http_downstream_rq_tx_reset&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_watchdog_mega_miss counter&lt;/span&gt;
envoy_server_watchdog_mega_miss&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_access_log_file_flushed_by_timer counter&lt;/span&gt;
envoy_access_log_file_flushed_by_timer&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_rx_bytes_total counter&lt;/span&gt;
envoy_http_downstream_cx_rx_bytes_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1029&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_flow_control_paused_reading_total counter&lt;/span&gt;
envoy_http_downstream_flow_control_paused_reading_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_completed counter&lt;/span&gt;
envoy_http_downstream_rq_completed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_listener_removed counter&lt;/span&gt;
envoy_listener_manager_listener_removed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_xx counter&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_access_log_file_reopen_failed counter&lt;/span&gt;
envoy_access_log_file_reopen_failed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_rq_direct_response counter&lt;/span&gt;
envoy_http_rq_direct_response&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;async-client&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_ws_on_non_ws_route counter&lt;/span&gt;
envoy_http_downstream_rq_ws_on_non_ws_route&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_cluster_updated_via_merge counter&lt;/span&gt;
envoy_cluster_manager_cluster_updated_via_merge&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_cluster_added counter&lt;/span&gt;
envoy_cluster_manager_cluster_added&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_runtime_override_dir_exists counter&lt;/span&gt;
envoy_runtime_override_dir_exists&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_http2_total counter&lt;/span&gt;
envoy_http_downstream_rq_http2_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_response_before_rq_complete counter&lt;/span&gt;
envoy_http_downstream_rq_response_before_rq_complete&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_listener_modified counter&lt;/span&gt;
envoy_listener_manager_listener_modified&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_runtime_deprecated_feature_use counter&lt;/span&gt;
envoy_runtime_deprecated_feature_use&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_idle_timeout counter&lt;/span&gt;
envoy_http_downstream_cx_idle_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_rq_redirect counter&lt;/span&gt;
envoy_http_rq_redirect&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;async-client&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_too_large counter&lt;/span&gt;
envoy_http_downstream_rq_too_large&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_protocol_error counter&lt;/span&gt;
envoy_http_downstream_cx_protocol_error&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_timeout counter&lt;/span&gt;
envoy_http_downstream_rq_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_runtime_override_dir_not_exists counter&lt;/span&gt;
envoy_runtime_override_dir_not_exists&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_runtime_load_error counter&lt;/span&gt;
envoy_runtime_load_error&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_access_log_file_write_completed counter&lt;/span&gt;
envoy_access_log_file_write_completed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_no_cluster counter&lt;/span&gt;
envoy_http_no_cluster&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;async-client&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_rq_reset_after_downstream_response_started counter&lt;/span&gt;
envoy_http_rq_reset_after_downstream_response_started&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;async-client&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_watchdog_miss counter&lt;/span&gt;
envoy_server_watchdog_miss&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_cluster_removed counter&lt;/span&gt;
envoy_cluster_manager_cluster_removed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_debug_assertion_failures counter&lt;/span&gt;
envoy_server_debug_assertion_failures&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_update_merge_cancelled counter&lt;/span&gt;
envoy_cluster_manager_update_merge_cancelled&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_overload_disable_keepalive counter&lt;/span&gt;
envoy_http_downstream_cx_overload_disable_keepalive&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_upgrades_total counter&lt;/span&gt;
envoy_http_downstream_cx_upgrades_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_tx_bytes_total counter&lt;/span&gt;
envoy_http_downstream_cx_tx_bytes_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5132&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_destroy counter&lt;/span&gt;
envoy_http_downstream_cx_destroy&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_destroy_local_active_rq counter&lt;/span&gt;
envoy_http_downstream_cx_destroy_local_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_drain_close counter&lt;/span&gt;
envoy_http_downstream_cx_drain_close&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_http1_total counter&lt;/span&gt;
envoy_http_downstream_rq_http1_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_destroy_active_rq counter&lt;/span&gt;
envoy_http_downstream_cx_destroy_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_access_log_file_write_buffered counter&lt;/span&gt;
envoy_access_log_file_write_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_destroy_local counter&lt;/span&gt;
envoy_http_downstream_cx_destroy_local&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_rq_total counter&lt;/span&gt;
envoy_http_rq_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;async-client&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_total counter&lt;/span&gt;
envoy_http_downstream_cx_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_total counter&lt;/span&gt;
envoy_http_downstream_rq_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_runtime_load_success counter&lt;/span&gt;
envoy_runtime_load_success&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_cluster_modified counter&lt;/span&gt;
envoy_cluster_manager_cluster_modified&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_rx_reset counter&lt;/span&gt;
envoy_http_downstream_rq_rx_reset&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_idle_timeout counter&lt;/span&gt;
envoy_http_downstream_rq_idle_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_delayed_close_timeout counter&lt;/span&gt;
envoy_http_downstream_cx_delayed_close_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_destroy_remote_active_rq counter&lt;/span&gt;
envoy_http_downstream_cx_destroy_remote_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_ssl_total counter&lt;/span&gt;
envoy_http_downstream_cx_ssl_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_idle_timeout counter&lt;/span&gt;
envoy_cluster_upstream_cx_idle_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_destroy_local counter&lt;/span&gt;
envoy_cluster_upstream_cx_destroy_local&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_close_notify counter&lt;/span&gt;
envoy_cluster_upstream_cx_close_notify&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_flow_control_paused_reading_total counter&lt;/span&gt;
envoy_cluster_upstream_flow_control_paused_reading_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_connect_timeout counter&lt;/span&gt;
envoy_cluster_upstream_cx_connect_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_xx counter&lt;/span&gt;
envoy_cluster_upstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;,envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_cancelled counter&lt;/span&gt;
envoy_cluster_upstream_rq_cancelled&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_overflow counter&lt;/span&gt;
envoy_cluster_upstream_cx_overflow&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_destroy_local_with_active_rq counter&lt;/span&gt;
envoy_cluster_upstream_cx_destroy_local_with_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_internal_redirect_succeeded_total counter&lt;/span&gt;
envoy_cluster_upstream_internal_redirect_succeeded_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_subsets_fallback counter&lt;/span&gt;
envoy_cluster_lb_subsets_fallback&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_zone_routing_sampled counter&lt;/span&gt;
envoy_cluster_lb_zone_routing_sampled&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_connect_attempts_exceeded counter&lt;/span&gt;
envoy_cluster_upstream_cx_connect_attempts_exceeded&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_per_try_timeout counter&lt;/span&gt;
envoy_cluster_upstream_rq_per_try_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_tx_bytes_total counter&lt;/span&gt;
envoy_cluster_upstream_cx_tx_bytes_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1065&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_flow_control_resumed_reading_total counter&lt;/span&gt;
envoy_cluster_upstream_flow_control_resumed_reading_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_original_dst_host_invalid counter&lt;/span&gt;
envoy_cluster_original_dst_host_invalid&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_subsets_created counter&lt;/span&gt;
envoy_cluster_lb_subsets_created&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_external_upstream_rq_completed counter&lt;/span&gt;
envoy_cluster_external_upstream_rq_completed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_rx_bytes_total counter&lt;/span&gt;
envoy_cluster_upstream_cx_rx_bytes_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;715&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_flow_control_backed_up_total counter&lt;/span&gt;
envoy_cluster_upstream_flow_control_backed_up_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_update_success counter&lt;/span&gt;
envoy_cluster_update_success&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_update_no_rebuild counter&lt;/span&gt;
envoy_cluster_update_no_rebuild&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;56&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_destroy_remote_with_active_rq counter&lt;/span&gt;
envoy_cluster_upstream_cx_destroy_remote_with_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_zone_cluster_too_small counter&lt;/span&gt;
envoy_cluster_lb_zone_cluster_too_small&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_zone_routing_all_directly counter&lt;/span&gt;
envoy_cluster_lb_zone_routing_all_directly&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_protocol_error counter&lt;/span&gt;
envoy_cluster_upstream_cx_protocol_error&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_external_upstream_rq_xx counter&lt;/span&gt;
envoy_cluster_external_upstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;,envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_external_upstream_rq counter&lt;/span&gt;
envoy_cluster_external_upstream_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;200&quot;&lt;/span&gt;,envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_completed counter&lt;/span&gt;
envoy_cluster_upstream_rq_completed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_update_attempt counter&lt;/span&gt;
envoy_cluster_update_attempt&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;58&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_recalculate_zone_structures counter&lt;/span&gt;
envoy_cluster_lb_recalculate_zone_structures&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_pending_overflow counter&lt;/span&gt;
envoy_cluster_upstream_rq_pending_overflow&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_bind_errors counter&lt;/span&gt;
envoy_cluster_bind_errors&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_retry_overflow counter&lt;/span&gt;
envoy_cluster_upstream_rq_retry_overflow&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq counter&lt;/span&gt;
envoy_cluster_upstream_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;200&quot;&lt;/span&gt;,envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_zone_number_differs counter&lt;/span&gt;
envoy_cluster_lb_zone_number_differs&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_none_healthy counter&lt;/span&gt;
envoy_cluster_upstream_cx_none_healthy&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_zone_no_capacity_left counter&lt;/span&gt;
envoy_cluster_lb_zone_no_capacity_left&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_update_failure counter&lt;/span&gt;
envoy_cluster_update_failure&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_timeout counter&lt;/span&gt;
envoy_cluster_upstream_rq_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_destroy_remote counter&lt;/span&gt;
envoy_cluster_upstream_cx_destroy_remote&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_max_requests counter&lt;/span&gt;
envoy_cluster_upstream_cx_max_requests&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_internal_redirect_failed_total counter&lt;/span&gt;
envoy_cluster_upstream_internal_redirect_failed_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_flow_control_drained_total counter&lt;/span&gt;
envoy_cluster_upstream_flow_control_drained_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_local_cluster_not_ok counter&lt;/span&gt;
envoy_cluster_lb_local_cluster_not_ok&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_rx_reset counter&lt;/span&gt;
envoy_cluster_upstream_rq_rx_reset&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_destroy counter&lt;/span&gt;
envoy_cluster_upstream_cx_destroy&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_subsets_selected counter&lt;/span&gt;
envoy_cluster_lb_subsets_selected&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_subsets_removed counter&lt;/span&gt;
envoy_cluster_lb_subsets_removed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_http1_total counter&lt;/span&gt;
envoy_cluster_upstream_cx_http1_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_connect_fail counter&lt;/span&gt;
envoy_cluster_upstream_cx_connect_fail&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_pending_total counter&lt;/span&gt;
envoy_cluster_upstream_rq_pending_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_zone_routing_cross_zone counter&lt;/span&gt;
envoy_cluster_lb_zone_routing_cross_zone&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_healthy_panic counter&lt;/span&gt;
envoy_cluster_lb_healthy_panic&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_total counter&lt;/span&gt;
envoy_cluster_upstream_cx_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_http2_total counter&lt;/span&gt;
envoy_cluster_upstream_cx_http2_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_destroy_with_active_rq counter&lt;/span&gt;
envoy_cluster_upstream_cx_destroy_with_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_total counter&lt;/span&gt;
envoy_cluster_upstream_rq_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_retry_success counter&lt;/span&gt;
envoy_cluster_upstream_rq_retry_success&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_subsets_fallback_panic counter&lt;/span&gt;
envoy_cluster_lb_subsets_fallback_panic&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_pending_failure_eject counter&lt;/span&gt;
envoy_cluster_upstream_rq_pending_failure_eject&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_membership_change counter&lt;/span&gt;
envoy_cluster_membership_change&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_retry counter&lt;/span&gt;
envoy_cluster_upstream_rq_retry&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_retry_or_shadow_abandoned counter&lt;/span&gt;
envoy_cluster_retry_or_shadow_abandoned&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_maintenance_mode counter&lt;/span&gt;
envoy_cluster_upstream_rq_maintenance_mode&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_tx_reset counter&lt;/span&gt;
envoy_cluster_upstream_rq_tx_reset&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_update_empty counter&lt;/span&gt;
envoy_cluster_update_empty&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_http_downstream_rq_xx counter&lt;/span&gt;
envoy_listener_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_downstream_cx_destroy counter&lt;/span&gt;
envoy_listener_downstream_cx_destroy&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_downstream_pre_cx_timeout counter&lt;/span&gt;
envoy_listener_downstream_pre_cx_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_http_downstream_rq_completed counter&lt;/span&gt;
envoy_listener_http_downstream_rq_completed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_no_filter_chain_match counter&lt;/span&gt;
envoy_listener_no_filter_chain_match&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_downstream_cx_total counter&lt;/span&gt;
envoy_listener_downstream_cx_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_tx_reset&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_destroy_remote_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_http1_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_overload_close&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_tracing_random_sampling counter&lt;/span&gt;
envoy_http_tracing_random_sampling&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_no_route&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_destroy_remote&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_protocol_error&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_response_before_rq_complete&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_rq_direct_response&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_flow_control_resumed_reading_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_destroy_local_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_http1_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_rq_reset_after_downstream_response_started&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_tracing_service_forced counter&lt;/span&gt;
envoy_http_tracing_service_forced&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_overload_disable_keepalive&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_ws_on_non_ws_route&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_rx_bytes_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;390&lt;/span&gt;
envoy_http_downstream_cx_idle_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_idle_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_rs_too_large&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_completed&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_no_cluster&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_destroy_local&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_rx_reset&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_rq_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_tracing_not_traceable counter&lt;/span&gt;
envoy_http_tracing_not_traceable&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_tx_bytes_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;840&lt;/span&gt;
envoy_http_downstream_cx_delayed_close_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_drain_close&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_flow_control_paused_reading_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_timeout&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_destroy&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_rq_redirect&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_tracing_health_check counter&lt;/span&gt;
envoy_http_tracing_health_check&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_ssl_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_too_large&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_tracing_client_enabled counter&lt;/span&gt;
envoy_http_tracing_client_enabled&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_xx&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_response_code_class&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4&quot;&lt;/span&gt;,envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_upgrades_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_http2_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_non_relative_path&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_http2_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_destroy_active_rq&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_downstream_pre_cx_active gauge&lt;/span&gt;
envoy_listener_admin_downstream_pre_cx_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_downstream_cx_active gauge&lt;/span&gt;
envoy_listener_admin_downstream_cx_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_active gauge&lt;/span&gt;
envoy_http_downstream_cx_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_total_listeners_draining gauge&lt;/span&gt;
envoy_listener_manager_total_listeners_draining&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_parent_connections gauge&lt;/span&gt;
envoy_server_parent_connections&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_runtime_admin_overrides_active gauge&lt;/span&gt;
envoy_runtime_admin_overrides_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_active_clusters gauge&lt;/span&gt;
envoy_cluster_manager_active_clusters&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_manager_warming_clusters gauge&lt;/span&gt;
envoy_cluster_manager_warming_clusters&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_total_listeners_active gauge&lt;/span&gt;
envoy_listener_manager_total_listeners_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_http1_active gauge&lt;/span&gt;
envoy_http_downstream_cx_http1_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_uptime gauge&lt;/span&gt;
envoy_server_uptime&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;140&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_memory_heap_size gauge&lt;/span&gt;
envoy_server_memory_heap_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5242880&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_days_until_first_cert_expiring gauge&lt;/span&gt;
envoy_server_days_until_first_cert_expiring&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2147483647&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_hot_restart_epoch gauge&lt;/span&gt;
envoy_server_hot_restart_epoch&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_total_connections gauge&lt;/span&gt;
envoy_server_total_connections&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_concurrency gauge&lt;/span&gt;
envoy_server_concurrency&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_version gauge&lt;/span&gt;
envoy_server_version&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15294198&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_memory_allocated gauge&lt;/span&gt;
envoy_server_memory_allocated&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3875056&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_rx_bytes_buffered gauge&lt;/span&gt;
envoy_http_downstream_cx_rx_bytes_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;513&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_access_log_file_write_total_buffered gauge&lt;/span&gt;
envoy_access_log_file_write_total_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_manager_total_listeners_warming gauge&lt;/span&gt;
envoy_listener_manager_total_listeners_warming&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_upgrades_active gauge&lt;/span&gt;
envoy_http_downstream_cx_upgrades_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_active gauge&lt;/span&gt;
envoy_http_downstream_rq_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_runtime_num_keys gauge&lt;/span&gt;
envoy_runtime_num_keys&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_tx_bytes_buffered gauge&lt;/span&gt;
envoy_http_downstream_cx_tx_bytes_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_server_live gauge&lt;/span&gt;
envoy_server_live&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_ssl_active gauge&lt;/span&gt;
envoy_http_downstream_cx_ssl_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_http2_active gauge&lt;/span&gt;
envoy_http_downstream_cx_http2_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_high_rq_retry_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_high_rq_retry_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_max_host_weight gauge&lt;/span&gt;
envoy_cluster_max_host_weight&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_default_cx_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_default_cx_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_high_rq_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_high_rq_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_default_rq_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_default_rq_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_membership_healthy gauge&lt;/span&gt;
envoy_cluster_membership_healthy&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_lb_subsets_active gauge&lt;/span&gt;
envoy_cluster_lb_subsets_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_default_rq_pending_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_default_rq_pending_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_active gauge&lt;/span&gt;
envoy_cluster_upstream_cx_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_pending_active gauge&lt;/span&gt;
envoy_cluster_upstream_rq_pending_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_version gauge&lt;/span&gt;
envoy_cluster_version&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_tx_bytes_buffered gauge&lt;/span&gt;
envoy_cluster_upstream_cx_tx_bytes_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_membership_total gauge&lt;/span&gt;
envoy_cluster_membership_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_default_rq_retry_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_default_rq_retry_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_default_cx_pool_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_default_cx_pool_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_high_rq_pending_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_high_rq_pending_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_membership_degraded gauge&lt;/span&gt;
envoy_cluster_membership_degraded&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_high_cx_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_high_cx_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_active gauge&lt;/span&gt;
envoy_cluster_upstream_rq_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_circuit_breakers_high_cx_pool_open gauge&lt;/span&gt;
envoy_cluster_circuit_breakers_high_cx_pool_open&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_rx_bytes_buffered gauge&lt;/span&gt;
envoy_cluster_upstream_cx_rx_bytes_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_downstream_pre_cx_active gauge&lt;/span&gt;
envoy_listener_downstream_pre_cx_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_downstream_cx_active gauge&lt;/span&gt;
envoy_listener_downstream_cx_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_upgrades_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_tx_bytes_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_http1_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_http2_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_rx_bytes_buffered&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_ssl_active&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_admin_downstream_cx_length_ms histogram&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_admin_downstream_cx_length_ms_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_rq_time histogram&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_http_downstream_rq_time_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_time_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_http_downstream_cx_length_ms histogram&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;admin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_connect_ms histogram&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_connect_ms_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_cx_length_ms histogram&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;25250&lt;/span&gt;
envoy_cluster_upstream_cx_length_ms_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_external_upstream_rq_time histogram&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17.200000000000002842170943040401&lt;/span&gt;
envoy_cluster_external_upstream_rq_time_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_cluster_upstream_rq_time histogram&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_cluster_upstream_rq_time_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17.200000000000002842170943040401&lt;/span&gt;
envoy_cluster_upstream_rq_time_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_cluster_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http_service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE envoy_listener_downstream_cx_length_ms histogram&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;28.6999999999999992894572642399&lt;/span&gt;
envoy_listener_downstream_cx_length_ms_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_listener_address&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0_9988&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_rq_time_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;19.25&lt;/span&gt;
envoy_http_downstream_rq_time_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;250&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;300000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1800000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3600000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
envoy_http_downstream_cx_length_ms_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;28.6999999999999992894572642399&lt;/span&gt;
envoy_http_downstream_cx_length_ms_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;envoy_http_conn_manager_prefix&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress_http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[gRPC Notes]]></title><link>https://xenojoshua.com/posts/2019/05/grpc-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/05/grpc-note</guid><pubDate>Mon, 06 May 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%9F%BA%E6%9C%AC%E8%B5%84%E6%96%99%E5%8F%8A%E7%BD%91%E7%BB%9C%E9%97%AE%E9%A2%98&quot;&gt;2. 基本资料及网络问题&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-go-support-for-protocol-buffers&quot;&gt;2.1 Go support for Protocol Buffers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-grpc-basics-go&quot;&gt;2.2 gRPC Basics: Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-grpc-enhanced-example&quot;&gt;2.3 gRPC enhanced example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#24-%E7%BD%91%E7%BB%9C%E9%97%AE%E9%A2%98&quot;&gt;2.4 网络问题&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B&quot;&gt;3. 并发编程&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-go%E8%AF%AD%E8%A8%80%E7%9A%84grpc%E5%B9%B6%E5%8F%91&quot;&gt;3.1 Go语言的gRPC并发&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E5%B9%B6%E5%8F%91%E7%9B%B8%E5%85%B3%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3-id_concurrency_doc&quot;&gt;3.2 并发相关官方文档 {#ID_CONCURRENCY_DOC}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#concurrency&quot;&gt;Concurrency&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#clients&quot;&gt;Clients&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#streams&quot;&gt;Streams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#servers&quot;&gt;Servers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E5%B9%B6%E5%8F%91%E8%8C%83%E4%BE%8B&quot;&gt;3.3 并发范例&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#331-%E4%BB%A3%E7%A0%81%E5%B7%AE%E5%BC%82&quot;&gt;3.3.1 代码差异&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#332-%E9%A1%BA%E5%BA%8F%E6%89%A7%E8%A1%8C&quot;&gt;3.3.2 顺序执行&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#333-%E5%B9%B6%E5%8F%91%E6%89%A7%E8%A1%8C&quot;&gt;3.3.3 并发执行&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-%E8%BF%9E%E6%8E%A5%E6%B1%A0&quot;&gt;3.4 连接池&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-benchmark&quot;&gt;3.5 Benchmark&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%B5%8B%E8%AF%95%E7%A1%AC%E4%BB%B6&quot;&gt;测试硬件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%8A%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%AF%E5%8A%A8%E5%91%BD%E4%BB%A4&quot;&gt;客户端及服务器启动命令&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%B5%8B%E8%AF%95%E7%BB%93%E6%9E%9C&quot;&gt;测试结果&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%BB%93%E8%AE%BA&quot;&gt;结论&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1&quot;&gt;4. 负载均衡&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E7%8A%B6%E6%80%81%E6%A3%80%E6%9F%A5&quot;&gt;5. 状态检查&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-interceptor&quot;&gt;6. Interceptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-debug&quot;&gt;7. Debug&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-%E7%9B%91%E6%8E%A7&quot;&gt;8. 监控&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;首先需要申明本文并不是通泛的对gRPC的讲解，而是以Golang为基础的一篇gRPC偏应用方向的博文。因此后面的所有技术点和使用范例都会以Go语言为基础。此外，本文中对gRPC偏基础方面的内容不会涉猎过多，而是更多讲解gRPC偏设计方向的技术点。&lt;/p&gt;
&lt;h1 id=&quot;2-基本资料及网络问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%9F%BA%E6%9C%AC%E8%B5%84%E6%96%99%E5%8F%8A%E7%BD%91%E7%BB%9C%E9%97%AE%E9%A2%98&quot; aria-label=&quot;2 基本资料及网络问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 基本资料及网络问题&lt;/h1&gt;
&lt;h2 id=&quot;21-go-support-for-protocol-buffers&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-go-support-for-protocol-buffers&quot; aria-label=&quot;21 go support for protocol buffers permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 Go support for Protocol Buffers&lt;/h2&gt;
&lt;p&gt;关于使用Go语言的情况下的一系列protobuf相关技术点，可以参阅：&lt;a href=&quot;https://github.com/golang/protobuf&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;golang/protobuf&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;主要需要关注的点有几个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装：除了标准的protobuf（protoc）之外，还需要安装go的插件：&lt;code class=&quot;language-text&quot;&gt;protoc-gen-go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;插件：protoc如果要使用go的插件，且需要生成service相关代码的话，需要在&lt;code class=&quot;language-text&quot;&gt;go_out&lt;/code&gt;中附带上&lt;code class=&quot;language-text&quot;&gt;plugins=grpc:&lt;/code&gt;字符串，e.g：&lt;code class=&quot;language-text&quot;&gt;--go_out=plugins=grpc:${OUTPUT_PATH}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;包管理：protobuf的包定义和go语言的习惯用法有不少差异，使用前建议阅读：&lt;a href=&quot;https://github.com/golang/protobuf#packages-and-input-paths&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Packages and input paths&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;默认的包名不会转换成相对文件夹，e.g：&lt;code class=&quot;language-text&quot;&gt;package com.book&lt;/code&gt;会生成&lt;code class=&quot;language-text&quot;&gt;com_book&lt;/code&gt;文件夹，而不是&lt;code class=&quot;language-text&quot;&gt;com/book&lt;/code&gt;这样的嵌套文件夹&lt;/li&gt;
&lt;li&gt;go的包路径可以使用：&lt;code class=&quot;language-text&quot;&gt;option go_package = ...&lt;/code&gt;来设定&lt;/li&gt;
&lt;li&gt;在某些全局编译的情况下，可以：&lt;code class=&quot;language-text&quot;&gt;--go_out=$GOPATH&lt;/code&gt;，直接输出到GOPATH&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;生成出来的代码相关规范：&lt;a href=&quot;https://github.com/golang/protobuf#generated-code&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Generated code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;protoc插件的额外参数：&lt;a href=&quot;https://github.com/golang/protobuf#parameters&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Parameters&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;22-grpc-basics-go&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-grpc-basics-go&quot; aria-label=&quot;22 grpc basics go permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 gRPC Basics: Go&lt;/h2&gt;
&lt;p&gt;初次使用Go语言来编写gRPC代码，请阅读文档：&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/gotutorial.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-go/examples/gotutorial.md&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;对于gRPC非常熟悉的程序员可以跳过这个文档，基本上这个文档是面向新手的指引，但是范例代码都使用的是Go语言。&lt;/p&gt;
&lt;h2 id=&quot;23-grpc-enhanced-example&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-grpc-enhanced-example&quot; aria-label=&quot;23 grpc enhanced example permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 gRPC enhanced example&lt;/h2&gt;
&lt;p&gt;进阶的Go语言gRPC代码可以阅读范例：&lt;a href=&quot;https://github.com/grpc/grpc-go/tree/master/examples/route_guide&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-go/examples/route_guide/&lt;/a&gt;。这个范例代码里加入了单向和双向流的范例，算是比较进阶和完整的范例代码了。&lt;/p&gt;
&lt;p&gt;我的实验项目中也有比较完整的应用范例代码，相对官方的范例来说少了点不伦不类的业务逻辑，对于只需要了解技术的读者来说更友好：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/experiment/grpc/samples/book&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/experiment/grpc/samples/book/&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;24-网络问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#24-%E7%BD%91%E7%BB%9C%E9%97%AE%E9%A2%98&quot; aria-label=&quot;24 网络问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4 网络问题&lt;/h2&gt;
&lt;p&gt;因国情原因，Go的包安装会遇到一些网络问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/issues/1959&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go get not working unrecognized import path “google.golang.org/grpc” #1959&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/issues/1780&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go get -u google.golang.org/grpc i/o timeout #1780&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种情况的最佳对应方法是在命令行下设置HTTP和HTTPS代理：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;http_proxy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://127.0.0.1:6152
&lt;span class=&quot;token builtin class-name&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;https_proxy&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;http://127.0.0.1:6152
go get &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-并发编程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B&quot; aria-label=&quot;3 并发编程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 并发编程&lt;/h1&gt;
&lt;h2 id=&quot;31-go语言的grpc并发&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-go%E8%AF%AD%E8%A8%80%E7%9A%84grpc%E5%B9%B6%E5%8F%91&quot; aria-label=&quot;31 go语言的grpc并发 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 Go语言的gRPC并发&lt;/h2&gt;
&lt;p&gt;关于在Go语言中使用gRPC的并发问题在官方的issues中已经有很多了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/issues/682&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Best practices for reusing connections, concurrency #682&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/issues/85&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Concurrency #85&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/issues/1345&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Add section on concurrency to documentation #1345&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上述的三个issues都可以仔细阅读下，提出的问题都非常有代表性。从一系列的问题中可以看出，官方对于gRPC的并发其实是有一些指导意见的，但并没有很好的文档化（至少之前如此）。而目前对这些问题已经有部分解答了，请继续阅读下去。&lt;/p&gt;
&lt;h2 id=&quot;32-并发相关官方文档-id_concurrency_doc&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E5%B9%B6%E5%8F%91%E7%9B%B8%E5%85%B3%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3-id_concurrency_doc&quot; aria-label=&quot;32 并发相关官方文档 id_concurrency_doc permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 并发相关官方文档 {#ID_CONCURRENCY_DOC}&lt;/h2&gt;
&lt;p&gt;在&lt;a href=&quot;https://github.com/grpc/grpc-go/pull/2034/files&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;这个提交&lt;/a&gt;中，官方添加了对于并发相关的官方指引。正式的文档地址是在：&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/Documentation/concurrency.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-go/Documentation/concurrency.md&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这里做下简单翻译：&lt;/p&gt;
&lt;h3 id=&quot;concurrency&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#concurrency&quot; aria-label=&quot;concurrency permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Concurrency&lt;/h3&gt;
&lt;p&gt;一般来说，gRPC-go提供了对并发友好的API。下文是一些指引。&lt;/p&gt;
&lt;h4 id=&quot;clients&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#clients&quot; aria-label=&quot;clients permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Clients&lt;/h4&gt;
&lt;p&gt;一个&lt;a href=&quot;https://godoc.org/google.golang.org/grpc#ClientConn&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ClientConn&lt;/a&gt;可以被安全地并发访问。以&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_client/main.go#L43&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;helloworld&lt;/a&gt;作为范例，程序员可以在多个goroutine之间共享一个ClientConn来创建多个GreeterClient客户端类型。在这种使用情况下，RPCs会并行传输。&lt;/p&gt;
&lt;h4 id=&quot;streams&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#streams&quot; aria-label=&quot;streams permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Streams&lt;/h4&gt;
&lt;p&gt;当使用&lt;a href=&quot;https://godoc.org/google.golang.org/grpc#Stream&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Stream&lt;/a&gt;的时候，程序员必须小心避免从不同的goroutine向同一个stream发送多次&lt;code class=&quot;language-text&quot;&gt;SendMsg&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;RecvMsg&lt;/code&gt;请求。换句话来说，如果有一个goroutine向stream中发送SendMsg，然后在同一时间有另一个goroutine向stream中发送RecvMsg，这样做是安全的。但在不同的goroutine中同时向同一个stream发送SendMsg，或是RecvMsg则是不安全的。&lt;/p&gt;
&lt;h4 id=&quot;servers&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#servers&quot; aria-label=&quot;servers permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Servers&lt;/h4&gt;
&lt;p&gt;每个被附到已注册服务器上的RPC处理器都会在其自身的goroutine中运作。举例来说，&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/helloworld/greeter_server/main.go#L41&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;SayHello&lt;/a&gt;会在其自身的goroutine中被调用到。同样的，streaming RPC也是一样，route guide例子可以在&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/route_guide/server/server.go#L126&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;这里&lt;/a&gt;看得到。&lt;/p&gt;
&lt;h2 id=&quot;33-并发范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E5%B9%B6%E5%8F%91%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;33 并发范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 并发范例&lt;/h2&gt;
&lt;p&gt;我在实验项目中做了点并发的范例，可以看下：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/experiment/grpc/samples/concurrency&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/experiment/grpc/samples/concurrency/&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;331-代码差异&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#331-%E4%BB%A3%E7%A0%81%E5%B7%AE%E5%BC%82&quot; aria-label=&quot;331 代码差异 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3.1 代码差异&lt;/h3&gt;
&lt;p&gt;服务端代码是一致的，根据&lt;a href=&quot;#ID_CONCURRENCY_DOC&quot;&gt;3.2 并发相关官方文档&lt;/a&gt;，服务端的所有请求都是自然并发的，无需代码特殊处理。但客户端则需要自行编码处理。&lt;/p&gt;
&lt;p&gt;顺序执行：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    start &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Echo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;pb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;EchoRequest&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[Client] singleConnSequence: err: %v&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        end &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        elapsed &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; end&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[Client] singleConnSequence: response: %v, consumed: %v&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; elapsed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;并发执行：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; waitgroup sync&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;WaitGroup

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    waitgroup&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;go&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        start &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Echo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ctx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;pb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;EchoRequest&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Fatalf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[Client] singleConnConcurrency: err: %v&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            end &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Now&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            elapsed &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; end&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sub&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;[Client] singleConnConcurrency: response: %v, consumed: %v&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; elapsed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        waitgroup&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Done&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
waitgroup&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Wait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;332-顺序执行&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#332-%E9%A1%BA%E5%BA%8F%E6%89%A7%E8%A1%8C&quot; aria-label=&quot;332 顺序执行 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3.2 顺序执行&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 启动服务器
DELAY_NO_5=true go run server.go

# 启动客户端，发送请求
MODE=CONN_ONE_SEQUENCE go run client.go&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 客户端输出
2019/05/03 13:58:23 [Client] singleConnSequence: response: id:1 , consumed: 4.284231ms
2019/05/03 13:58:23 [Client] singleConnSequence: response: id:2 , consumed: 381.818µs
2019/05/03 13:58:23 [Client] singleConnSequence: response: id:3 , consumed: 361.608µs
2019/05/03 13:58:23 [Client] singleConnSequence: response: id:4 , consumed: 332.662µs
2019/05/03 13:58:24 [Client] singleConnSequence: response: id:5 , consumed: 1.004485058s
2019/05/03 13:58:24 [Client] singleConnSequence: response: id:6 , consumed: 470.532µs
2019/05/03 13:58:24 [Client] singleConnSequence: response: id:7 , consumed: 468.148µs
2019/05/03 13:58:24 [Client] singleConnSequence: response: id:8 , consumed: 389.214µs
2019/05/03 13:58:24 [Client] singleConnSequence: response: id:9 , consumed: 418.01µs
2019/05/03 13:58:25 [Client] singleConnSequence: response: id:10 , consumed: 1.003602442s

# 服务器输出
2019/05/03 13:58:23 [Server] Echo: request: id:1
2019/05/03 13:58:23 [Server] Echo: response: id:1
2019/05/03 13:58:23 [Server] Echo: request: id:2
2019/05/03 13:58:23 [Server] Echo: response: id:2
2019/05/03 13:58:23 [Server] Echo: request: id:3
2019/05/03 13:58:23 [Server] Echo: response: id:3
2019/05/03 13:58:23 [Server] Echo: request: id:4
2019/05/03 13:58:23 [Server] Echo: response: id:4
2019/05/03 13:58:23 [Server] Echo: request: id:5
2019/05/03 13:58:24 [Server] Echo: response: id:5
2019/05/03 13:58:24 [Server] Echo: request: id:6
2019/05/03 13:58:24 [Server] Echo: response: id:6
2019/05/03 13:58:24 [Server] Echo: request: id:7
2019/05/03 13:58:24 [Server] Echo: response: id:7
2019/05/03 13:58:24 [Server] Echo: request: id:8
2019/05/03 13:58:24 [Server] Echo: response: id:8
2019/05/03 13:58:24 [Server] Echo: request: id:9
2019/05/03 13:58:24 [Server] Echo: response: id:9
2019/05/03 13:58:24 [Server] Echo: request: id:10
2019/05/03 13:58:25 [Server] Echo: response: id:10&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;333-并发执行&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#333-%E5%B9%B6%E5%8F%91%E6%89%A7%E8%A1%8C&quot; aria-label=&quot;333 并发执行 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3.3 并发执行&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 启动服务器
DELAY_NO_5=true go run server.go

# 启动客户端，发送请求
MODE=CONN_ONE_CONCURRENCY go run client.go&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# 客户端输出
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:9 , consumed: 5.651184ms
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:6 , consumed: 5.595945ms
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:2 , consumed: 5.693124ms
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:4 , consumed: 5.637734ms
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:1 , consumed: 5.592096ms
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:3 , consumed: 5.58596ms
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:7 , consumed: 5.652258ms
2019/05/03 13:54:41 [Client] singleConnConcurrency: response: id:8 , consumed: 5.658945ms
2019/05/03 13:54:42 [Client] singleConnConcurrency: response: id:10 , consumed: 1.008472004s
2019/05/03 13:54:42 [Client] singleConnConcurrency: response: id:5 , consumed: 1.008440948s

# 服务器输出
2019/05/03 13:54:41 [Server] Echo: request: id:3
2019/05/03 13:54:41 [Server] Echo: response: id:3
2019/05/03 13:54:41 [Server] Echo: request: id:1
2019/05/03 13:54:41 [Server] Echo: response: id:1
2019/05/03 13:54:41 [Server] Echo: request: id:6
2019/05/03 13:54:41 [Server] Echo: response: id:6
2019/05/03 13:54:41 [Server] Echo: request: id:10
2019/05/03 13:54:41 [Server] Echo: request: id:8
2019/05/03 13:54:41 [Server] Echo: response: id:8
2019/05/03 13:54:41 [Server] Echo: request: id:9
2019/05/03 13:54:41 [Server] Echo: response: id:9
2019/05/03 13:54:41 [Server] Echo: request: id:5
2019/05/03 13:54:41 [Server] Echo: request: id:2
2019/05/03 13:54:41 [Server] Echo: response: id:2
2019/05/03 13:54:41 [Server] Echo: request: id:4
2019/05/03 13:54:41 [Server] Echo: response: id:4
2019/05/03 13:54:41 [Server] Echo: request: id:7
2019/05/03 13:54:41 [Server] Echo: response: id:7
2019/05/03 13:54:42 [Server] Echo: response: id:10
2019/05/03 13:54:42 [Server] Echo: response: id:5&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;服务端对ID逢5的请求sleep 1秒进行反馈，因此并发的客户端请求中，5和10就是最后返回打印出来的，耗时也是1秒多。&lt;/p&gt;
&lt;h2 id=&quot;34-连接池&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-%E8%BF%9E%E6%8E%A5%E6%B1%A0&quot; aria-label=&quot;34 连接池 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 连接池&lt;/h2&gt;
&lt;p&gt;虽然单连接也是可以进行并发编程的，但在某些极端情况下，数据包可能达到网络吞吐的极限。众所周知Go语言天生对并发编程友好，因此CPU的利用必然是非常充分的，如果RPC服务的类型是低CPU消耗而高网络消耗的情况就有可能出现之前提到的问题。这种情况就需要创建多个连接了。&lt;/p&gt;
&lt;p&gt;在多连接管理方面，官方的类库并没有连接池的功能，第三方倒是有：&lt;a href=&quot;https://github.com/processout/grpc-go-pool/blob/master/pool_test.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-go-pool/pool_test.go&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;此外，可以拓展阅读：&lt;a href=&quot;https://mycodesmells.com/post/pooling-grpc-connections&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Pooling gRPC Connections&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;范例可以看：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/experiment/grpc/samples/pool&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/experiment/grpc/samples/pool/&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;35-benchmark&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#35-benchmark&quot; aria-label=&quot;35 benchmark permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.5 Benchmark&lt;/h2&gt;
&lt;p&gt;范例代码在：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/experiment/grpc/samples/throughput&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/golang/src/experiment/grpc/samples/throughput/&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;测试硬件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%B5%8B%E8%AF%95%E7%A1%AC%E4%BB%B6&quot; aria-label=&quot;测试硬件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;测试硬件&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;rMBP 2014 mid
CPU：2.5GHz 四核 Intel Core i7 处理器 (Turbo Boost 3.7GHz)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;测试的时候一些在系统使用中的软件我并没有清空，因此可能有稍许干扰，但总体问题不大。&lt;/p&gt;
&lt;h3 id=&quot;客户端及服务器启动命令&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%8A%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%90%AF%E5%8A%A8%E5%91%BD%E4%BB%A4&quot; aria-label=&quot;客户端及服务器启动命令 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;客户端及服务器启动命令&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;CORE_NUM=3 go run server.go
CORE_NUM=4 ROUTINES_PER_CORE=50 go run client.go&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;使用&lt;code class=&quot;language-text&quot;&gt;CORE_NUM&lt;/code&gt;来控制使用到的物理核心数量，客户端使用&lt;code class=&quot;language-text&quot;&gt;ROUTINES_PER_CORE&lt;/code&gt;来决定启动的routine总量：&lt;code class=&quot;language-text&quot;&gt;CORE_NUM * ROUTINES_PER_CORE&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&quot;测试结果&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%B5%8B%E8%AF%95%E7%BB%93%E6%9E%9C&quot; aria-label=&quot;测试结果 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;测试结果&lt;/h3&gt;
&lt;p&gt;请求数量/s：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;2019/05/04 14:19:33 [Client] 73065 requests in 1s
2019/05/04 14:19:34 [Client] 68826 requests in 1s
2019/05/04 14:19:35 [Client] 73655 requests in 1s
2019/05/04 14:19:36 [Client] 70973 requests in 1s
2019/05/04 14:19:37 [Client] 73645 requests in 1s
2019/05/04 14:19:38 [Client] 70616 requests in 1s
2019/05/04 14:19:39 [Client] 72252 requests in 1s
2019/05/04 14:19:40 [Client] 69342 requests in 1s
2019/05/04 14:19:41 [Client] 69745 requests in 1s
2019/05/04 14:19:42 [Client] 62251 requests in 1s
2019/05/04 14:19:43 [Client] 58043 requests in 1s
2019/05/04 14:19:44 [Client] 69316 requests in 1s
2019/05/04 14:19:45 [Client] 69796 requests in 1s
2019/05/04 14:19:46 [Client] 57246 requests in 1s
2019/05/04 14:19:47 [Client] 72265 requests in 1s
2019/05/04 14:19:48 [Client] 72940 requests in 1s
2019/05/04 14:19:49 [Client] 70237 requests in 1s&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;CPU：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/05/grpc-note/cpu.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Network：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/05/grpc-note/network-low.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2019/05/grpc-note/network-high.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;结论&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%BB%93%E8%AE%BA&quot; aria-label=&quot;结论 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;结论&lt;/h3&gt;
&lt;p&gt;因硬件环境的限制，没有使用通过网卡的测试方案，而是使用了127.0.0.1的环回请求方案。此外，测试期间MAC上的一些软件进程也并没有进行清理，因此可能有部分干扰。结论就不做了，这样简单且限制资源的benchmark实际意义不大，列几点可以观测到的状态：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;请求数量/s&lt;/code&gt;符合预期&lt;/li&gt;
&lt;li&gt;CPU占用基本满&lt;/li&gt;
&lt;li&gt;提升核心使用数量，提升routine数量，能观察到rps提升&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;4-负载均衡&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1&quot; aria-label=&quot;4 负载均衡 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 负载均衡&lt;/h1&gt;
&lt;p&gt;官方有一篇关于负载均衡设计的文档，可以读下：&lt;a href=&quot;https://github.com/grpc/grpc/blob/master/doc/load-balancing.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Load Balancing in gRPC&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;意义不大，可以了解一些简单的负载均衡概念，以及一些设计上的思路。&lt;/p&gt;
&lt;h1 id=&quot;5-状态检查&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E7%8A%B6%E6%80%81%E6%A3%80%E6%9F%A5&quot; aria-label=&quot;5 状态检查 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 状态检查&lt;/h1&gt;
&lt;p&gt;官方对于如何设计及暴露服务端状态检查接口的一份文档：&lt;a href=&quot;https://github.com/grpc/grpc/blob/master/doc/health-checking.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;GRPC Health Checking Protocol&lt;/a&gt;。可以说是一份guideline。同样意义不大。&lt;/p&gt;
&lt;h1 id=&quot;6-interceptor&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-interceptor&quot; aria-label=&quot;6 interceptor permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Interceptor&lt;/h1&gt;
&lt;p&gt;所谓的interceptor，写过gin或者koa的可以直接理解为gRPC里的&lt;code class=&quot;language-text&quot;&gt;middleware&lt;/code&gt;。官方文档：&lt;a href=&quot;https://github.com/grpc/grpc-go/tree/master/examples/features/interceptor&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Interceptor&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;虽然gRPC本身的rpc调用分为多种不同的可能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;请求响应皆为unary&lt;/li&gt;
&lt;li&gt;请求unary响应stream&lt;/li&gt;
&lt;li&gt;请求stream响应unary&lt;/li&gt;
&lt;li&gt;请求响应皆为stream&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但interceptor的签名则只有&lt;code class=&quot;language-text&quot;&gt;unary&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;stream&lt;/code&gt;这两种。&lt;/p&gt;
&lt;p&gt;范例代码可以查看官方的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/client/main.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;client/main.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/server/main.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;server/main.go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在使用中可能会遇到多个Interceptor同时存在的情况，在编码的时候就需要使用工具对其进行组合：&lt;a href=&quot;https://github.com/grpc-ecosystem/go-grpc-middleware/blob/master/chain.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go-grpc-middleware/chain.go&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;s &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; grpc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewServer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	grpc_middleware&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;WithUnaryServerChain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
		grpc_opentracing&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;UnaryServerInterceptor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		grpc_prometheus&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;UnaryServerInterceptor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	grpc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;StreamInterceptor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;grpc_prometheus&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;StreamServerInterceptor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;7-debug&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-debug&quot; aria-label=&quot;7 debug permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. Debug&lt;/h1&gt;
&lt;p&gt;官方的指引：&lt;a href=&quot;https://github.com/grpc/grpc-go/tree/master/examples/features/debugging&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Debugging&lt;/a&gt;，包括了一份范例代码：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/features/debugging/client/main.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;client/main.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/features/debugging/server/main.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;server/main.go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也可以使用go的trace包，做简单的观察：&lt;a href=&quot;https://segmentfault.com/a/1190000008087436&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang gRPC实践 连载六 内置Trace&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;几个环境变量可以大量输出程序执行的细节：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;GODEBUG=http2debug=1 \
GODEBUG=http2debug=2 \
GRPC_GO_LOG_VERBOSITY_LEVEL=99 \
GRPC_GO_LOG_SEVERITY_LEVEL=info \
yourapp&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;8-监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;8 监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. 监控&lt;/h1&gt;
&lt;p&gt;Grpc go自身也有监控用的Interceptor：&lt;a href=&quot;https://github.com/grpc-ecosystem/go-grpc-prometheus&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-ecosystem/go-grpc-prometheus&lt;/a&gt;，和HTTP服务器无关，主要是grpc自身的指标。&lt;/p&gt;
&lt;p&gt;范例代码可以参见README中的说明，服务端和客户端代码都有提供。&lt;/p&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/processout/grpc-go-pool/blob/master/pool_test.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-go-pool/pool_test.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mycodesmells.com/post/pooling-grpc-connections&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Pooling gRPC Connections&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Kafka Notes]]></title><link>https://xenojoshua.com/posts/2019/04/kafka-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/kafka-note</guid><pubDate>Mon, 29 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&quot;&gt;2. 消息队列&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E9%80%89%E5%9E%8B%E6%AF%94%E8%BE%83&quot;&gt;3. 消息队列选型比较&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-apache-pulsar&quot;&gt;3.1 Apache Pulsar&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-kafka%E6%9E%B6%E6%9E%84&quot;&gt;4. Kafka架构&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E6%A6%82%E5%BF%B5&quot;&gt;4.1 概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E9%9B%86%E7%BE%A4-id_cluster&quot;&gt;4.2 集群 {#ID_CLUSTER}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E5%88%86%E5%B8%83%E5%BC%8F%E7%97%9B%E7%82%B9offset&quot;&gt;4.3 分布式痛点（offset）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E4%B8%B4%E6%97%B6%E6%B6%88%E8%B4%B9%E5%8E%8B%E5%8A%9B%E5%BA%94%E6%80%A5&quot;&gt;4.4 临时消费压力应急&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-kafka%E7%9B%91%E6%8E%A7--%E9%AB%98%E5%8F%AF%E7%94%A8&quot;&gt;5. Kafka监控 &amp;#x26; 高可用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-%E7%9B%91%E6%8E%A7&quot;&gt;5.1 监控&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#511-exporter--grafana-dashboard&quot;&gt;5.1.1 Exporter &amp;#x26; Grafana Dashboard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#512-docker%E5%AE%9E%E8%B7%B5&quot;&gt;5.1.2 Docker实践&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E9%AB%98%E5%8F%AF%E7%94%A8&quot;&gt;5.2 高可用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-kafka-benchmark&quot;&gt;6. Kafka Benchmark&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-%E6%B5%8B%E8%AF%95%E7%8E%AF%E5%A2%83&quot;&gt;6.1 测试环境&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-%E4%B8%8D%E5%90%8C%E5%9C%BA%E6%99%AF%E6%B5%8B%E8%AF%95&quot;&gt;6.2 不同场景测试&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#621-%E5%9C%BA%E6%99%AF1&quot;&gt;6.2.1 场景1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#622-%E5%9C%BA%E6%99%AF2&quot;&gt;6.2.2 场景2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#623-%E5%9C%BA%E6%99%AF3&quot;&gt;6.2.3 场景3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#624-%E5%9C%BA%E6%99%AF4-id_benchmark_scen4&quot;&gt;6.2.4 场景4 {#ID_BENCHMARK_SCEN4}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#625-%E5%9C%BA%E6%99%AF5&quot;&gt;6.2.5 场景5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#626-%E5%9C%BA%E6%99%AF6&quot;&gt;6.2.6 场景6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#63-%E5%90%84%E5%9C%BA%E6%99%AF%E6%B5%8B%E8%AF%95%E6%80%BB%E7%BB%93&quot;&gt;6.3 各场景测试总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-kafka%E4%BD%BF%E7%94%A8%E8%8C%83%E4%BE%8B&quot;&gt;7. Kafka使用范例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-%E5%9C%A8docker%E5%86%85%E9%83%A8%E7%BD%B2%E9%9B%86%E7%BE%A4&quot;&gt;8. 在Docker内部署集群&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#81-%E9%87%8D%E8%A6%81%E9%85%8D%E7%BD%AE%E9%A1%B9&quot;&gt;8.1 重要配置项&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#82-%E5%AF%B9%E5%AE%B9%E5%99%A8%E5%A4%96%E5%BA%94%E7%94%A8%E6%8F%90%E4%BE%9B%E6%9C%8D%E5%8A%A1-docker_out_net&quot;&gt;8.2 对容器外应用提供服务 {#DOCKER_OUT_NET}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#83-docker-compose-scale&quot;&gt;8.3 docker-compose scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#84-yaml%E9%85%8D%E7%BD%AE%E9%87%8D%E7%94%A8&quot;&gt;8.4 yaml配置重用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#84-%E7%9B%B8%E5%85%B3%E5%8F%82%E8%80%83&quot;&gt;8.4 相关参考&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#9-%E5%86%99%E6%80%A7%E8%83%BD%E4%B8%8E%E5%AE%89%E5%85%A8%E6%80%A7&quot;&gt;9. 写性能与安全性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#10-todo&quot;&gt;10. TODO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Kafka是现在业界选择比较多的一种消息队列解决方案。我这里主要也是选Kafka作为消息队列这块需求的解决方案。下面的技术调研会先从消息队列本身开始，然后做一个横向比较，最后再聚焦到Kafka本身上。&lt;/p&gt;
&lt;p&gt;调研用的Kafka版本为：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;2.2.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;官方文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官方介绍：&lt;a href=&quot;https://kafka.apache.org/intro&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;官方新手入门：&lt;a href=&quot;https://kafka.apache.org/quickstart&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;官方应用场景介绍：&lt;a href=&quot;https://kafka.apache.org/uses&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Use cases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;官方文档：&lt;a href=&quot;https://kafka.apache.org/documentation/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docker Hub：&lt;a href=&quot;https://hub.docker.com/r/wurstmeister/kafka&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;wurstmeister/kafka&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一本中文手册，版本较老，看看范例代码尚可：&lt;a href=&quot;http://www.kubiji.cn/book/apache_kafka/APACHEKAFKAJiaoCheng/APACHEKAFKAGaiShu.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Apache kafka中文手册&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;2-消息队列&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&quot; aria-label=&quot;2 消息队列 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 消息队列&lt;/h1&gt;
&lt;p&gt;在聊Kafka之前，其实更需要关注下消息队列本身。什么需求下需要使用消息队列、消息队列的功能点有哪些、消息队列的模式有哪些、消息队列的实现难点有哪些，等等。如果什么都不了解，那技术选型就无从谈起了，也没办法理解为什么消息队列要做好是非常困难的一件事情。展开了说，也就没办法举一反三，理解其他软件系统的设计精髓了。&lt;/p&gt;
&lt;p&gt;下面会简单列举下消息队列的一系列知识点，细节内容这里就不展开了，篇幅太大。&lt;/p&gt;
&lt;p&gt;消息队列的需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;解耦&lt;/li&gt;
&lt;li&gt;最终一致性&lt;/li&gt;
&lt;li&gt;广播&lt;/li&gt;
&lt;li&gt;错峰与流控&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消息队列的模型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;点对点：单生产、单队列、单消费&lt;/li&gt;
&lt;li&gt;生产者消费者模型：多生产、单队列、多消费&lt;/li&gt;
&lt;li&gt;发布订阅模型：根据topic分队列，多生产、多队列、多消费&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消息队列的投递模式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Push：消息队列主动推送（e.g RocketMQ可选）&lt;/li&gt;
&lt;li&gt;Pull：消费者主动抓取（e.g Kafka）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消息队列的性能指标：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;吞吐量（Throughput）&lt;/li&gt;
&lt;li&gt;响应时间（Latency）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消息队列的投递策略：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最多一次（At most Once）：消息可能会丢，但绝不会重复传输&lt;/li&gt;
&lt;li&gt;最少一次（At least Once）：消息绝不会丢，但可能会重复传输&lt;/li&gt;
&lt;li&gt;仅有一次（Exactly Once）：每条消息肯定会被传输一次且仅传输一次&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;消息队列的功能性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优先级队列&lt;/li&gt;
&lt;li&gt;延迟队列&lt;/li&gt;
&lt;li&gt;死信队列&lt;/li&gt;
&lt;li&gt;重试队列&lt;/li&gt;
&lt;li&gt;消息回溯&lt;/li&gt;
&lt;li&gt;消息堆积 + 持久化&lt;/li&gt;
&lt;li&gt;消息追踪&lt;/li&gt;
&lt;li&gt;消息过滤&lt;/li&gt;
&lt;li&gt;多租户&lt;/li&gt;
&lt;li&gt;多协议支持&lt;/li&gt;
&lt;li&gt;跨语言支持&lt;/li&gt;
&lt;li&gt;流量控制&lt;/li&gt;
&lt;li&gt;可靠投递&lt;/li&gt;
&lt;li&gt;消费确认&lt;/li&gt;
&lt;li&gt;消息顺序性&lt;/li&gt;
&lt;li&gt;安全机制&lt;/li&gt;
&lt;li&gt;消息幂等性&lt;/li&gt;
&lt;li&gt;事务性消息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;几篇值得一读的博文：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/2019/04/message-queue-design/&quot;&gt;消息队列设计精要 - 美团点评技术团队&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;一篇通论形式的消息队列设计博文，讲解了一些消息队列通用的知识点，值得一读。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-01.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.infoq.cn/article/distributed-queue-programme-model-actual-combat-optimization&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;分布式队列编程：从模型、实战到优化&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本质上也是一篇对于消息队列进行设计和讲解的博文，但结合了美团公司内部的实际项目经验，对于大型系统的设计者有更好的贴近应用场景的指导作用。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&amp;#x26;mid=2651745361&amp;#x26;idx=1&amp;#x26;sn=5f0f67484a0de4b0dd2796848ef9cc94&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;分布式队列编程优化篇&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;接上一篇的博文，更多讲到了性能和高级功能相关的实现以及性能的优化。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jianshu.com/p/7a6deaba34d2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;如何保证消息队列的高可用和幂等性以及数据丢失，顺序一致性&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;排版比较粗糙，但内容非常不错。以贴近项目经验的内容讲解了RabbitMQ和Kafka的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高可用性&lt;/li&gt;
&lt;li&gt;消息幂等性&lt;/li&gt;
&lt;li&gt;消息可靠性&lt;/li&gt;
&lt;li&gt;消息顺序性&lt;/li&gt;
&lt;li&gt;消息积压场景处理&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-消息队列选型比较&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97%E9%80%89%E5%9E%8B%E6%AF%94%E8%BE%83&quot; aria-label=&quot;3 消息队列选型比较 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 消息队列选型比较&lt;/h1&gt;
&lt;p&gt;消息队列的选型一直都是比较困难的，业界现在比较主流的选择有：ActiveMQ、RabbitMQ、Kafka、RocketMQ、ZeroMQ 这几种。&lt;/p&gt;
&lt;p&gt;有几篇不错的博文可以看下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.infoq.cn/article/kafka-vs-rabbitmq&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;消息中间件选型分析：从 Kafka 与 RabbitMQ 的对比看全局&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这篇时间还算比较接近&lt;code class=&quot;language-text&quot;&gt;2018年5月2日&lt;/code&gt;，主要是以Kafka和RabbitMQ为范例进行了消息队列选型的要点讲解。虽然讲解的时候使用了Kafka以及RabbitMQ作为范例，但实际上讲解的是通用的消息队列选型要点。结合本文上一节所讲到的消息队列的一系列知识点，应该能有更深刻的理解。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-02.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-03.jpg&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-04.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.infoq.cn/article/dXJ3EYIp*WaHfmVwlMeu&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;滴滴出行基于 RocketMQ 构建企业级消息队列服务的实践&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这篇时间稍微有点久，文中提到的Kafka版本还是0.8左右的（虽然文章的发布时间倒是不久之前），所以文中提到的性能指标之类的仅可作为参考。这篇文章是对Kafka和RocketMQ做的一个技术选型比较，文章中有相当多的性能指标比较，并结合滴滴公司的实际情况讲解了下消息队列系统进行替换时候所做的Migration工作，非常有借鉴价值。此外，文中还有一小节讲解了下RocketMQ使用的经验。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/39586635/why-is-kafka-pull-based-instead-of-push-based&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Why is Kafka pull-based instead of push-based?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;为什么Kafka消息队列使用的是Pull投递模式。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.com/@philipfeng/modern-open-source-messaging-apache-kafka-rabbitmq-nats-pulsar-and-nsq-ca3bf7422db5&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Modern Open Source Messaging: NATS, RabbitMQ, Apache Kafka, hmbdc, Synapse, NSQ and Pulsar&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;老外写的一篇，提到了不少国内较少提到的开源项目，可以作为参考。&lt;/p&gt;
&lt;h2 id=&quot;31-apache-pulsar&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-apache-pulsar&quot; aria-label=&quot;31 apache pulsar permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 Apache Pulsar&lt;/h2&gt;
&lt;p&gt;关于Kafka和后起新秀Pulsar的横向比较，可以看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/47388267&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;比拼Kafka，大数据分析新秀Pulsar到底好在哪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/merlimat/high-performance-messaging-with-apache-pulsar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;High performance messaging with Apache Pulsar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/Us*a8umKXT9LpV9hA6tF&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;选择 Pulsar 而不是 Kafka 的 7 大理由&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大略的要点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能性上Pulsar要比Kafka更好，且这是在不牺牲性能的前提下的，就更加难能可贵&lt;/li&gt;
&lt;li&gt;解决了Kafka单partition只能单consumer消费的问题&lt;/li&gt;
&lt;li&gt;将Broker和存储解耦，做到更好的错误恢复，在Broker宕机之后可以做到无损耗恢复&lt;/li&gt;
&lt;li&gt;存储方面的功能交付给Bookie，更细粒度的存储，更好的错误恢复和同步性能&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;4-kafka架构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-kafka%E6%9E%B6%E6%9E%84&quot; aria-label=&quot;4 kafka架构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Kafka架构&lt;/h1&gt;
&lt;h2 id=&quot;41-概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;41 概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 概念&lt;/h2&gt;
&lt;p&gt;老样子从基本的概念开始梳理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;broker&lt;/code&gt;：kafka集群中的任意一台提供服务的物理服务器即被称为broker&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;topic&lt;/code&gt;：消息队列的一个队列，一般做架构的时候按需求将不同的消息分别派送到不同的管道里，而其中的任意一个管道在kafka里就是一个topic&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;partition&lt;/code&gt;：topic下的概念，任意一个topic根据启动时的设定，会分成多个partition，而每个partition会由集群安排在某一台物理机broker上，以此做到集群的横向扩展&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;offset&lt;/code&gt;：partition下的概念，topic被分为很多partition，而每个partition则都会存储消息，每个partition存储的消息都是从0开始进行标号，而这个每条消息一个的标号，即为offset；可以理解为消息在partition里的唯一id；不同的partition都是从0开始标号，因此offset只对其自身的partition生效，不可混用&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;replica&lt;/code&gt;：某个partition的完整备份（在接收写入请求时数据可能会落后于leader），用在集群的高可用服务上，同时也可以提供partition读操作的负载均衡&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;producer&lt;/code&gt;：向topic里输入消息数据的角色&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;consumer&lt;/code&gt;：从topic里消费消息数据的角色&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;consumer group&lt;/code&gt;：可扩展且具有容错性的consumer机制，多个consumer共享一个group id，组内的所有consumer一起来消费topic的所有partition；但一个partition仍旧只能由一个consumer进行消费；主要是为了解决consumer和partition配对balance的问题，将consumer做成组由集群自动进行平衡并分配到partition&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于consumer group，更多的可以看：&lt;a href=&quot;https://www.cnblogs.com/huxi2b/p/6223228.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kafka消费组(consumer group)&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;42-集群-id_cluster&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-%E9%9B%86%E7%BE%A4-id_cluster&quot; aria-label=&quot;42 集群 id_cluster permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 集群 {#ID_CLUSTER}&lt;/h2&gt;
&lt;p&gt;一张图基本上就能说明问题：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-05.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kafka集群由多台broker（物理机）组成&lt;/li&gt;
&lt;li&gt;图示中有&lt;code class=&quot;language-text&quot;&gt;四台&lt;/code&gt;broker&lt;/li&gt;
&lt;li&gt;每个topic会根据配置，生成固定数量的partition，均匀分配到物理机上&lt;/li&gt;
&lt;li&gt;图示中的topic被分成了&lt;code class=&quot;language-text&quot;&gt;3个&lt;/code&gt;partition：&lt;code class=&quot;language-text&quot;&gt;P1_leader&lt;/code&gt;（broker1）、&lt;code class=&quot;language-text&quot;&gt;P2_leader&lt;/code&gt;（broker2）、&lt;code class=&quot;language-text&quot;&gt;P3_leader&lt;/code&gt;（broker4）&lt;/li&gt;
&lt;li&gt;每个partition根据配置，会拥有固定数量的follower（replica），分别分配到各个物理机上&lt;/li&gt;
&lt;li&gt;图示中即：&lt;code class=&quot;language-text&quot;&gt;P1_follower&lt;/code&gt;（broker2、broker3）、&lt;code class=&quot;language-text&quot;&gt;P2_follower&lt;/code&gt;（broker3、broker4）、&lt;code class=&quot;language-text&quot;&gt;P3_follower&lt;/code&gt;（broker1、broker2）&lt;/li&gt;
&lt;li&gt;当有broker宕机的时候：
&lt;ul&gt;
&lt;li&gt;丢失的follower会由集群重新寻找节点进行备份&lt;code class=&quot;language-text&quot;&gt;恢复&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;丢失的leader会由集群自现存的follower中&lt;code class=&quot;language-text&quot;&gt;选举&lt;/code&gt;产生，成为新的leader&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;43-分布式痛点offset&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E5%88%86%E5%B8%83%E5%BC%8F%E7%97%9B%E7%82%B9offset&quot; aria-label=&quot;43 分布式痛点offset permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 分布式痛点（offset）&lt;/h2&gt;
&lt;p&gt;Kafka在分布式解决方案上也有痛点，主要是每个partition的offset问题。&lt;/p&gt;
&lt;p&gt;为了性能，kafka将一个partition视作一个管道，拥有一个从0开始的offset。这样做的好处就是不再需要在每一个消息体上做metadata存放该消息是否被消费掉等信息，而是通过partition的offset来标记整个管道中的消息被消费到了哪里。消息体更简单，流程上也更简单，不会出现乱序的消费情况。但也正是因为这种设计，导致每个partition无法由多个consumer并发消费，每个partition绑定只能同时允许一个consumer消费。&lt;/p&gt;
&lt;p&gt;因此，从机制上来说，kafka并不适合用来做consumer重消耗（CPU）类型的消息通道。虽然partition可以做很多，极端点来说可以做到和consumer实际需求1：1的配比，但超过适配当前需求的partition数量设置也会造成吞吐量的下降（参见：&lt;a href=&quot;#ID_BENCHMARK_SCEN4&quot;&gt;6.2.4 场景4&lt;/a&gt;）。&lt;/p&gt;
&lt;p&gt;consumer和partition在进行消息是否被消费掉的确认行为上，有两种方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自动提交：
&lt;ul&gt;
&lt;li&gt;设置&lt;code class=&quot;language-text&quot;&gt;enable.auto.commit=true&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;更新的频率根据参数&lt;code class=&quot;language-text&quot;&gt;auto.commit.interval.ms&lt;/code&gt;来定，这种方式被称为&lt;code class=&quot;language-text&quot;&gt;at most once&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;consumer fetch到消息后，partition就会更新offset，无论是否消费成功&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;手动提交：
&lt;ul&gt;
&lt;li&gt;设置&lt;code class=&quot;language-text&quot;&gt;enable.auto.commit=false&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;这种方式被称为&lt;code class=&quot;language-text&quot;&gt;at least once&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;consumer fetch到消息后，必须在消费成功后调用方法&lt;code class=&quot;language-text&quot;&gt;consumer.commitSync()&lt;/code&gt;，手动通知partition更新offset&lt;/li&gt;
&lt;li&gt;如果消费失败，则offset不会更新，此条消息会被重复消费一次&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于partition和consumer之间的关系，更多可以看下：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://stackoverflow.com/questions/45175424/how-multiple-consumer-group-consumers-work-across-partition-on-the-same-topic-in&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How multiple consumer group consumers work across partition on the same topic in Kafka?&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you want to have more consumers than partitions and still have performance enhancement and process only each message once, then you should increase the number of partitions in the topics so that there are at least as many partitions as consumers. Often topics are created with 2 times as many partitions needed to start, just so more consumers can be added later if needed without having to repartition the topic.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.csdn.net/pursuer211/article/details/79799478&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;kafka中partition和消费者对应关系&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;1个partition只能被同组的一个consumer消费，同组的consumer则起到均衡效果&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;以及自动提交相关：&lt;a href=&quot;https://medium.com/@danieljameskay/understanding-the-enable-auto-commit-kafka-consumer-property-12fa0ade7b65&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Understanding the ‘enable.auto.commit’ Kafka Consumer property&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;44-临时消费压力应急&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E4%B8%B4%E6%97%B6%E6%B6%88%E8%B4%B9%E5%8E%8B%E5%8A%9B%E5%BA%94%E6%80%A5&quot; aria-label=&quot;44 临时消费压力应急 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 临时消费压力应急&lt;/h2&gt;
&lt;p&gt;如果因某些原因，之前设计的partition分片数量不够导致能够上工的consumer数量不够，且consumer的消费速率跟不上的时候，就会发生消息堆积。如果堆积的情况比较严重的话，就需要程序介入处理。&lt;/p&gt;
&lt;p&gt;思路如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;老的partition以及老的topic肯定不能动，就算重新进行repartition整个集群重新平衡耗费的时间也是难以忍受的&lt;/li&gt;
&lt;li&gt;创建新的topic&lt;/li&gt;
&lt;li&gt;将新的topic的partition设到consumer消费速率能跟上的数量&lt;/li&gt;
&lt;li&gt;将新的consumer部署上去，消费新设置的topic和partition&lt;/li&gt;
&lt;li&gt;将老的topic以及partition上挂载的consumer全部停止&lt;/li&gt;
&lt;li&gt;在老的topic以及partition上挂载临时consumer，这批consumer不做任何逻辑处理，只是将老的topic内的消息全部读取出来，并输入到新的topic里&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样老的topic里的消息就全部分发到新的topic里了，且新的topic的partition数量很高，可以挂载很多consumer处理堆积的消息。&lt;/p&gt;
&lt;h1 id=&quot;5-kafka监控--高可用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-kafka%E7%9B%91%E6%8E%A7--%E9%AB%98%E5%8F%AF%E7%94%A8&quot; aria-label=&quot;5 kafka监控  高可用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Kafka监控 &amp;#x26; 高可用&lt;/h1&gt;
&lt;h2 id=&quot;51-监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;51 监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 监控&lt;/h2&gt;
&lt;p&gt;监控方面，datadog的几篇文章非常不错，值得一读，不过版本有点老了，文章是2016年的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.datadoghq.com/blog/monitoring-kafka-performance-metrics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Monitoring Kafka performance metrics - P1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.datadoghq.com/blog/collecting-kafka-performance-metrics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Monitoring Kafka performance metrics - P2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详细的指标列表及其含义，可以看这篇：&lt;a href=&quot;https://docs.confluent.io/current/kafka/monitoring.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Monitoring Kafka&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;511-exporter--grafana-dashboard&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#511-exporter--grafana-dashboard&quot; aria-label=&quot;511 exporter  grafana dashboard permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1.1 Exporter &amp;#x26; Grafana Dashboard&lt;/h3&gt;
&lt;p&gt;Prometheus的Exporter分为两块：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;以Java为runtime的通用监控：prometheus/jmx_exporter
&lt;ul&gt;
&lt;li&gt;代码：&lt;a href=&quot;https://github.com/prometheus/jmx_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus/jmx_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;镜像：&lt;a href=&quot;https://hub.docker.com/r/sscaling/jmx-prometheus-exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;sscaling/jmx-prometheus-exporter&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;sscaling/jmx-prometheus-exporter:0.11.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/dashboards/721&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kafka Overview&lt;/a&gt;，这个dashboard相当老了，一直没有更新，而且仅只有6个Panel，和kafka有关的panel更只有3个，基本没什么用；但未能找到更近一点的kafka专用dashboard&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/dashboards/8563&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;JVM dashboard&lt;/a&gt;，jmx通用dashboard，看上去更好点；但这个dashboard变量设置的是job，所以在设置Prometheus的时候就需要将多个kafka的数据采集到同一个job里，而不是分开&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/dashboards/7727&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;JMX exporter prometheus&lt;/a&gt;，另一款jmx通用dashboard；这个dashboard是为了在k8s中使用而特化的，也不够灵活&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;列在Prometheus官方列表上的第三方Exporter：danielqsj/kafka_exporter
&lt;ul&gt;
&lt;li&gt;代码：&lt;a href=&quot;https://github.com/danielqsj/kafka_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;danielqsj/kafka_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;镜像：&lt;a href=&quot;https://hub.docker.com/r/danielqsj/kafka-exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;danielqsj/kafka-exporter&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;danielqsj/kafka-exporter:v1.2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard：&lt;a href=&quot;https://grafana.com/dashboards/7589&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kafka Exporter Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;该Exporter使用Golang编写，更专注于部分Kafka业务相关metrics，对于核心的Java runtime metrics仍旧需要jmx_exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，还有一个confluent公司的grafana dashboard配置，没找到对应的labs dashboard地址，但该配置文件本身也有参考价值：&lt;a href=&quot;https://github.com/kubernauts/kafka-confluent-platform/blob/master/grafana-kafka-dashboard.json&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;kafka-confluent-platform/grafana-kafka-dashboard.json&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;可参考的jmx_exporter配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/oded-dd/prometheus-jmx-kafka&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;oded-dd/prometheus-jmx-kafka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Mousavi310/kafka-grafana&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Mousavi310/kafka-grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;512-docker实践&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#512-docker%E5%AE%9E%E8%B7%B5&quot; aria-label=&quot;512 docker实践 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1.2 Docker实践&lt;/h3&gt;
&lt;p&gt;实际运行范例参见：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/conf/dev/kafka-cluster.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/conf/dev/kafka-cluster.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/conf/dev/prometheus-cluster.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/conf/dev/prometheus-cluster.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/dist-system-practice/vendors/kafka&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/vendors/kafka/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/golang/src/dist-system-practice/vendors/prometheus/grafana/dashboards&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/vendors/prometheus/grafana/dashboards/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Exporter方面，jmx_exporter和kafka_exporter同时使用，两者侧重不同。jmx_exporter主要用来进行JVM监控，针对java runtime自身的状态进行监控，而kafka_exporter则针对kafka运行状况进行监控（其实只要不怕麻烦自己处理dashboard，则jmx_exporter就完全足够了）。&lt;/p&gt;
&lt;p&gt;jmx_exporter的部署有两种选择，一是独立的容器进行部署，好处是可观察性强，且不会对kafka容器造成影响，缺点是部署更繁杂，配置内容更多；二是修改kafka容器，添加几项配置项，就可以直接在kafka容器内启动一个java进程，进行metrics输出。这里实践使用的是第二种方法，配置修改如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;  &lt;span class=&quot;token key atrule&quot;&gt;kafka_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /private/tmp/jmx_prometheus_javaagent&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;0.9.jar&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/usr/local/bin/jmx_prometheus_javaagent&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;0.9.jar
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /private/tmp/jmx&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;kafka&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;2_0_0.yaml&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/etc/jmx&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;exporter/jmx&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;kafka&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;2_0_0.yaml
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19092:9092&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# client port&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17071:7071&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# jmx prometheus metrics&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9092&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# client port&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9093&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# internal traffic&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9991&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# jmx&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;7071&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# jmx prometheus metrics&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;always&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*KAFKA_LOGGING_DEFAULTS&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;JMX_PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9991&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_OPTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-javaagent:/usr/local/bin/jmx_prometheus_javaagent-0.9.jar=7071:/etc/jmx-exporter/jmx-kafka-2_0_0.yaml&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*KAFKA_ENV_DEFAULTS&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;JMX_PORT&lt;/code&gt;告知kafka在启动的时候需要一并启动jmx，&lt;code class=&quot;language-text&quot;&gt;KAFKA_OPTS&lt;/code&gt;告知kafka在启动时一并需要启动jmx_exporter，而这个exporter的jar包以及配置文件则是通过bind mount放入容器内的。&lt;/p&gt;
&lt;p&gt;配置文件主要来自于：&lt;a href=&quot;https://github.com/Mousavi310/kafka-grafana/blob/master/jmx-exporter/kafka-2_0_0.yml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;kafka-grafana/jmx-exporter/kafka-2_0_0.yml&lt;/a&gt;。此外，因为使用通用jmx dashboard：&lt;a href=&quot;https://grafana.com/dashboards/8563&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;JVM dashboard&lt;/a&gt;来进行数据展示，该配置文件中也放入了部分这个dashboard要求的数据转换规则：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;lowercaseOutputLabelNames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;rules&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# JMX common&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;pattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;java.lang&amp;lt;type=OperatingSystem&gt;&amp;lt;&gt;(committed_virtual_memory|free_physical_memory|free_swap_space|total_physical_memory|total_swap_space)_size:&apos;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; os_$1_bytes
  &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; GAUGE
  &lt;span class=&quot;token key atrule&quot;&gt;attrNameSnakeCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;pattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;java.lang&amp;lt;type=OperatingSystem&gt;&amp;lt;&gt;((?!process_cpu_time)\w+):&apos;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; os_$1
  &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; GAUGE
  &lt;span class=&quot;token key atrule&quot;&gt;attrNameSnakeCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;此外还有prometheus集群采集添加以及grafana dashboard导入，都是常规操作，就不多说了。&lt;/p&gt;
&lt;h2 id=&quot;52-高可用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E9%AB%98%E5%8F%AF%E7%94%A8&quot; aria-label=&quot;52 高可用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 高可用&lt;/h2&gt;
&lt;p&gt;在之前的&lt;a href=&quot;#ID_CLUSTER&quot;&gt;4.2 集群&lt;/a&gt;中，已经介绍过了Kafka的集群模式，可以看到Kafka天然就是分布式的，而且在设计之初就考虑到了集群的高可用。本文之前章节内关于集群的内容偏简单了，只介绍了大致的设计。如有需要更深入了解分布式和高可用的细节，则可以阅读唯品会的：&lt;a href=&quot;https://www.infoq.cn/article/depth-interpretation-of-kafka-data-reliability&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kafka 数据可靠性深度解读&lt;/a&gt;，这篇讲解非常透彻，基本上可以当经典来看了。&lt;/p&gt;
&lt;p&gt;Kafka的高可用配置，有几个配置项控制了集群的安全程度。这里需要记住一点，整个集群越安全集群的吞吐量就越低，这是等价交换的，不可能不付出任何代价就获得数据的安全性。唯品会的文章讲解的细节非常多，但我们真正执行操作的时候可以只知其然，懂得哪几个配置项需要操作即可：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;topic：
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;replication.factor&lt;/code&gt;：每个partition会拥有多少个replica&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;min.insync.replicas&lt;/code&gt;：partition的leader节点要求当前在线的replica节点的数量，如果实际在线数量少于这个数值，客户端的请求会被拒绝：&lt;code class=&quot;language-text&quot;&gt;org.apache.kafka.common.errors.NotEnoughReplicasExceptoin: Messages are rejected since there are fewer in-sync replicas than required&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;broker：
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;unclean.leader.election.enable&lt;/code&gt;：是否允许out-of-sync replica成为leader&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;producer：
&lt;ul&gt;
&lt;li&gt;producer.type：消息生产者提交消息到kafka服务器的时候的模式，可选：sync或async
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sync&lt;/code&gt;拥有很好的安全性&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;async&lt;/code&gt;拥有更高的吞吐量，可以批量进行消息发送&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;request.required.acks：kafka服务器在收到消息之后何时对生产者进行完成反馈
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;1（默认）&lt;/code&gt;：partition的leader节点收取完成即反馈，如果在follower同步数据之前leader宕机则数据丢失&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt;：producer不等待kafka服务器反馈即直接进行后续发送，拥有最高的吞吐量以及最低的安全性&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;-1&lt;/code&gt;：partition的所有节点包括了leader以及所有的follower全部都确认数据同步完成再反馈，最高的安全性以及最低的吞吐量&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要保证数据写入到Kafka是安全的，高可靠的，需要如下配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;topic：
&lt;ul&gt;
&lt;li&gt;replication.factor&gt;=3：即副本数至少是3个&lt;/li&gt;
&lt;li&gt;2&amp;#x3C;=min.insync.replicas&amp;#x3C;=replication.factor：要求每个partition leader的在线replica数量最少保持2个&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;broker：
&lt;ul&gt;
&lt;li&gt;unclean.leader.election.enable=false：不允许out-of-sync replica成为leader&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;producer：
&lt;ul&gt;
&lt;li&gt;request.required.acks=-1(all)：producer发送的消息请求必须让partition所有的replica都同步完毕才会返回成功&lt;/li&gt;
&lt;li&gt;producer.type=sync：producer发送的消息以同步方式发送，即在写入成功之前，producer必须等待&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;6-kafka-benchmark&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-kafka-benchmark&quot; aria-label=&quot;6 kafka benchmark permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Kafka Benchmark&lt;/h1&gt;
&lt;p&gt;这里的内容全部是转载自唯品会的：&lt;a href=&quot;https://www.infoq.cn/article/depth-interpretation-of-kafka-data-reliability&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kafka 数据可靠性深度解读&lt;/a&gt;。网上的资料很容易失效，因此在这里做下转载。&lt;/p&gt;
&lt;p&gt;Benchmark的Kafka版本是：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;0.10.1.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;61-测试环境&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-%E6%B5%8B%E8%AF%95%E7%8E%AF%E5%A2%83&quot; aria-label=&quot;61 测试环境 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 测试环境&lt;/h2&gt;
&lt;p&gt;Kafka broker 用到了 4 台机器，分别为 broker[0/1/2/3] 配置如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: 24core/2.6GHZ&lt;/li&gt;
&lt;li&gt;Memory: 62G&lt;/li&gt;
&lt;li&gt;Network: 4000Mb&lt;/li&gt;
&lt;li&gt;OS/kernel: CentOs release 6.6 (Final)&lt;/li&gt;
&lt;li&gt;Disk: 1089G&lt;/li&gt;
&lt;li&gt;Kafka 版本：0.10.1.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;broker 端 JVM 参数设置：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;-Xmx8G -Xms8G -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+CMSScavengeBeforeRemark -XX:+DisableExplicitGC -Djava.awt.headless=true -Xloggc:/apps/service/kafka/bin/../logs/kafkaServer-gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.port=9999&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;客户端机器配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU: 24core/2.6GHZ&lt;/li&gt;
&lt;li&gt;Memory: 3G&lt;/li&gt;
&lt;li&gt;Network: 1000Mb&lt;/li&gt;
&lt;li&gt;OS/kernel: CentOs release 6.3 (Final)&lt;/li&gt;
&lt;li&gt;Disk: 240G&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;62-不同场景测试&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-%E4%B8%8D%E5%90%8C%E5%9C%BA%E6%99%AF%E6%B5%8B%E8%AF%95&quot; aria-label=&quot;62 不同场景测试 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 不同场景测试&lt;/h2&gt;
&lt;h3 id=&quot;621-场景1&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#621-%E5%9C%BA%E6%99%AF1&quot; aria-label=&quot;621 场景1 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2.1 场景1&lt;/h3&gt;
&lt;p&gt;测试不同的副本数、min.insync.replicas 策略以及 request.required.acks 策略（以下简称 acks 策略）对于发送速度（TPS）的影响。&lt;/p&gt;
&lt;p&gt;具体配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 producer&lt;/li&gt;
&lt;li&gt;发送方式为 sync&lt;/li&gt;
&lt;li&gt;消息体大小为 1kB&lt;/li&gt;
&lt;li&gt;partition 数为 12&lt;/li&gt;
&lt;li&gt;副本数为：1/2/4&lt;/li&gt;
&lt;li&gt;min.insync.replicas 分别为 1/2/4&lt;/li&gt;
&lt;li&gt;acks 分别为 -1（all）/1/0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;具体测试数据如下表（min.insync.replicas 只在 acks=-1 时有效）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-06.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;测试结果分析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;客户端的 acks 策略对发送的 TPS 有较大的影响，TPS：acks_0 &gt; acks_1 &gt; ack_-1;&lt;/li&gt;
&lt;li&gt;副本数越高，TPS 越低；副本数一致时，min.insync.replicas 不影响 TPS；&lt;/li&gt;
&lt;li&gt;acks=0/1 时，TPS 与 min.insync.replicas 参数以及副本数无关，仅受 acks 策略的影响。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面将 partition 的个数设置为 1，来进一步确认下不同的 acks 策略、不同的 min.insync.replicas 策略以及不同的副本数对于发送速度的影响，详细请看情景 2 和情景 3。&lt;/p&gt;
&lt;h3 id=&quot;622-场景2&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#622-%E5%9C%BA%E6%99%AF2&quot; aria-label=&quot;622 场景2 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2.2 场景2&lt;/h3&gt;
&lt;p&gt;在 partition 个数固定为 1，测试不同的副本数和 min.insync.replicas 策略对发送速度的影响。&lt;/p&gt;
&lt;p&gt;具体配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 producer&lt;/li&gt;
&lt;li&gt;发送方式为 sync&lt;/li&gt;
&lt;li&gt;消息体大小为 1kB&lt;/li&gt;
&lt;li&gt;producer 端 acks=-1(all)&lt;/li&gt;
&lt;li&gt;变换副本数：2/3/4&lt;/li&gt;
&lt;li&gt;min.insync.replicas 设置为：1/2/4&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-07.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;测试结果分析：&lt;/p&gt;
&lt;p&gt;副本数越高，TPS 越低（这点与场景 1 的测试结论吻合），但是当 partition 数为 1 时差距甚微。min.insync.replicas 不影响 TPS。&lt;/p&gt;
&lt;h3 id=&quot;623-场景3&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#623-%E5%9C%BA%E6%99%AF3&quot; aria-label=&quot;623 场景3 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2.3 场景3&lt;/h3&gt;
&lt;p&gt;在 partition 个数固定为 1，测试不同的 acks 策略和副本数对发送速度的影响。&lt;/p&gt;
&lt;p&gt;具体配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 producer&lt;/li&gt;
&lt;li&gt;发送方式为 sync&lt;/li&gt;
&lt;li&gt;消息体大小为 1kB&lt;/li&gt;
&lt;li&gt;min.insync.replicas=1&lt;/li&gt;
&lt;li&gt;topic 副本数为：1/2/4&lt;/li&gt;
&lt;li&gt;acks： 0/1/-1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-08.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;测试结果分析（与情景 1 一致）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;副本数越多，TPS 越低；&lt;/li&gt;
&lt;li&gt;客户端的 acks 策略对发送的 TPS 有较大的影响，TPS：acks_0 &gt; acks_1 &gt; ack_-1。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;624-场景4-id_benchmark_scen4&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#624-%E5%9C%BA%E6%99%AF4-id_benchmark_scen4&quot; aria-label=&quot;624 场景4 id_benchmark_scen4 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2.4 场景4 {#ID_BENCHMARK_SCEN4}&lt;/h3&gt;
&lt;p&gt;测试不同 partition 数对发送速率的影响&lt;/p&gt;
&lt;p&gt;具体配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 producer&lt;/li&gt;
&lt;li&gt;消息体大小为 1KB&lt;/li&gt;
&lt;li&gt;发送方式为 sync&lt;/li&gt;
&lt;li&gt;topic 副本数为 2&lt;/li&gt;
&lt;li&gt;min.insync.replicas=2&lt;/li&gt;
&lt;li&gt;acks=-1&lt;/li&gt;
&lt;li&gt;partition 数量设置为 1/2/4/8/12&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试结果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-09.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;测试结果分析：&lt;/p&gt;
&lt;p&gt;partition 的不同会影响 TPS，随着 partition 的个数的增长 TPS 会有所增长，但并不是一直成正比关系，到达一定临界值时，partition 数量的增加反而会使 TPS 略微降低。&lt;/p&gt;
&lt;h3 id=&quot;625-场景5&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#625-%E5%9C%BA%E6%99%AF5&quot; aria-label=&quot;625 场景5 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2.5 场景5&lt;/h3&gt;
&lt;p&gt;通过将集群中部分 broker 设置成不可服务状态，测试对客户端以及消息落盘的影响。&lt;/p&gt;
&lt;p&gt;具体配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 producer&lt;/li&gt;
&lt;li&gt;消息体大小 1KB&lt;/li&gt;
&lt;li&gt;发送方式为 sync&lt;/li&gt;
&lt;li&gt;topic 副本数为 4&lt;/li&gt;
&lt;li&gt;min.insync.replicas 设置为 2&lt;/li&gt;
&lt;li&gt;acks=-1&lt;/li&gt;
&lt;li&gt;retries=0/100000000&lt;/li&gt;
&lt;li&gt;partition 数为 12&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;具体测试数据如下表：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-10.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;出错信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;错误 1：客户端返回异常，部分数据可落盘，部分失败：org.apache.kafka.common.errors.NetworkException: The server disconnected before a response was received.&lt;/li&gt;
&lt;li&gt;错误 2：[WARN]internals.Sender - Got error produce response with correlation id 19369 on topic-partition default_channel_replicas_4_1-3, retrying (999999999 attempts left). Error: NETWORK_EXCEPTION&lt;/li&gt;
&lt;li&gt;错误 3： [WARN]internals.Sender - Got error produce response with correlation id 77890 on topic-partition default_channel_replicas_4_1-8, retrying (999999859 attempts left). Error: NOT_ENOUGH_REPLICAS&lt;/li&gt;
&lt;li&gt;错误 4： [WARN]internals.Sender - Got error produce response with correlation id 77705 on topic-partition default_channel_replicas_4_1-3, retrying (999999999 attempts left). Error: NOT_ENOUGH_REPLICAS_AFTER_APPEND&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试结果分析：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kill 两台 broker 后，客户端可以继续发送。broker 减少后，partition 的 leader 分布在剩余的两台 broker 上，造成了 TPS 的减小；&lt;/li&gt;
&lt;li&gt;kill 三台 broker 后，客户端无法继续发送。Kafka 的自动重试功能开始起作用，当大于等于 min.insync.replicas 数量的 broker 恢复后，可以继续发送；&lt;/li&gt;
&lt;li&gt;当 retries 不为 0 时，消息有重复落盘；客户端成功返回的消息都成功落盘，异常时部分消息可以落盘。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;626-场景6&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#626-%E5%9C%BA%E6%99%AF6&quot; aria-label=&quot;626 场景6 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2.6 场景6&lt;/h3&gt;
&lt;p&gt;测试单个 producer 的发送延迟，以及端到端的延迟。&lt;/p&gt;
&lt;p&gt;具体配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个 producer&lt;/li&gt;
&lt;li&gt;消息体大小 1KB&lt;/li&gt;
&lt;li&gt;发送方式为 sync&lt;/li&gt;
&lt;li&gt;topic 副本数为 4&lt;/li&gt;
&lt;li&gt;min.insync.replicas 设置为 2&lt;/li&gt;
&lt;li&gt;acks=-1&lt;/li&gt;
&lt;li&gt;partition 数为 12&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试数据及结果（单位为 ms）：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/kafka-note/message-queue-11.jpg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;63-各场景测试总结&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#63-%E5%90%84%E5%9C%BA%E6%99%AF%E6%B5%8B%E8%AF%95%E6%80%BB%E7%BB%93&quot; aria-label=&quot;63 各场景测试总结 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3 各场景测试总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;当 acks=-1 时，Kafka 发送端的 TPS 受限于 topic 的副本数量（ISR 中），副本越多 TPS 越低；&lt;/li&gt;
&lt;li&gt;acks=0 时，TPS 最高，其次为 1，最差为 -1，即 TPS：acks_0 &gt; acks_1 &gt; ack_-1；&lt;/li&gt;
&lt;li&gt;min.insync.replicas 参数不影响 TPS；&lt;/li&gt;
&lt;li&gt;partition 的不同会影响 TPS，随着 partition 的个数的增长 TPS 会有所增长，但并不是一直成正比关系，到达一定临界值时，partition 数量的增加反而会使 TPS 略微降低；&lt;/li&gt;
&lt;li&gt;Kafka 在 acks=-1,min.insync.replicas&gt;=1 时，具有高可靠性，所有成功返回的消息都可以落盘。&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;7-kafka使用范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-kafka%E4%BD%BF%E7%94%A8%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;7 kafka使用范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. Kafka使用范例&lt;/h1&gt;
&lt;p&gt;实验使用的还是下载下来的Kafka，版本如头部申明的是&lt;code class=&quot;language-text&quot;&gt;2.2.0&lt;/code&gt;。范例代码可以在Github查看：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/experiment/kafka&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/experiment/kafka/&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;8-在docker内部署集群&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-%E5%9C%A8docker%E5%86%85%E9%83%A8%E7%BD%B2%E9%9B%86%E7%BE%A4&quot; aria-label=&quot;8 在docker内部署集群 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. 在Docker内部署集群&lt;/h1&gt;
&lt;p&gt;一般来说部署一个以上的docker容器组成集群，可以使用bash脚本的方法，自己编写命令一个个启动，但更好的方法是使用&lt;code class=&quot;language-text&quot;&gt;docker-compose&lt;/code&gt;命令，读取配置文件，将整个集群按设定的模式启动起来。可运行范例可以查看：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/conf/dev/kafka-cluster.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/conf/dev/kafka-cluster.yaml&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;启动脚本：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/bash/dev/docker_kafka.sh&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/bash/dev/docker_kafka.sh&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;主要有几个点需要注意下。&lt;/p&gt;
&lt;h2 id=&quot;81-重要配置项&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#81-%E9%87%8D%E8%A6%81%E9%85%8D%E7%BD%AE%E9%A1%B9&quot; aria-label=&quot;81 重要配置项 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1 重要配置项&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;kafka_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;wurstmeister/kafka:2.12-2.2.0&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 一定需要&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;kafka_1&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;kafka_1&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 使用这个名字来让同network的其他服务进行访问&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;zookeeper&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 保证启动先后顺序&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /private/tmp/jmx_prometheus_javaagent&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;0.9.jar&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/usr/local/bin/jmx_prometheus_javaagent&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;0.9.jar
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /private/tmp/jmx&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;kafka&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;2_0_0.yaml&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/etc/jmx&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;exporter/jmx&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;kafka&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;2_0_0.yaml
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; kafka_vol_1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/tmp/kafka/data
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;net&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;19092:9092&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# client port # 保证非同一network的其他服务也能访问，但这么做要求每个kafka service都监听不同的端口，相互不能冲突&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;17071:7071&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# jmx prometheus metrics&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9092&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# client port&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9093&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# internal traffic # kafka集群内部流量走的端口号&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9991&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# jmx # jmx进程本身监听的地址，提供给jmx_exporter连接用&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;7071&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# jmx prometheus metrics # jmx_exporter监听的地址，提供给prometheus抓取metrics&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;always&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;json-file&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 日志输出以json格式，容易让聚合工具使用&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;512m&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 保证日志最大尺寸不会过大占用过多系统磁盘&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_LISTENERS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# kafka的实际监听地址，一般不是0.0.0.0就是容器名&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_ADVERTISED_LISTENERS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INSIDE://kafka_1:9093,OUTSIDE://127.0.0.1:19092&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# kafka发布到zookeeper，让客户端获取并凭之连接kafka的地址，一定需要是客户端能访问到的地址，INSIDE部分供集群内部流量使用，OUTSIDE供客户端使用&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_LISTENER_SECURITY_PROTOCOL_MAP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 明确内部外部的通讯协议&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_INTER_BROKER_LISTENER_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; INSIDE &lt;span class=&quot;token comment&quot;&gt;# 告诉kafka集群上面的INSIDE和OUTSIDE配置哪个才是供集群内部流量使用的，按语义一般是INSIDE&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_BROKER_ID&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 必须每个kafka broker单独一个，不可重复&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;JMX_PORT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9991&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# jmx监听的地址&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_OPTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;-javaagent:/usr/local/bin/jmx_prometheus_javaagent-0.9.jar=7071:/etc/jmx-exporter/jmx-kafka-2_0_0.yaml&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# kafka在启动时一并会给予启动&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_ZOOKEEPER_CONNECT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;zookeeper:2181&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 告知kafka zookeeper的地址&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_LOG_DIRS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/tmp/kafka-logs&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# kafka实际的数据存放位置，推荐使用volume进行该地址的local映射&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# kafka内部用来保存topic的offset的数据，其replication数量&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# kafka内部用来保存transaction state log的数据，其replication数量&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;KAFKA_MIN_INSYNC_REPLICAS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# partition的leader节点要求当前在线的replica节点的数量&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;关于&lt;code class=&quot;language-text&quot;&gt;LISTENER&lt;/code&gt;相关的几个配置（用于集群访问）更多的可以看下：&lt;a href=&quot;#DOCKER_OUT_NET&quot;&gt;8.2 对容器外应用提供服务&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;参见：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.confluent.io/current/kafka/deployment.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Running Kafka in Production&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;82-对容器外应用提供服务-docker_out_net&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#82-%E5%AF%B9%E5%AE%B9%E5%99%A8%E5%A4%96%E5%BA%94%E7%94%A8%E6%8F%90%E4%BE%9B%E6%9C%8D%E5%8A%A1-docker_out_net&quot; aria-label=&quot;82 对容器外应用提供服务 docker_out_net permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2 对容器外应用提供服务 {#DOCKER_OUT_NET}&lt;/h2&gt;
&lt;p&gt;在docker中部署集群有一个比较大的问题就是容器内部和外部的网络访问地址是隔离的，而kafka集群部分节点的相互发现是根据配置：&lt;code class=&quot;language-text&quot;&gt;KAFKA_ADVERTISED_LISTENERS&lt;/code&gt;来进行通知的。&lt;/p&gt;
&lt;p&gt;如果该配置内的地址填写的是&lt;code class=&quot;language-text&quot;&gt;127.0.0.1&lt;/code&gt;这样的回环地址或容器外的IP，那么容器内各kafka节点之间的通讯就会有问题（因为容器内各节点拿到的配置地址都是容器外的IP）。而如果将该配置内的地址都配置成docker容器的名字，那么在容器内部的流量是没问题了，但外部访问kafka服务的应用程序拿到的地址则是容器的名字，就没法访问了。&lt;/p&gt;
&lt;p&gt;所以对于需要向容器外部环境的应用提供服务的情况来说，需要做好几项配置的调整（这里说的配置都是kafka的配置，不涉及到zookeeper的配置，事实上集群部署的配置中zookeeper相关的内容非常简单）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;KAFKA_LISTENERS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;KAFKA_ADVERTISED_LISTENERS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INSIDE://kafka_1:9093,OUTSIDE://127.0.0.1:19092&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;KAFKA_LISTENER_SECURITY_PROTOCOL_MAP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT&quot;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;KAFKA_INTER_BROKER_LISTENER_NAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; INSIDE&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;kafka的配置中，现在可以将内部流量和外部流量的监听地址分离开来，在配置&lt;code class=&quot;language-text&quot;&gt;LISTENERS&lt;/code&gt;相关的配置时，使用&lt;code class=&quot;language-text&quot;&gt;,&lt;/code&gt;将&lt;code class=&quot;language-text&quot;&gt;INSIDE&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;OUTSIDE&lt;/code&gt;隔离开来即可。一般来说，&lt;code class=&quot;language-text&quot;&gt;INSIDE&lt;/code&gt;的地址会配置成当前节点的容器名，或者就直接设置成&lt;code class=&quot;language-text&quot;&gt;0.0.0.0&lt;/code&gt;。而&lt;code class=&quot;language-text&quot;&gt;OUTSIDE&lt;/code&gt;则根据自身需求设置即可，这里的范例是给本机开发测试用，因此设置的是&lt;code class=&quot;language-text&quot;&gt;127.0.0.1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;KAFKA_INTER_BROKER_LISTENER_NAME&lt;/code&gt;配置项则是告诉kafka，集群各broker节点之间是使用INSIDE还是OUTSIDE配置作为集群内部流量的通讯地址。此外需要注意的是，该配置的&lt;code class=&quot;language-text&quot;&gt;INSIDE&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;OUTSIDE&lt;/code&gt;监听的端口是&lt;code class=&quot;language-text&quot;&gt;不可以重复&lt;/code&gt;的，因为实际上kafka就是开了两个端口都在监听。&lt;/p&gt;
&lt;p&gt;一般第一次在本地设置集群进行开发和调试的时候，这里是个大坑，非常麻烦。配置不正确就会发现kafka完全无法通讯。&lt;/p&gt;
&lt;h2 id=&quot;83-docker-compose-scale&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#83-docker-compose-scale&quot; aria-label=&quot;83 docker compose scale permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.3 docker-compose scale&lt;/h2&gt;
&lt;p&gt;一般来说，kafka service的配置不适合在配置文件中只设置一份，然后使用docker-compose scale的方法进行横向扩展。&lt;/p&gt;
&lt;p&gt;适用scale的场景只有完全无状态，且各个节点之间的配置完全相同的情况，而kafka各节点一般最好设置自身的&lt;code class=&quot;language-text&quot;&gt;container_name&lt;/code&gt;，然后在监听地址中使用正确的容器名作为地址，来进行相互通讯。&lt;/p&gt;
&lt;h2 id=&quot;84-yaml配置重用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#84-yaml%E9%85%8D%E7%BD%AE%E9%87%8D%E7%94%A8&quot; aria-label=&quot;84 yaml配置重用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.4 yaml配置重用&lt;/h2&gt;
&lt;p&gt;因为无法使用scale的缘故，必须手写大量的kafka service节点yaml配置，这倒也不算是大问题。关键的问题在于有大量重复的配置项，如果后面要修改，就很麻烦，怕漏改或者改错。&lt;/p&gt;
&lt;p&gt;因此最好的方法是使用yaml的配置重用，来设置共通的配置，然后像变量一样重用。这可以参见我之前提到的范例配置文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;x-kafka-environment-defaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;&amp;amp;KAFKA_ENV_DEFAULTS&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# 在这里放默认的配置&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;kafka_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*KAFKA_ENV_DEFAULTS&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 这样就把作为变量的配置全部导入到这个点上了&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;84-相关参考&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#84-%E7%9B%B8%E5%85%B3%E5%8F%82%E8%80%83&quot; aria-label=&quot;84 相关参考 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.4 相关参考&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://better-coding.com/building-apache-kafka-cluster-using-docker-compose-and-virtualbox/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Building Apache Kafka cluster using docker-compose and VirtualBox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kaaproject.org/kafka-docker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deploying a Kafka broker in a Docker container&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;9-写性能与安全性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#9-%E5%86%99%E6%80%A7%E8%83%BD%E4%B8%8E%E5%AE%89%E5%85%A8%E6%80%A7&quot; aria-label=&quot;9 写性能与安全性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;9. 写性能与安全性&lt;/h1&gt;
&lt;p&gt;在进行测试的过程中，发现写入的速度比较慢，基本上每次写入在kafka集群这边会耗时1秒多，完全不能接受了。之前的博文中也提到了，集群安全性和写入性能是反比的，主要有几项因素：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;producer的写入模式：同步、异步
&lt;ul&gt;
&lt;li&gt;异步拥有最佳的性能，但安全性极差&lt;/li&gt;
&lt;li&gt;同步性能很差，但安全性有保证&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;acks写入的集群同步模式：-1完全同步、0完全不等待同步、1Leader节点同步
&lt;ul&gt;
&lt;li&gt;0拥有最佳性能，最低的安全性&lt;/li&gt;
&lt;li&gt;-1拥有最佳性能，但性能最低&lt;/li&gt;
&lt;li&gt;1则比较均衡&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;partition数量：acks如果为-1，则需要同步所有节点，partition数量越多则性能越低&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后续进行了一些研究和测试。&lt;/p&gt;
&lt;p&gt;集群共3个broker，topic分片如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Topic:work-topic	PartitionCount:3	ReplicationFactor:3	Configs:
	Topic: work-topic	Partition: 0	Leader: 2	Replicas: 2,0,1	Isr: 2,0,1
	Topic: work-topic	Partition: 1	Leader: 1	Replicas: 1,2,0	Isr: 1,2,0
	Topic: work-topic	Partition: 2	Leader: 0	Replicas: 0,1,2	Isr: 0,1,2&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;查了下官方配置，&lt;code class=&quot;language-text&quot;&gt;producer.acks&lt;/code&gt;这个现在放在&lt;code class=&quot;language-text&quot;&gt;3.3 Producer Configs&lt;/code&gt;里，命名为&lt;code class=&quot;language-text&quot;&gt;acks&lt;/code&gt;（&lt;a href=&quot;https://kafka.apache.org/22/documentation.html#producerconfigs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;链接&lt;/a&gt;）。需要注意的是，这一项配置并不是服务端的配置项，而是连接上来的客户端producer所进行的设置，是否acks根据客户端producer的要求而变动。这很反直觉，我一开始一直都以为这是服务端的配置项，没想到居然是客户端的。&lt;/p&gt;
&lt;p&gt;acks在kafka-go的使用，可以查看注释：&lt;a href=&quot;https://github.com/segmentio/kafka-go/blob/v0.2.4/writer.go#L101&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;kafka-go/writer.go&lt;/a&gt;，默认是-1，也就是最安全但最慢的那种。&lt;/p&gt;
&lt;p&gt;此外，写入模式是同步还是异步也是客户端设置，见：&lt;a href=&quot;https://github.com/segmentio/kafka-go/blob/v0.2.4/writer.go#L105&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;kafka-go/writer.go&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在上面提到的几项要素中，集群规模和partition数量之类都是业务要求，一般不会轻易变动，所以测试主要是实验在不同写入模式和acks情况下的性能变动。&lt;/p&gt;
&lt;p&gt;测试：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;同步 -1 1秒+
同步 1  1秒+
同步 0  1秒+
异步 -1 0.2ms 几乎瞬间完成
异步 1  0.2ms 几乎瞬间完成
异步 0  0.2ms 几乎瞬间完成&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;结论：性能只在于是否将客户端设置成异步写入，acks对性能的影响微乎其微。&lt;/p&gt;
&lt;p&gt;但上述的测试是在MAC本地环境进行的，有几项因素不够稳定：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;kafka集群的内存很小&lt;/li&gt;
&lt;li&gt;磁盘IO和实际情况差别较大&lt;/li&gt;
&lt;li&gt;集群规模过小&lt;/li&gt;
&lt;li&gt;partition数量很少（集群和partition数量很小能够部分解释为什么acks的改动基本上不影响性能）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此上述测试的结论主要是参考价值，不能作为最终结论。如果后续需要严谨结论的话，需要在真实机器上测试，并需要开启go的profiling，观察下kafka类库中的写入到底是怎么完成的，以及kafka集群的响应情况。此外，即便是模拟集群1秒左右的同步写入速度也实在是太慢了，后续还需要深入profiling，到底这1秒做了什么（无论是kafka还是go客户端）。&lt;/p&gt;
&lt;h1 id=&quot;10-todo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#10-todo&quot; aria-label=&quot;10 todo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;10. TODO&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;深入研究Kafka的监控Metrics&lt;/li&gt;
&lt;li&gt;Kafka集群同步写入性能较低的原因解析&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.kubiji.cn/book/apache_kafka/APACHEKAFKAJiaoCheng/APACHEKAFKAGaiShu.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Apache kafka中文手册&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/distributed-queue-programme-model-actual-combat-optimization&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;分布式队列编程：从模型、实战到优化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&amp;#x26;mid=2651745361&amp;#x26;idx=1&amp;#x26;sn=5f0f67484a0de4b0dd2796848ef9cc94&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;分布式队列编程优化篇&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/7a6deaba34d2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;如何保证消息队列的高可用和幂等性以及数据丢失，顺序一致性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/kafka-vs-rabbitmq&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;消息中间件选型分析：从 Kafka 与 RabbitMQ 的对比看全局&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/dXJ3EYIp*WaHfmVwlMeu&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;滴滴出行基于 RocketMQ 构建企业级消息队列服务的实践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/39586635/why-is-kafka-pull-based-instead-of-push-based&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Why is Kafka pull-based instead of push-based?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@philipfeng/modern-open-source-messaging-apache-kafka-rabbitmq-nats-pulsar-and-nsq-ca3bf7422db5&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Modern Open Source Messaging: NATS, RabbitMQ, Apache Kafka, hmbdc, Synapse, NSQ and Pulsar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/huxi2b/p/6223228.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kafka消费组(consumer group)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/45175424/how-multiple-consumer-group-consumers-work-across-partition-on-the-same-topic-in&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How multiple consumer group consumers work across partition on the same topic in Kafka?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/pursuer211/article/details/79799478&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;kafka中partition和消费者对应关系&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/@danieljameskay/understanding-the-enable-auto-commit-kafka-consumer-property-12fa0ade7b65&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Understanding the ‘enable.auto.commit’ Kafka Consumer property&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.datadoghq.com/blog/monitoring-kafka-performance-metrics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Monitoring Kafka performance metrics - P1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.datadoghq.com/blog/collecting-kafka-performance-metrics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Monitoring Kafka performance metrics - P2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/danielqsj/kafka_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;danielqsj/kafka_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.confluent.io/current/kafka/monitoring.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Monitoring Kafka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/depth-interpretation-of-kafka-data-reliability&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kafka 数据可靠性深度解读&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://better-coding.com/building-apache-kafka-cluster-using-docker-compose-and-virtualbox/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Building Apache Kafka cluster using docker-compose and VirtualBox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kaaproject.org/kafka-docker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deploying a Kafka broker in a Docker container&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.confluent.io/current/kafka/deployment.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Running Kafka in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/47388267&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;比拼Kafka，大数据分析新秀Pulsar到底好在哪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.slideshare.net/merlimat/high-performance-messaging-with-apache-pulsar&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;High performance messaging with Apache Pulsar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/Us*a8umKXT9LpV9hA6tF&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;选择 Pulsar 而不是 Kafka 的 7 大理由&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/prometheus/jmx_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus/jmx_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/sscaling/jmx-prometheus-exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;sscaling/jmx-prometheus-exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/danielqsj/kafka_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;danielqsj/kafka_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/danielqsj/kafka-exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;danielqsj/kafka-exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/oded-dd/prometheus-jmx-kafka&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;oded-dd/prometheus-jmx-kafka&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Mousavi310/kafka-grafana&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Mousavi310/kafka-grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[消息队列设计精要 - 美团点评技术团队]]></title><link>https://xenojoshua.com/posts/2019/04/message-queue-design</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/message-queue-design</guid><pubDate>Fri, 26 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot;&gt;前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%AD%A3%E6%96%87&quot;&gt;正文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E4%BD%95%E6%97%B6%E9%9C%80%E8%A6%81%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&quot;&gt;1. 何时需要消息队列&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#11-%E8%A7%A3%E8%80%A6&quot;&gt;1.1 解耦&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#12-%E6%9C%80%E7%BB%88%E4%B8%80%E8%87%B4%E6%80%A7&quot;&gt;1.2 最终一致性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#13-%E5%B9%BF%E6%92%AD&quot;&gt;1.3 广播&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#14-%E9%94%99%E5%B3%B0%E4%B8%8E%E6%B5%81%E6%8E%A7&quot;&gt;1.4 错峰与流控&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&quot;&gt;2. 如何设计一个消息队列&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E7%BB%BC%E8%BF%B0&quot;&gt;2.1 综述&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97%E5%9F%BA%E6%9C%AC%E5%8A%9F%E8%83%BD&quot;&gt;2.2 实现队列基本功能&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#221-rpc%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE&quot;&gt;2.2.1 RPC通信协议&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#222-%E9%AB%98%E5%8F%AF%E7%94%A8&quot;&gt;2.2.2 高可用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#223-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%89%BF%E8%BD%BD%E6%B6%88%E6%81%AF%E5%A0%86%E7%A7%AF%E7%9A%84%E8%83%BD%E5%8A%9B&quot;&gt;2.2.3 服务端承载消息堆积的能力&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#224-%E5%AD%98%E5%82%A8%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E9%80%89%E6%8B%A9&quot;&gt;2.2.4 存储子系统的选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#225-%E6%B6%88%E8%B4%B9%E5%85%B3%E7%B3%BB%E8%A7%A3%E6%9E%90&quot;&gt;2.2.5 消费关系解析&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-%E9%98%9F%E5%88%97%E9%AB%98%E7%BA%A7%E7%89%B9%E6%80%A7%E8%AE%BE%E8%AE%A1&quot;&gt;2.3 队列高级特性设计&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#231-%E5%8F%AF%E9%9D%A0%E6%8A%95%E9%80%92%E6%9C%80%E7%BB%88%E4%B8%80%E8%87%B4%E6%80%A7&quot;&gt;2.3.1 可靠投递（最终一致性）&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#2311-%E6%B6%88%E8%B4%B9%E7%A1%AE%E8%AE%A4&quot;&gt;2.3.1.1 消费确认&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2312-%E9%87%8D%E5%A4%8D%E6%B6%88%E6%81%AF%E5%92%8C%E9%A1%BA%E5%BA%8F%E6%B6%88%E6%81%AF&quot;&gt;2.3.1.2 重复消息和顺序消息&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%89%88%E6%9C%AC%E5%8F%B7&quot;&gt;版本号&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%8A%B6%E6%80%81%E6%9C%BA&quot;&gt;状态机&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2313-%E4%B8%AD%E9%97%B4%E4%BB%B6%E5%AF%B9%E4%BA%8E%E9%87%8D%E5%A4%8D%E6%B6%88%E6%81%AF%E7%9A%84%E5%A4%84%E7%90%86&quot;&gt;2.3.1.3 中间件对于重复消息的处理&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#232-%E4%BA%8B%E5%8A%A1&quot;&gt;2.3.2 事务&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#233-%E6%80%A7%E8%83%BD%E7%9B%B8%E5%85%B3&quot;&gt;2.3.3 性能相关&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#2331-%E5%BC%82%E6%AD%A5%E5%90%8C%E6%AD%A5&quot;&gt;2.3.3.1 异步/同步&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2332-%E6%89%B9%E9%87%8F&quot;&gt;2.3.3.2 批量&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#24-push%E8%BF%98%E6%98%AFpull&quot;&gt;2.4 push还是pull&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#241-%E6%85%A2%E6%B6%88%E8%B4%B9&quot;&gt;2.4.1 慢消费&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#242-%E6%B6%88%E6%81%AF%E5%BB%B6%E8%BF%9F%E4%B8%8E%E5%BF%99%E7%AD%89&quot;&gt;2.4.2 消息延迟与忙等&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#243-%E9%A1%BA%E5%BA%8F%E6%B6%88%E6%81%AF&quot;&gt;2.4.3 顺序消息&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E6%80%BB%E7%BB%93&quot;&gt;3. 总结&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%9C%E8%80%85%E7%AE%80%E4%BB%8B&quot;&gt;作者简介&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%89%8D%E8%A8%80&quot; aria-label=&quot;前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;前言&lt;/h1&gt;
&lt;p&gt;本文源自美团点评技术团队博客，但似乎是因为博客改版的原因，之前本文的链接失效了。我因为有剪藏文章的习惯，因此有幸没有丢失原文内容。而最近在写的消息队列文章中，我希望引用部分内容，而网上已经不好找原文了，因此无奈之下在这里做一份备份转载。&lt;/p&gt;
&lt;h1 id=&quot;正文&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%AD%A3%E6%96%87&quot; aria-label=&quot;正文 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;正文&lt;/h1&gt;
&lt;p&gt;消息队列已经逐渐成为企业IT系统内部通信的核心手段。它具有低耦合、可靠投递、广播、流量控制、最终一致性等一系列功能，成为异步RPC的主要手段之一。&lt;/p&gt;
&lt;p&gt;当今市面上有很多主流的消息中间件，如老牌的ActiveMQ、RabbitMQ，炙手可热的Kafka，阿里巴巴自主开发的Notify、MetaQ、RocketMQ等。&lt;/p&gt;
&lt;p&gt;本文不会一一介绍这些消息队列的所有特性，而是探讨一下自主开发设计一个消息队列时，你需要思考和设计的重要方面。过程中我们会参考这些成熟消息队列的很多重要思想。&lt;/p&gt;
&lt;p&gt;本文首先会阐述什么时候你需要一个消息队列，然后以Push模型为主，从零开始分析设计一个消息队列时需要考虑到的问题，如RPC、高可用、顺序和重复消息、可靠投递、消费关系解析等。&lt;/p&gt;
&lt;p&gt;也会分析以Kafka为代表的pull模型所具备的优点。最后是一些高级主题，如用批量/异步提高性能、pull模型的系统设计理念、存储子系统的设计、流量控制的设计、公平调度的实现等。其中最后四个方面会放在下篇讲解。&lt;/p&gt;
&lt;h1 id=&quot;1-何时需要消息队列&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E4%BD%95%E6%97%B6%E9%9C%80%E8%A6%81%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&quot; aria-label=&quot;1 何时需要消息队列 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 何时需要消息队列&lt;/h1&gt;
&lt;p&gt;当你需要使用消息队列时，首先需要考虑它的必要性。可以使用mq的场景有很多，最常用的几种，是做业务解耦/最终一致性/广播/错峰流控等。反之，如果需要强一致性，关注业务逻辑的处理结果，则RPC显得更为合适。&lt;/p&gt;
&lt;h2 id=&quot;11-解耦&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#11-%E8%A7%A3%E8%80%A6&quot; aria-label=&quot;11 解耦 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.1 解耦&lt;/h2&gt;
&lt;p&gt;解耦是消息队列要解决的最本质问题。所谓解耦，简单点讲就是一个事务，只关心核心的流程。而需要依赖其他系统但不那么重要的事情，有通知即可，无需等待结果。换句话说，基于消息的模型，关心的是“通知”，而非“处理”。&lt;/p&gt;
&lt;p&gt;比如在美团旅游，我们有一个产品中心，产品中心上游对接的是主站、移动后台、旅游供应链等各个数据源；下游对接的是筛选系统、API系统等展示系统。当上游的数据发生变更的时候，如果不使用消息系统，势必要调用我们的接口来更新数据，就特别依赖产品中心接口的稳定性和处理能力。但其实，作为旅游的产品中心，也许只有对于旅游自建供应链，产品中心更新成功才是他们关心的事情。而对于团购等外部系统，产品中心更新成功也好、失败也罢，并不是他们的职责所在。他们只需要保证在信息变更的时候通知到我们就好了。&lt;/p&gt;
&lt;p&gt;而我们的下游，可能有更新索引、刷新缓存等一系列需求。对于产品中心来说，这也不是我们的职责所在。说白了，如果他们定时来拉取数据，也能保证数据的更新，只是实时性没有那么强。但使用接口方式去更新他们的数据，显然对于产品中心来说太过于“重量级”了，只需要发布一个产品ID变更的通知，由下游系统来处理，可能更为合理。&lt;/p&gt;
&lt;p&gt;再举一个例子，对于我们的订单系统，订单最终支付成功之后可能需要给用户发送短信积分什么的，但其实这已经不是我们系统的核心流程了。如果外部系统速度偏慢（比如短信网关速度不好），那么主流程的时间会加长很多，用户肯定不希望点击支付过好几分钟才看到结果。那么我们只需要通知短信系统“我们支付成功了”，不一定非要等待它处理完成。&lt;/p&gt;
&lt;h2 id=&quot;12-最终一致性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#12-%E6%9C%80%E7%BB%88%E4%B8%80%E8%87%B4%E6%80%A7&quot; aria-label=&quot;12 最终一致性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.2 最终一致性&lt;/h2&gt;
&lt;p&gt;最终一致性指的是两个系统的状态保持一致，要么都成功，要么都失败。当然有个时间限制，理论上越快越好，但实际上在各种异常的情况下，可能会有一定延迟达到最终一致状态，但最后两个系统的状态是一样的。&lt;/p&gt;
&lt;p&gt;业界有一些为“最终一致性”而生的消息队列，如Notify（阿里）、QMQ（去哪儿）等，其设计初衷，就是为了交易系统中的高可靠通知。&lt;/p&gt;
&lt;p&gt;以一个银行的转账过程来理解最终一致性，转账的需求很简单，如果A系统扣钱成功，则B系统加钱一定成功。反之则一起回滚，像什么都没发生一样。&lt;/p&gt;
&lt;p&gt;然而，这个过程中存在很多可能的意外：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;A扣钱成功，调用B加钱接口失败。&lt;/li&gt;
&lt;li&gt;A扣钱成功，调用B加钱接口虽然成功，但获取最终结果时网络异常引起超时。&lt;/li&gt;
&lt;li&gt;A扣钱成功，B加钱失败，A想回滚扣的钱，但A机器down机。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;可见，想把这件看似简单的事真正做成，真的不那么容易。所有跨VM的一致性问题，从技术的角度讲通用的解决方案是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;强一致性，分布式事务，但落地太难且成本太高，后文会具体提到。&lt;/li&gt;
&lt;li&gt;最终一致性，主要是用“记录”和“补偿”的方式。在做所有的不确定的事情之前，先把事情记录下来，然后去做不确定的事情，结果可能是：成功、失败或是不确定，“不确定”（例如超时等）可以等价为失败。成功就可以把记录的东西清理掉了，对于失败和不确定，可以依靠定时任务等方式把所有失败的事情重新搞一遍，直到成功为止。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;回到刚才的例子，系统在A扣钱成功的情况下，把要给B“通知”这件事记录在库里（为了保证最高的可靠性可以把通知B系统加钱和扣钱成功这两件事维护在一个本地事务里），通知成功则删除这条记录，通知失败或不确定则依靠定时任务补偿性地通知我们，直到我们把状态更新成正确的为止。&lt;/p&gt;
&lt;p&gt;整个这个模型依然可以基于RPC来做，但可以抽象成一个统一的模型，基于消息队列来做一个“企业总线”。&lt;/p&gt;
&lt;p&gt;具体来说，本地事务维护业务变化和通知消息，一起落地（失败则一起回滚），然后RPC到达broker，在broker成功落地后，RPC返回成功，本地消息可以删除。否则本地消息一直靠定时任务轮询不断重发，这样就保证了消息可靠落地broker。&lt;/p&gt;
&lt;p&gt;Broker往consumer发送消息的过程类似，一直发送消息，直到consumer发送消费成功确认。&lt;/p&gt;
&lt;p&gt;我们先不理会重复消息的问题，通过两次消息落地加补偿，下游是一定可以收到消息的。然后依赖状态机版本号等方式做判重，更新自己的业务，就实现了最终一致性。&lt;/p&gt;
&lt;p&gt;最终一致性不是消息队列的必备特性，但确实可以依靠消息队列来做最终一致性的事情。另外，所有不保证100%不丢消息的消息队列，理论上无法实现最终一致性。好吧，应该说理论上的100%，排除系统严重故障和bug。&lt;/p&gt;
&lt;p&gt;像Kafka一类的设计，在设计层面上就有丢消息的可能（比如定时刷盘，如果掉电就会丢消息）。哪怕只丢千分之一的消息，业务也必须用其他的手段来保证结果正确。&lt;/p&gt;
&lt;h2 id=&quot;13-广播&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#13-%E5%B9%BF%E6%92%AD&quot; aria-label=&quot;13 广播 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.3 广播&lt;/h2&gt;
&lt;p&gt;消息队列的基本功能之一是进行广播。如果没有消息队列，每当一个新的业务方接入，我们都要联调一次新接口。有了消息队列，我们只需要关心消息是否送达了队列，至于谁希望订阅，是下游的事情，无疑极大地减少了开发和联调的工作量。&lt;/p&gt;
&lt;p&gt;比如本文开始提到的产品中心发布产品变更的消息，以及景点库很多去重更新的消息，可能“关心”方有很多个，但产品中心和景点库只需要发布变更消息即可，谁关心谁接入。&lt;/p&gt;
&lt;h2 id=&quot;14-错峰与流控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#14-%E9%94%99%E5%B3%B0%E4%B8%8E%E6%B5%81%E6%8E%A7&quot; aria-label=&quot;14 错峰与流控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1.4 错峰与流控&lt;/h2&gt;
&lt;p&gt;试想上下游对于事情的处理能力是不同的。比如，Web前端每秒承受上千万的请求，并不是什么神奇的事情，只需要加多一点机器，再搭建一些LVS负载均衡设备和Nginx等即可。但数据库的处理能力却十分有限，即使使用SSD加分库分表，单机的处理能力仍然在万级。由于成本的考虑，我们不能奢求数据库的机器数量追上前端。&lt;/p&gt;
&lt;p&gt;这种问题同样存在于系统和系统之间，如短信系统可能由于短板效应，速度卡在网关上（每秒几百次请求），跟前端的并发量不是一个数量级。但用户晚上个半分钟左右收到短信，一般是不会有太大问题的。如果没有消息队列，两个系统之间通过协商、滑动窗口等复杂的方案也不是说不能实现。但系统复杂性指数级增长，势必在上游或者下游做存储，并且要处理定时、拥塞等一系列问题。而且每当有处理能力有差距的时候，都需要单独开发一套逻辑来维护这套逻辑。所以，利用中间系统转储两个系统的通信内容，并在下游系统有能力处理这些消息的时候，再处理这些消息，是一套相对较通用的方式。&lt;/p&gt;
&lt;p&gt;总而言之，消息队列不是万能的。对于需要强事务保证而且延迟敏感的，RPC是优于消息队列的。&lt;/p&gt;
&lt;p&gt;对于一些无关痛痒，或者对于别人非常重要但是对于自己不是那么关心的事情，可以利用消息队列去做。&lt;/p&gt;
&lt;p&gt;支持最终一致性的消息队列，能够用来处理延迟不那么敏感的“分布式事务”场景，而且相对于笨重的分布式事务，可能是更优的处理方式。&lt;/p&gt;
&lt;p&gt;当上下游系统处理能力存在差距的时候，利用消息队列做一个通用的“漏斗”。在下游有能力处理的时候，再进行分发。如果下游有很多系统关心你的系统发出的通知的时候，果断地使用消息队列吧。&lt;/p&gt;
&lt;h1 id=&quot;2-如何设计一个消息队列&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%A6%82%E4%BD%95%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&quot; aria-label=&quot;2 如何设计一个消息队列 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 如何设计一个消息队列&lt;/h1&gt;
&lt;h2 id=&quot;21-综述&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E7%BB%BC%E8%BF%B0&quot; aria-label=&quot;21 综述 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 综述&lt;/h2&gt;
&lt;p&gt;我们现在明确了消息队列的使用场景，下一步就是如何设计实现一个消息队列了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/message-queue-design/message-queue-01.png&quot; alt=&quot;01&quot;&gt;&lt;/p&gt;
&lt;p&gt;基于消息的系统模型，不一定需要broker(消息队列服务端)。市面上的的Akka（actor模型）、ZeroMQ等，其实都是基于消息的系统设计范式，但是没有broker。&lt;/p&gt;
&lt;p&gt;我们之所以要设计一个消息队列，并且配备broker，无外乎要做两件事情：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;消息的转储，在更合适的时间点投递，或者通过一系列手段辅助消息最终能送达消费机。&lt;/li&gt;
&lt;li&gt;规范一种范式和通用的模式，以满足解耦、最终一致性、错峰等需求。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;掰开了揉碎了看，最简单的消息队列可以做成一个消息转发器，把一次RPC做成两次RPC。发送者把消息投递到服务端（以下简称broker），服务端再将消息转发一手到接收端，就是这么简单。&lt;/p&gt;
&lt;p&gt;一般来讲，设计消息队列的整体思路是先build一个整体的数据流,例如producer发送给broker,broker发送给consumer,consumer回复消费确认，broker删除/备份消息等。&lt;/p&gt;
&lt;p&gt;利用RPC将数据流串起来。然后考虑RPC的高可用性，尽量做到无状态，方便水平扩展。&lt;/p&gt;
&lt;p&gt;之后考虑如何承载消息堆积，然后在合适的时机投递消息，而处理堆积的最佳方式，就是存储，存储的选型需要综合考虑性能/可靠性和开发维护成本等诸多因素。&lt;/p&gt;
&lt;p&gt;为了实现广播功能，我们必须要维护消费关系，可以利用zk/config server等保存消费关系。&lt;/p&gt;
&lt;p&gt;在完成了上述几个功能后，消息队列基本就实现了。然后我们可以考虑一些高级特性，如可靠投递，事务特性，性能优化等。&lt;/p&gt;
&lt;p&gt;下面我们会以设计消息队列时重点考虑的模块为主线，穿插灌输一些消息队列的特性实现方法，来具体分析设计实现一个消息队列时的方方面面。&lt;/p&gt;
&lt;h2 id=&quot;22-实现队列基本功能&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E5%AE%9E%E7%8E%B0%E9%98%9F%E5%88%97%E5%9F%BA%E6%9C%AC%E5%8A%9F%E8%83%BD&quot; aria-label=&quot;22 实现队列基本功能 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 实现队列基本功能&lt;/h2&gt;
&lt;h3 id=&quot;221-rpc通信协议&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#221-rpc%E9%80%9A%E4%BF%A1%E5%8D%8F%E8%AE%AE&quot; aria-label=&quot;221 rpc通信协议 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.1 RPC通信协议&lt;/h3&gt;
&lt;p&gt;刚才讲到，所谓消息队列，无外乎两次RPC加一次转储，当然需要消费端最终做消费确认的情况是三次RPC。既然是RPC，就必然牵扯出一系列话题，什么负载均衡啊、服务发现啊、通信协议啊、序列化协议啊，等等。在这一块，我的强烈建议是不要重复造轮子。利用公司现有的RPC框架：Thrift也好，Dubbo也好，或者是其他自定义的框架也好。因为消息队列的RPC，和普通的RPC没有本质区别。当然了，自主利用Memchached或者Redis协议重新写一套RPC框架并非不可（如MetaQ使用了自己封装的Gecko NIO框架，卡夫卡也用了类似的协议）。但实现成本和难度无疑倍增。排除对效率的极端要求，都可以使用现成的RPC框架。&lt;/p&gt;
&lt;p&gt;简单来讲，服务端提供两个RPC服务，一个用来接收消息，一个用来确认消息收到。并且做到不管哪个server收到消息和确认消息，结果一致即可。当然这中间可能还涉及跨IDC的服务的问题。这里和RPC的原则是一致的，尽量优先选择本机房投递。你可能会问，如果producer和consumer本身就在两个机房了，怎么办？首先，broker必须保证感知的到所有consumer的存在。其次，producer尽量选择就近的机房就好了。&lt;/p&gt;
&lt;h3 id=&quot;222-高可用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#222-%E9%AB%98%E5%8F%AF%E7%94%A8&quot; aria-label=&quot;222 高可用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.2 高可用&lt;/h3&gt;
&lt;p&gt;其实所有的高可用，是依赖于RPC和存储的高可用来做的。先来看RPC的高可用，美团的基于MTThrift的RPC框架，阿里的Dubbo等，其本身就具有服务自动发现，负载均衡等功能。而消息队列的高可用，只要保证broker接受消息和确认消息的接口是幂等的，并且consumer的几台机器处理消息是幂等的，这样就把消息队列的可用性，转交给RPC框架来处理了。&lt;/p&gt;
&lt;p&gt;那么怎么保证幂等呢？最简单的方式莫过于共享存储。broker多机器共享一个DB或者一个分布式文件/kv系统，则处理消息自然是幂等的。就算有单点故障，其他节点可以立刻顶上。另外failover可以依赖定时任务的补偿，这是消息队列本身天然就可以支持的功能。存储系统本身的可用性我们不需要操太多心，放心大胆的交给DBA们吧！&lt;/p&gt;
&lt;p&gt;对于不共享存储的队列，如Kafka使用分区加主备模式，就略微麻烦一些。需要保证每一个分区内的高可用性，也就是每一个分区至少要有一个主备且需要做数据的同步，关于这块HA的细节，可以参考下篇pull模型消息系统设计。&lt;/p&gt;
&lt;h3 id=&quot;223-服务端承载消息堆积的能力&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#223-%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%89%BF%E8%BD%BD%E6%B6%88%E6%81%AF%E5%A0%86%E7%A7%AF%E7%9A%84%E8%83%BD%E5%8A%9B&quot; aria-label=&quot;223 服务端承载消息堆积的能力 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.3 服务端承载消息堆积的能力&lt;/h3&gt;
&lt;p&gt;消息到达服务端如果不经过任何处理就到接收者了，broker就失去了它的意义。为了满足我们错峰/流控/最终可达等一系列需求，把消息存储下来，然后选择时机投递就显得是顺理成章的了。&lt;/p&gt;
&lt;p&gt;只是这个存储可以做成很多方式。比如存储在内存里，存储在分布式KV里，存储在磁盘里，存储在数据库里等等。但归结起来，主要有持久化和非持久化两种。&lt;/p&gt;
&lt;p&gt;持久化的形式能更大程度地保证消息的可靠性（如断电等不可抗外力），并且理论上能承载更大限度的消息堆积（外存的空间远大于内存）。&lt;/p&gt;
&lt;p&gt;但并不是每种消息都需要持久化存储。很多消息对于投递性能的要求大于可靠性的要求，且数量极大（如日志）。这时候，消息不落地直接暂存内存，尝试几次failover，最终投递出去也未尝不可。&lt;/p&gt;
&lt;p&gt;市面上的消息队列普遍两种形式都支持。当然具体的场景还要具体结合公司的业务来看。&lt;/p&gt;
&lt;h3 id=&quot;224-存储子系统的选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#224-%E5%AD%98%E5%82%A8%E5%AD%90%E7%B3%BB%E7%BB%9F%E7%9A%84%E9%80%89%E6%8B%A9&quot; aria-label=&quot;224 存储子系统的选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.4 存储子系统的选择&lt;/h3&gt;
&lt;p&gt;我们来看看如果需要数据落地的情况下各种存储子系统的选择。理论上，从速度来看，文件系统&gt;分布式KV（持久化）&gt;分布式文件系统&gt;数据库，而可靠性却截然相反。还是要从支持的业务场景出发作出最合理的选择，如果你们的消息队列是用来支持支付/交易等对可靠性要求非常高，但对性能和量的要求没有这么高，而且没有时间精力专门做文件存储系统的研究，DB是最好的选择。&lt;/p&gt;
&lt;p&gt;但是DB受制于IOPS，如果要求单broker 5位数以上的QPS性能，基于文件的存储是比较好的解决方案。整体上可以采用数据文件+索引文件的方式处理，具体这块的设计比较复杂，可以参考下篇的存储子系统设计。&lt;/p&gt;
&lt;p&gt;分布式KV（如MongoDB，HBase）等，或者持久化的Redis，由于其编程接口较友好，性能也比较可观，如果在可靠性要求不是那么高的场景，也不失为一个不错的选择。&lt;/p&gt;
&lt;h3 id=&quot;225-消费关系解析&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#225-%E6%B6%88%E8%B4%B9%E5%85%B3%E7%B3%BB%E8%A7%A3%E6%9E%90&quot; aria-label=&quot;225 消费关系解析 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.5 消费关系解析&lt;/h3&gt;
&lt;p&gt;现在我们的消息队列初步具备了转储消息的能力。下面一个重要的事情就是解析发送接收关系，进行正确的消息投递了。&lt;/p&gt;
&lt;p&gt;市面上的消息队列定义了一堆让人晕头转向的名词，如JMS 规范中的Topic/Queue，Kafka里面的Topic/Partition/ConsumerGroup，RabbitMQ里面的Exchange等等。抛开现象看本质，无外乎是单播与广播的区别。所谓单播，就是点到点；而广播，是一点对多点。当然，对于互联网的大部分应用来说，组间广播、组内单播是最常见的情形。&lt;/p&gt;
&lt;p&gt;消息需要通知到多个业务集群，而一个业务集群内有很多台机器，只要一台机器消费这个消息就可以了。&lt;/p&gt;
&lt;p&gt;当然这不是绝对的，很多时候组内的广播也是有适用场景的，如本地缓存的更新等等。另外，消费关系除了组内组间，可能会有多级树状关系。这种情况太过于复杂，一般不列入考虑范围。所以，一般比较通用的设计是支持组间广播，不同的组注册不同的订阅。组内的不同机器，如果注册一个相同的ID，则单播；如果注册不同的ID(如IP地址+端口)，则广播。&lt;/p&gt;
&lt;p&gt;至于广播关系的维护，一般由于消息队列本身都是集群，所以都维护在公共存储上，如config server、zookeeper等。维护广播关系所要做的事情基本是一致的:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;发送关系的维护。&lt;/li&gt;
&lt;li&gt;发送关系变更时的通知。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;23-队列高级特性设计&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-%E9%98%9F%E5%88%97%E9%AB%98%E7%BA%A7%E7%89%B9%E6%80%A7%E8%AE%BE%E8%AE%A1&quot; aria-label=&quot;23 队列高级特性设计 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 队列高级特性设计&lt;/h2&gt;
&lt;p&gt;上面都是些消息队列基本功能的实现，下面来看一些关于消息队列特性相关的内容，不管可靠投递/消息丢失与重复以及事务乃至于性能，不是每个消息队列都会照顾到，所以要依照业务的需求，来仔细衡量各种特性实现的成本，利弊，最终做出最为合理的设计。&lt;/p&gt;
&lt;h3 id=&quot;231-可靠投递最终一致性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#231-%E5%8F%AF%E9%9D%A0%E6%8A%95%E9%80%92%E6%9C%80%E7%BB%88%E4%B8%80%E8%87%B4%E6%80%A7&quot; aria-label=&quot;231 可靠投递最终一致性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.1 可靠投递（最终一致性）&lt;/h3&gt;
&lt;p&gt;这是个激动人心的话题，完全不丢消息，究竟可不可能？答案是，完全可能，前提是消息可能会重复，并且，在异常情况下，要接受消息的延迟。&lt;/p&gt;
&lt;p&gt;方案说简单也简单，就是每当要发生不可靠的事情（RPC等）之前，先将消息落地，然后发送。当失败或者不知道成功失败（比如超时）时，消息状态是待发送，定时任务不停轮询所有待发送消息，最终一定可以送达。&lt;/p&gt;
&lt;p&gt;具体来说：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;producer往broker发送消息之前，需要做一次落地。&lt;/li&gt;
&lt;li&gt;请求到server后，server确保数据落地后再告诉客户端发送成功。&lt;/li&gt;
&lt;li&gt;支持广播的消息队列需要对每个待发送的endpoint，持久化一个发送状态，直到所有endpoint状态都OK才可删除消息。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于各种不确定（超时、down机、消息没有送达、送达后数据没落地、数据落地了回复没收到），其实对于发送方来说，都是一件事情，就是消息没有送达。&lt;/p&gt;
&lt;p&gt;重推消息所面临的问题就是消息重复。重复和丢失就像两个噩梦，你必须要面对一个。好在消息重复还有处理的机会，消息丢失再想找回就难了。&lt;/p&gt;
&lt;p&gt;Anyway，作为一个成熟的消息队列，应该尽量在各个环节减少重复投递的可能性，不能因为重复有解决方案就放纵的乱投递。&lt;/p&gt;
&lt;p&gt;最后说一句，不是所有的系统都要求最终一致性或者可靠投递，比如一个论坛系统、一个招聘系统。一个重复的简历或话题被发布，可能比丢失了一个发布显得更让用户无法接受。不断重复一句话，任何基础组件要服务于业务场景。&lt;/p&gt;
&lt;h4 id=&quot;2311-消费确认&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2311-%E6%B6%88%E8%B4%B9%E7%A1%AE%E8%AE%A4&quot; aria-label=&quot;2311 消费确认 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.1.1 消费确认&lt;/h4&gt;
&lt;p&gt;当broker把消息投递给消费者后，消费者可以立即响应我收到了这个消息。但收到了这个消息只是第一步，我能不能处理这个消息却不一定。或许因为消费能力的问题，系统的负荷已经不能处理这个消息；或者是刚才状态机里面提到的消息不是我想要接收的消息，主动要求重发。&lt;/p&gt;
&lt;p&gt;把消息的送达和消息的处理分开，这样才真正的实现了消息队列的本质-解耦。所以，允许消费者主动进行消费确认是必要的。当然，对于没有特殊逻辑的消息，默认Auto Ack也是可以的，但一定要允许消费方主动ack。&lt;/p&gt;
&lt;p&gt;对于正确消费ack的，没什么特殊的。但是对于reject和error，需要特别说明。reject这件事情，往往业务方是无法感知到的，系统的流量和健康状况的评估，以及处理能力的评估是一件非常复杂的事情。举个极端的例子，收到一个消息开始build索引，可能这个消息要处理半个小时，但消息量却是非常的小。所以reject这块建议做成滑动窗口/线程池类似的模型来控制，消费能力不匹配的时候，直接拒绝，过一段时间重发，减少业务的负担。&lt;/p&gt;
&lt;p&gt;但业务出错这件事情是只有业务方自己知道的，就像上文提到的状态机等等。这时应该允许业务方主动ack error，并可以与broker约定下次投递的时间。&lt;/p&gt;
&lt;h4 id=&quot;2312-重复消息和顺序消息&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2312-%E9%87%8D%E5%A4%8D%E6%B6%88%E6%81%AF%E5%92%8C%E9%A1%BA%E5%BA%8F%E6%B6%88%E6%81%AF&quot; aria-label=&quot;2312 重复消息和顺序消息 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.1.2 重复消息和顺序消息&lt;/h4&gt;
&lt;p&gt;上文谈到重复消息是不可能100%避免的，除非可以允许丢失，那么，顺序消息能否100%满足呢? 答案是可以，但条件更为苛刻：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;允许消息丢失。&lt;/li&gt;
&lt;li&gt;从发送方到服务方到接受者都是单点单线程。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以绝对的顺序消息基本上是不能实现的，当然在METAQ/Kafka等pull模型的消息队列中，单线程生产/消费，排除消息丢失，也是一种顺序消息的解决方案。&lt;/p&gt;
&lt;p&gt;一般来讲，一个主流消息队列的设计范式里，应该是不丢消息的前提下，尽量减少重复消息，不保证消息的投递顺序。&lt;/p&gt;
&lt;p&gt;谈到重复消息，主要是两个话题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如何鉴别消息重复，并幂等的处理重复消息。&lt;/li&gt;
&lt;li&gt;一个消息队列如何尽量减少重复消息的投递。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;先来看看第一个话题，每一个消息应该有它的唯一身份。不管是业务方自定义的，还是根据IP/PID/时间戳生成的MessageId，如果有地方记录这个MessageId，消息到来是能够进行比对就能完成重复的鉴定。数据库的唯一键/bloom filter/分布式KV中的key，都是不错的选择。由于消息不能被永久存储，所以理论上都存在消息从持久化存储移除的瞬间上游还在投递的可能（上游因种种原因投递失败，不停重试，都到了下游清理消息的时间）。这种事情都是异常情况下才会发生的，毕竟是小众情况。两分钟消息都还没送达，多送一次又能怎样呢？幂等的处理消息是一门艺术，因为种种原因重复消息或者错乱的消息还是来到了，说两种通用的解决方案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;版本号。&lt;/li&gt;
&lt;li&gt;状态机。&lt;/li&gt;
&lt;/ol&gt;
&lt;h5 id=&quot;版本号&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%89%88%E6%9C%AC%E5%8F%B7&quot; aria-label=&quot;版本号 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;版本号&lt;/h5&gt;
&lt;p&gt;举个简单的例子，一个产品的状态有上线/下线状态。如果消息1是下线，消息2是上线。不巧消息1判重失败，被投递了两次，且第二次发生在2之后，如果不做重复性判断，显然最终状态是错误的。&lt;/p&gt;
&lt;p&gt;但是，如果每个消息自带一个版本号。上游发送的时候，标记消息1版本号是1，消息2版本号是2。如果再发送下线消息，则版本号标记为3。下游对于每次消息的处理，同时维护一个版本号。&lt;/p&gt;
&lt;p&gt;每次只接受比当前版本号大的消息。初始版本为0，当消息1到达时，将版本号更新为1。消息2到来时，因为版本号&gt;1.可以接收，同时更新版本号为2.当另一条下线消息到来时，如果版本号是3.则是真实的下线消息。如果是1，则是重复投递的消息。&lt;/p&gt;
&lt;p&gt;如果业务方只关心消息重复不重复，那么问题就已经解决了。但很多时候另一个头疼的问题来了，就是消息顺序如果和想象的顺序不一致。比如应该的顺序是12，到来的顺序是21。则最后会发生状态错误。&lt;/p&gt;
&lt;p&gt;参考TCP/IP协议，如果想让乱序的消息最后能够正确的被组织，那么就应该只接收比当前版本号大一的消息。并且在一个session周期内要一直保存各个消息的版本号。&lt;/p&gt;
&lt;p&gt;如果到来的顺序是21，则先把2存起来，待2到来后，再处理1，这样重复性和顺序性要求就都达到了。&lt;/p&gt;
&lt;h5 id=&quot;状态机&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%8A%B6%E6%80%81%E6%9C%BA&quot; aria-label=&quot;状态机 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;状态机&lt;/h5&gt;
&lt;p&gt;基于版本号来处理重复和顺序消息听起来是个不错的主意，但凡事总有瑕疵。使用版本号的最大问题是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对发送方必须要求消息带业务版本号。&lt;/li&gt;
&lt;li&gt;下游必须存储消息的版本号，对于要严格保证顺序的。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;还不能只存储最新的版本号的消息，要把乱序到来的消息都存储起来。而且必须要对此做出处理。试想一个永不过期的”session”，比如一个物品的状态，会不停流转于上下线。那么中间环节的所有存储就必须保留，直到在某个版本号之前的版本一个不丢的到来，成本太高。&lt;/p&gt;
&lt;p&gt;就刚才的场景看，如果消息没有版本号，该怎么解决呢？业务方只需要自己维护一个状态机，定义各种状态的流转关系。例如，“下线”状态只允许接收”上线”消息，“上线”状态只能接收“下线消息”，如果上线收到上线消息，或者下线收到下线消息，在消息不丢失和上游业务正确的前提下。要么是消息发重了，要么是顺序到达反了。这时消费者只需要把“我不能处理这个消息”告诉投递者，要求投递者过一段时间重发即可。而且重发一定要有次数限制，比如5次，避免死循环，就解决了。&lt;/p&gt;
&lt;p&gt;举例子说明，假设产品本身状态是下线，1是上线消息，2是下线消息，3是上线消息，正常情况下，消息应该的到来顺序是123，但实际情况下收到的消息状态变成了3123。&lt;/p&gt;
&lt;p&gt;那么下游收到3消息的时候，判断状态机流转是下线-&gt;上线，可以接收消息。然后收到消息1，发现是上线-&gt;上线，拒绝接收，要求重发。然后收到消息2，状态是上线-&gt;下线，于是接收这个消息。&lt;/p&gt;
&lt;p&gt;此时无论重发的消息1或者3到来，还是可以接收。另外的重发，在一定次数拒绝后停止重发，业务正确。&lt;/p&gt;
&lt;h4 id=&quot;2313-中间件对于重复消息的处理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2313-%E4%B8%AD%E9%97%B4%E4%BB%B6%E5%AF%B9%E4%BA%8E%E9%87%8D%E5%A4%8D%E6%B6%88%E6%81%AF%E7%9A%84%E5%A4%84%E7%90%86&quot; aria-label=&quot;2313 中间件对于重复消息的处理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.1.3 中间件对于重复消息的处理&lt;/h4&gt;
&lt;p&gt;回归到消息队列的话题来讲。上述通用的版本号/状态机/ID判重解决方案里，哪些是消息队列该做的、哪些是消息队列不该做业务方处理的呢？其实这里没有一个完全严格的定义，但回到我们的出发点，我们保证不丢失消息的情况下尽量少重复消息，消费顺序不保证。那么重复消息下和乱序消息下业务的正确，应该是由消费方保证的，我们要做的是减少消息发送的重复。&lt;/p&gt;
&lt;p&gt;我们无法定义业务方的业务版本号/状态机，如果API里强制需要指定版本号，则显得过于绑架客户了。况且，在消费方维护这么多状态，就涉及到一个消费方的消息落地/多机间的同步消费状态问题，复杂度指数级上升，而且只能解决部分问题。&lt;/p&gt;
&lt;p&gt;减少重复消息的关键步骤：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;broker记录MessageId，直到投递成功后清除，重复的ID到来不做处理，这样只要发送者在清除周期内能够感知到消息投递成功，就基本不会在server端产生重复消息。&lt;/li&gt;
&lt;li&gt;对于server投递到consumer的消息，由于不确定对端是在处理过程中还是消息发送丢失的情况下，有必要记录下投递的IP地址。决定重发之前询问这个IP，消息处理成功了吗？如果询问无果，再重发。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;232-事务&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#232-%E4%BA%8B%E5%8A%A1&quot; aria-label=&quot;232 事务 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.2 事务&lt;/h3&gt;
&lt;p&gt;持久性是事务的一个特性，然而只满足持久性却不一定能满足事务的特性。还是拿扣钱/加钱的例子讲。满足事务的一致性特征，则必须要么都不进行，要么都能成功。&lt;/p&gt;
&lt;p&gt;解决方案从大方向上有两种：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;两阶段提交，分布式事务。&lt;/li&gt;
&lt;li&gt;本地事务，本地落地，补偿发送。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;分布式事务存在的最大问题是成本太高，两阶段提交协议，对于仲裁down机或者单点故障，几乎是一个无解的黑洞。对于交易密集型或者I/O密集型的应用，没有办法承受这么高的网络延迟，系统复杂性。&lt;/p&gt;
&lt;p&gt;并且成熟的分布式事务一定构建与比较靠谱的商用DB和商用中间件上，成本也太高。&lt;/p&gt;
&lt;p&gt;那如何使用本地事务解决分布式事务的问题呢？以本地和业务在一个数据库实例中建表为例子，与扣钱的业务操作同一个事务里，将消息插入本地数据库。如果消息入库失败，则业务回滚；如果消息入库成功，事务提交。&lt;/p&gt;
&lt;p&gt;然后发送消息（注意这里可以实时发送，不需要等定时任务检出，以提高消息实时性）。以后的问题就是前文的最终一致性问题所提到的了，只要消息没有发送成功，就一直靠定时任务重试。&lt;/p&gt;
&lt;p&gt;这里有一个关键的点，本地事务做的，是业务落地和消息落地的事务，而不是业务落地和RPC成功的事务。这里很多人容易混淆，如果是后者，无疑是事务嵌套RPC，是大忌，会有长事务死锁等各种风险。&lt;/p&gt;
&lt;p&gt;而消息只要成功落地，很大程度上就没有丢失的风险（磁盘物理损坏除外）。而消息只要投递到服务端确认后本地才做删除，就完成了producer-&gt;broker的可靠投递，并且当消息存储异常时，业务也是可以回滚的。&lt;/p&gt;
&lt;p&gt;本地事务存在两个最大的使用障碍：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;配置较为复杂，“绑架”业务方，必须本地数据库实例提供一个库表。&lt;/li&gt;
&lt;li&gt;对于消息延迟高敏感的业务不适用。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;话说回来，不是每个业务都需要强事务的。扣钱和加钱需要事务保证，但下单和生成短信却不需要事务，不能因为要求发短信的消息存储投递失败而要求下单业务回滚。所以，一个完整的消息队列应该定义清楚自己可以投递的消息类型，如事务型消息，本地非持久型消息，以及服务端不落地的非可靠消息等。对不同的业务场景做不同的选择。另外事务的使用应该尽量低成本、透明化，可以依托于现有的成熟框架，如Spring的声明式事务做扩展。业务方只需要使用@Transactional标签即可。&lt;/p&gt;
&lt;h3 id=&quot;233-性能相关&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#233-%E6%80%A7%E8%83%BD%E7%9B%B8%E5%85%B3&quot; aria-label=&quot;233 性能相关 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.3 性能相关&lt;/h3&gt;
&lt;h4 id=&quot;2331-异步同步&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2331-%E5%BC%82%E6%AD%A5%E5%90%8C%E6%AD%A5&quot; aria-label=&quot;2331 异步同步 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.3.1 异步/同步&lt;/h4&gt;
&lt;p&gt;首先澄清一个概念，异步，同步和oneway是三件事。异步，归根结底你还是需要关心结果的，但可能不是当时的时间点关心，可以用轮询或者回调等方式处理结果；同步是需要当时关心的结果的；而oneway是发出去就不管死活的方式，这种对于某些完全对可靠性没有要求的场景还是适用的，但不是我们重点讨论的范畴。&lt;/p&gt;
&lt;p&gt;回归来看，任何的RPC都是存在客户端异步与服务端异步的，而且是可以任意组合的：客户端同步对服务端异步，客户端异步对服务端异步，客户端同步对服务端同步，客户端异步对服务端同步。&lt;/p&gt;
&lt;p&gt;对于客户端来说，同步与异步主要是拿到一个Result，还是Future(Listenable)的区别。实现方式可以是线程池，NIO或者其他事件机制，这里先不展开讲。&lt;/p&gt;
&lt;p&gt;服务端异步可能稍微难理解一点，这个是需要RPC协议支持的。参考servlet 3.0规范，服务端可以吐一个future给客户端，并且在future done的时候通知客户端。&lt;/p&gt;
&lt;p&gt;整个过程可以参考下面的代码：&lt;/p&gt;
&lt;p&gt;客户端同步服务端异步。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; future &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// server立刻返回future&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;synchronized&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;future&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isDone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
       future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;wait&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// server处理结束后会notify这个future，并修改isdone标志&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;客户端同步服务端同步。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;客户端异步服务端同步(这里用线程池的方式)。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; future &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Callable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; call&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;客户端异步服务端异步。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Future&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Result&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; future &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// server立刻返回future&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; future&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上面说了这么多，其实是想让大家脱离两个误区：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;RPC只有客户端能做异步，服务端不能。&lt;/li&gt;
&lt;li&gt;异步只能通过线程池。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;那么，服务端使用异步最大的好处是什么呢？说到底，是解放了线程和I/O。试想服务端有一堆I/O等待处理，如果每个请求都需要同步响应，每条消息都需要结果立刻返回，那么就几乎没法做I/O合并（当然接口可以设计成batch的，但可能batch发过来的仍然数量较少）。而如果用异步的方式返回给客户端future，就可以有机会进行I/O的合并，把几个批次发过来的消息一起落地（这种合并对于MySQL等允许batch insert的数据库效果尤其明显），并且彻底释放了线程。不至于说来多少请求开多少线程，能够支持的并发量直线提高。&lt;/p&gt;
&lt;p&gt;来看第二个误区，返回future的方式不一定只有线程池。换句话说，可以在线程池里面进行同步操作，也可以进行异步操作，也可以不使用线程池使用异步操作（NIO、事件）。&lt;/p&gt;
&lt;p&gt;回到消息队列的议题上，我们当然不希望消息的发送阻塞主流程（前面提到了，server端如果使用异步模型，则可能因消息合并带来一定程度上的消息延迟），所以可以先使用线程池提交一个发送请求，主流程继续往下走。&lt;/p&gt;
&lt;p&gt;但是线程池中的请求关心结果吗？Of course，必须等待服务端消息成功落地，才算是消息发送成功。所以这里的模型，准确地说事客户端半同步半异步（使用线程池不阻塞主流程，但线程池中的任务需要等待server端的返回），server端是纯异步。客户端的线程池wait在server端吐回的future上，直到server端处理完毕，才解除阻塞继续进行。&lt;/p&gt;
&lt;p&gt;总结一句，同步能够保证结果，异步能够保证效率，要合理的结合才能做到最好的效率。&lt;/p&gt;
&lt;h4 id=&quot;2332-批量&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2332-%E6%89%B9%E9%87%8F&quot; aria-label=&quot;2332 批量 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.3.2 批量&lt;/h4&gt;
&lt;p&gt;谈到批量就不得不提生产者消费者模型。但生产者消费者模型中最大的痛点是：消费者到底应该何时进行消费。大处着眼来看，消费动作都是事件驱动的。主要事件包括：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;攒够了一定数量。&lt;/li&gt;
&lt;li&gt;到达了一定时间。&lt;/li&gt;
&lt;li&gt;队列里有新的数据到来。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于及时性要求高的数据，可用采用方式3来完成，比如客户端向服务端投递数据。只要队列有数据，就把队列中的所有数据刷出，否则将自己挂起，等待新数据的到来。&lt;/p&gt;
&lt;p&gt;在第一次把队列数据往外刷的过程中，又积攒了一部分数据，第二次又可以形成一个批量。伪代码如下:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Executor&lt;/span&gt; executor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Executors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newFixedThreadPool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BlockingQueue&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; queue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayBlockingQueue&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Runnable&lt;/span&gt; task &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Runnable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 这里由于共享队列，Runnable可以复用，故做成全局的&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; messages  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;drainTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;messages，&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;doSend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 阻塞，在这个过程中会有新的消息到来，如果4个线程都占满，队列就有机会囤新的消息&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Message&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;offer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这种方式是消息延迟和批量的一个比较好的平衡，但优先响应低延迟。延迟的最高程度由上一次发送的等待时间决定。但可能造成的问题是发送过快的话批量的大小不够满足性能的极致。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Executor&lt;/span&gt; executor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Executors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newFixedThreadPool&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BlockingQueue&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; queue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayBlockingQueue&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;volatile&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;long&lt;/span&gt; last &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;currentMills&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token class-name&quot;&gt;Executors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newSingleThreadScheduledExecutor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Runnable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token function&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;，&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;，&lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;，&lt;span class=&quot;token class-name&quot;&gt;TimeUnits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;MILLS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Runnable&lt;/span&gt; task &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Runnable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 这里由于共享队列，Runnable可以复用，顾做成全局的。&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; messages  &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;drainTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;messages，&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;doSend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;messages&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 阻塞，在这个过程中会有新的消息到来，如果4个线程都占满，队列就有机会屯新的消息。&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Message&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    last &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;currentMills&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;offer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;flush&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;currentMills&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; last &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
       executor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;submit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;task&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;相反对于可以用适量的延迟来换取高性能的场景来说，用定时/定量二选一的方式可能会更为理想，既到达一定数量才发送，但如果数量一直达不到，也不能干等，有一个时间上限。&lt;/p&gt;
&lt;p&gt;具体说来，在上文的submit之前，多判断一个时间和数量，并且Runnable内部维护一个定时器，避免没有新任务到来时旧的任务永远没有机会触发发送条件。对于server端的数据落地，使用这种方式就非常方便。&lt;/p&gt;
&lt;p&gt;最后啰嗦几句，曾经有人问我，为什么网络请求小包合并成大包会提高性能？主要原因有两个：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;减少无谓的请求头，如果你每个请求只有几字节，而头却有几十字节，无疑效率非常低下。&lt;/li&gt;
&lt;li&gt;减少回复的ack包个数。把请求合并后，ack包数量必然减少，确认和重发的成本就会降低。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;24-push还是pull&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#24-push%E8%BF%98%E6%98%AFpull&quot; aria-label=&quot;24 push还是pull permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4 push还是pull&lt;/h2&gt;
&lt;p&gt;上文提到的消息队列，大多是针对push模型的设计。现在市面上有很多经典的也比较成熟的pull模型的消息队列，如Kafka、MetaQ等。这跟JMS中传统的push方式有很大的区别，可谓另辟蹊径。&lt;/p&gt;
&lt;p&gt;我们简要分析下push和pull模型各自存在的利弊。&lt;/p&gt;
&lt;h3 id=&quot;241-慢消费&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#241-%E6%85%A2%E6%B6%88%E8%B4%B9&quot; aria-label=&quot;241 慢消费 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4.1 慢消费&lt;/h3&gt;
&lt;p&gt;慢消费无疑是push模型最大的致命伤，穿成流水线来看，如果消费者的速度比发送者的速度慢很多，势必造成消息在broker的堆积。假设这些消息都是有用的无法丢弃的，消息就要一直在broker端保存。当然这还不是最致命的，最致命的是broker给consumer推送一堆consumer无法处理的消息，consumer不是reject就是error，然后来回踢皮球。&lt;/p&gt;
&lt;p&gt;反观pull模式，consumer可以按需消费，不用担心自己处理不了的消息来骚扰自己，而broker堆积消息也会相对简单，无需记录每一个要发送消息的状态，只需要维护所有消息的队列和偏移量就可以了。所以对于建立索引等慢消费，消息量有限且到来的速度不均匀的情况，pull模式比较合适。&lt;/p&gt;
&lt;h3 id=&quot;242-消息延迟与忙等&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#242-%E6%B6%88%E6%81%AF%E5%BB%B6%E8%BF%9F%E4%B8%8E%E5%BF%99%E7%AD%89&quot; aria-label=&quot;242 消息延迟与忙等 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4.2 消息延迟与忙等&lt;/h3&gt;
&lt;p&gt;这是pull模式最大的短板。由于主动权在消费方，消费方无法准确地决定何时去拉取最新的消息。如果一次pull取到消息了还可以继续去pull，如果没有pull取到则需要等待一段时间重新pull。&lt;/p&gt;
&lt;p&gt;但等待多久就很难判定了。你可能会说，我可以有xx动态pull取时间调整算法，但问题的本质在于，有没有消息到来这件事情决定权不在消费方。也许1分钟内连续来了1000条消息，然后半个小时没有新消息产生，可能你的算法算出下次最有可能到来的时间点是31分钟之后，或者60分钟之后，结果下条消息10分钟后到了，是不是很让人沮丧？当然也不是说延迟就没有解决方案了，业界较成熟的做法是从短时间开始（不会对broker有太大负担），然后指数级增长等待。比如开始等5ms，然后10ms，然后20ms，然后40ms……直到有消息到来，然后再回到5ms。&lt;/p&gt;
&lt;p&gt;即使这样，依然存在延迟问题：假设40ms到80ms之间的50ms消息到来，消息就延迟了30ms，而且对于半个小时来一次的消息，这些开销就是白白浪费的。&lt;/p&gt;
&lt;p&gt;在阿里的RocketMq里，有一种优化的做法-长轮询，来平衡推拉模型各自的缺点。基本思路是:消费者如果尝试拉取失败，不是直接return,而是把连接挂在那里wait,服务端如果有新的消息到来，把连接notify起来，这也是不错的思路。但海量的长连接block对系统的开销还是不容小觑的，还是要合理的评估时间间隔，给wait加一个时间上限比较好~&lt;/p&gt;
&lt;h3 id=&quot;243-顺序消息&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#243-%E9%A1%BA%E5%BA%8F%E6%B6%88%E6%81%AF&quot; aria-label=&quot;243 顺序消息 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4.3 顺序消息&lt;/h3&gt;
&lt;p&gt;如果push模式的消息队列，支持分区，单分区只支持一个消费者消费，并且消费者只有确认一个消息消费后才能push送另外一个消息，还要发送者保证全局顺序唯一，听起来也能做顺序消息，但成本太高了，尤其是必须每个消息消费确认后才能发下一条消息，这对于本身堆积能力和慢消费就是瓶颈的push模式的消息队列，简直是一场灾难。&lt;/p&gt;
&lt;p&gt;反观pull模式，如果想做到全局顺序消息，就相对容易很多：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;producer对应partition，并且单线程。&lt;/li&gt;
&lt;li&gt;consumer对应partition，消费确认（或批量确认），继续消费即可。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以对于日志push送这种最好全局有序，但允许出现小误差的场景，pull模式非常合适。如果你不想看到通篇乱套的日志~~Anyway，需要顺序消息的场景还是比较有限的而且成本太高，请慎重考虑。&lt;/p&gt;
&lt;h1 id=&quot;3-总结&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E6%80%BB%E7%BB%93&quot; aria-label=&quot;3 总结 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 总结&lt;/h1&gt;
&lt;p&gt;本文从为何使用消息队列开始讲起，然后主要介绍了如何从零开始设计一个消息队列，包括RPC、事务、最终一致性、广播、消息确认等关键问题。并对消息队列的push、pull模型做了简要分析，最后从批量和异步角度，分析了消息队列性能优化的思路。下篇会着重介绍一些高级话题，如存储系统的设计、流控和错峰的设计、公平调度等。希望通过这些，让大家对消息队列有个提纲挈领的整体认识，并给自主开发消息队列提供思路。另外，本文主要是源自自己在开发消息队列中的思考和读源码时的体会，比较不”官方”，也难免会存在一些漏洞，欢迎大家多多交流。&lt;/p&gt;
&lt;p&gt;后续我们还会推出消息队列设计高级篇，内容会涵盖以下方面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pull模型消息系统设计理念&lt;/li&gt;
&lt;li&gt;存储子系统设计&lt;/li&gt;
&lt;li&gt;流量控制&lt;/li&gt;
&lt;li&gt;公平调度&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;敬请期待哦~&lt;/p&gt;
&lt;h2 id=&quot;作者简介&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E4%BD%9C%E8%80%85%E7%AE%80%E4%BB%8B&quot; aria-label=&quot;作者简介 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;作者简介&lt;/h2&gt;
&lt;p&gt;王烨，现在是美团旅游后台研发组的程序猿，之前曾经在百度、去哪和优酷工作过，专注Java后台开发。对于网络编程和并发编程具有浓厚的兴趣，曾经做过一些基础组件，也翻过一些源码，属于比较典型的宅男技术控。期待能够与更多知己，在coding的路上并肩前行~&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Elasticsearch Notes]]></title><link>https://xenojoshua.com/posts/2019/04/elasticsearch-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/elasticsearch-note</guid><pubDate>Thu, 25 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-log-shipper&quot;&gt;2. Log Shipper&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E6%A8%AA%E5%90%91%E6%AF%94%E8%BE%83--%E9%80%89%E6%8B%A9&quot;&gt;2.1 横向比较 &amp;#x26; 选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1&quot;&gt;2.2 架构设计&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-filebeat&quot;&gt;3. Filebeat&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E8%AE%BE%E8%AE%A1--%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5&quot;&gt;3.1 设计 &amp;#x26; 基础概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E4%BD%BF%E7%94%A8&quot;&gt;3.2 使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E6%A8%A1%E5%9D%97&quot;&gt;3.3 模块&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-%E8%BF%87%E6%BB%A4%E5%92%8C%E4%B8%B0%E5%AF%8C&quot;&gt;3.4 过滤和丰富&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-%E6%96%87%E4%BB%B6%E7%8A%B6%E6%80%81%E8%AE%B0%E5%BD%95--%E6%8A%95%E9%80%92%E4%BF%9D%E8%AF%81&quot;&gt;3.5 文件状态记录 &amp;#x26; 投递保证&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-elasticsearch&quot;&gt;4. Elasticsearch&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E7%9F%A5%E8%AF%86%E7%82%B9&quot;&gt;4.1 知识点&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#411-%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5&quot;&gt;4.1.1 基础概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#412-%E5%AE%89%E8%A3%85--%E9%85%8D%E7%BD%AE&quot;&gt;4.1.2 安装 &amp;#x26; 配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#413-api&quot;&gt;4.1.3 API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#414-query-dsl&quot;&gt;4.1.4 Query DSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#415-sql&quot;&gt;4.1.5 SQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#416-ingest%E8%8A%82%E7%82%B9&quot;&gt;4.1.6 Ingest节点&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E6%96%87%E6%A1%A3%E6%95%B0%E6%8D%AE%E5%BA%93--%E7%B4%A2%E5%BC%95-id_index&quot;&gt;4.2 文档数据库 &amp;#x26; 索引 {#ID_INDEX}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#421-index-template&quot;&gt;4.2.1 Index Template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#422-%E8%AE%BE%E7%BD%AEindex%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F&quot;&gt;4.2.2 设置index生命周期&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#423-index%E7%9A%84%E8%87%AA%E5%8A%A8%E5%88%9B%E5%BB%BA%E8%AE%BE%E7%BD%AE&quot;&gt;4.2.3 Index的自动创建设置&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E5%AD%98%E5%82%A8-id_storage&quot;&gt;4.3 存储 {#ID_STORAGE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E9%9B%86%E7%BE%A4-id_arc_cluster&quot;&gt;4.4 集群 {#ID_ARC_CLUSTER}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#45-%E7%9B%91%E6%8E%A7--%E9%AB%98%E5%8F%AF%E7%94%A8&quot;&gt;4.5 监控 &amp;#x26; 高可用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#451-%E7%9B%91%E6%8E%A7&quot;&gt;4.5.1 监控&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#452-%E7%9B%91%E6%8E%A7%E5%AE%9E%E8%B7%B5&quot;&gt;4.5.2 监控实践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#453-%E9%AB%98%E5%8F%AF%E7%94%A8&quot;&gt;4.5.3 高可用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#46-%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98&quot;&gt;4.6 性能调优&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-kibana&quot;&gt;5. Kibana&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-index-pattern-id_index_pattern&quot;&gt;5.1 Index Pattern {#ID_INDEX_PATTERN}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E4%BD%BF%E7%94%A8%E7%AE%80%E4%BB%8B&quot;&gt;5.2 使用简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#53-qa&quot;&gt;5.3 Q&amp;#x26;A&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-filebeat%E7%9B%B4%E8%BF%9Eelasticsearch%E5%AE%9E%E8%B7%B5&quot;&gt;6. Filebeat直连Elasticsearch实践&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-%E7%9B%B4%E8%BF%9E%E6%B5%81%E7%A8%8B&quot;&gt;6.1 直连流程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF&quot;&gt;6.2 应用场景&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#63-index-template-id_index_template&quot;&gt;6.3 Index Template {#ID_INDEX_TEMPLATE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#64-issues&quot;&gt;6.4 Issues&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#641-filebeat%E5%AD%97%E6%AE%B5%E5%B1%82%E7%BA%A7&quot;&gt;6.4.1 Filebeat字段层级&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#642-kibana-message%E5%AD%97%E6%AE%B5&quot;&gt;6.4.2 Kibana message字段&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#643-input--processors-fields&quot;&gt;6.4.3 input | processors fields&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#644-index-template%E8%AE%BE%E7%BD%AE-id_filebeat_index_template&quot;&gt;6.4.4 Index Template设置 {#ID_FILEBEAT_INDEX_TEMPLATE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#645-%E5%88%87%E7%89%87%E6%95%B0%E9%87%8F&quot;&gt;6.4.5 切片数量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#646-kibana-timestamp&quot;&gt;6.4.6 Kibana @timestamp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#647-elasticsearch-%E9%A2%84%E5%88%9B%E5%BB%BA%E6%95%B0%E6%8D%AE&quot;&gt;6.4.7 Elasticsearch 预创建数据&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-%E5%AE%9E%E8%B7%B5%E8%8C%83%E4%BE%8B&quot;&gt;7. 实践范例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-docker%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2&quot;&gt;8. Docker集群部署&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#81-elasticsearch%E9%85%8D%E7%BD%AE-id_es_config&quot;&gt;8.1 Elasticsearch配置 {#ID_ES_CONFIG}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#811-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E9%85%8D%E7%BD%AE&quot;&gt;8.1.1 环境变量配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#812-%E5%A4%9A%E8%8A%82%E7%82%B9%E9%85%8D%E7%BD%AE%E7%9A%84%E5%85%B1%E4%BA%AB&quot;&gt;8.1.2 多节点配置的共享&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#813-%E9%9B%86%E7%BE%A4%E5%8F%91%E7%8E%B0%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE&quot;&gt;8.1.3 集群发现相关配置&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#82-kibana%E9%85%8D%E7%BD%AE&quot;&gt;8.2 Kibana配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#83-filebeat%E9%85%8D%E7%BD%AE&quot;&gt;8.3 Filebeat配置&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#9-todo&quot;&gt;9. TODO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;之前做了Prometheus和Jaeger相关的调研工作，这两者虽然也涉及到日志聚合相关的技术或是类似的技术，但毕竟不是通用的日志聚合系统。通用的日志聚合系统需要能接受任何类型的日志，并将其索引入库以备后续的查询。市面上这方面的产品现在基本上是Elasticsearch为主要选择，已经可以说是很成熟了。所以这块需求我这里也是以ELK为第一备选进行相关的调研。&lt;/p&gt;
&lt;p&gt;后续的调研内容版本如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;elasticsearch 7.0.0
elastic/filebeat 7.0.0
kibana 7.0.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在提到Elasticsearch的时候我们一般不会只说Elasticsearch本身，而是会提到&lt;code class=&quot;language-text&quot;&gt;ELK&lt;/code&gt;这个词，这里说的其实就是从日志采集、清洗、转换、分发、到最后入库的整个流程，以及查询用的面板包含在内的一整套生态。因此下面行文会从：日志采集、日志存储、日志查询三方面着手。&lt;/p&gt;
&lt;p&gt;官方文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elastic Stack and Product Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Filebeat Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kibana User Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-log-shipper&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-log-shipper&quot; aria-label=&quot;2 log shipper permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. Log Shipper&lt;/h1&gt;
&lt;p&gt;日志是在各个应用程序中生产的，此外也包括了操作系统级别的日志生产。因此日志的产生这个行为是分散在各个节点上的，日志的收集就是从分散的节点采集数据汇集到中心存储的一个过程，这也是所谓的&lt;code class=&quot;language-text&quot;&gt;聚合&lt;/code&gt;。而从分散的节点上采集数据，我们需要Agent（Log Shipper）来执行这个操作。&lt;/p&gt;
&lt;p&gt;经典的&lt;code class=&quot;language-text&quot;&gt;ELK&lt;/code&gt;中，&lt;code class=&quot;language-text&quot;&gt;L&lt;/code&gt;代表的就是日志采集Agent：Logstash。当然，市面上也有非常多的其他选择，可以做到和Logstash类似的功能。从系统设计上来说，ELK三者本身是完全解耦分离的，所以所谓的ELK堆栈，只是一种经过验证的实践方案，其实中间除了E之外，L和K都是可以自由更换的。&lt;/p&gt;
&lt;h2 id=&quot;21-横向比较--选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E6%A8%AA%E5%90%91%E6%AF%94%E8%BE%83--%E9%80%89%E6%8B%A9&quot; aria-label=&quot;21 横向比较  选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 横向比较 &amp;#x26; 选择&lt;/h2&gt;
&lt;p&gt;关于日志采集组件的备选有大量横向比较，推荐阅读：&lt;a href=&quot;https://sematext.com/blog/logstash-alternatives/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;5 Logstash Alternatives&lt;/a&gt;。这篇的时间还算比较新&lt;code class=&quot;language-text&quot;&gt;2018-10-09&lt;/code&gt;，讲解也非常到位，基本上看这篇就OK了。&lt;/p&gt;
&lt;p&gt;此外，&lt;a href=&quot;https://gist.github.com/StevenACoffman/4e267f0f60c8e7fcb3f77b9e504f3bd7&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;StevenACoffman/fluent-filebeat-comparison.md&lt;/a&gt;也可以看下。&lt;/p&gt;
&lt;p&gt;排除比较年轻的项目，以及资历不太雄厚的项目，剩下的主要选项有三个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Logstash
&lt;ul&gt;
&lt;li&gt;优势：功能强大；经过实践检验&lt;/li&gt;
&lt;li&gt;劣势：资源占用过大；JVM&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Filebeat
&lt;ul&gt;
&lt;li&gt;优势：Go语言；部署简单；资源占用极小&lt;/li&gt;
&lt;li&gt;劣势：功能相对简单&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Fluentd
&lt;ul&gt;
&lt;li&gt;优势：CNCF孵化项目&lt;/li&gt;
&lt;li&gt;劣势：Ruby语言实现&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Log Shipper作为每个应用程序都需要附加的边车组件其中之一，Logstash的内存和CPU消耗在某些情况下是完全不能接受的（1GB内存，开玩笑）。JVM众所周知是比较难搞的虚拟机，如果要用好，调优需要有非常专门的知识，所以算是一个减分项。但放在Elasticsearch堆栈上来说，倒也不是那么严重，因为你无论如何都需要JVM知识来调优Elasticsearch本身。功能强大是Logstash的最大优势，能满足基本上所有的应用场景，在某些架构上，即便使用了Filebeat等高效轻量级的Log Shipper，在进入Elasticsearch入库之前仍旧需要一个Logstash来进行转换等工作。&lt;/p&gt;
&lt;p&gt;Filebeat基本上没有缺点，如果它的功能能满足你的需求的话。如果不能满足，那么最新的Kafka输出能解决你的问题。使用Filebeat作为边车的Log Shipper，输出到Kafka，然后使用Logstash或者自己编写的组件来消费Kafka里的日志，最终入库到Elasticsearch。&lt;/p&gt;
&lt;p&gt;Fluentd的最大优势在于CNCF的加持（背书）。但基于我多年的编程经验，ruby的性能一般来说是不可靠的，甚至使用JVM的Logstash都已经为性能付出了过大的代价，我又有什么理由要去相信口碑一直不怎么样的ruby呢。Logstash至少使用的JVM还和Elasticsearch本身是一个技术栈的，Fluentd会引入一个完全新的ruby虚拟机，就更加增加系统复杂度了。甚至，我在调研的初期就随手找到了：&lt;a href=&quot;https://github.com/fluent/fluentd/issues/1657&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Fluentd retains excessive amounts of memory after handling traffic peaks #1657&lt;/a&gt;，&lt;code class=&quot;language-text&quot;&gt;2017年&lt;/code&gt;的BUG，到现在还是&lt;code class=&quot;language-text&quot;&gt;Open状态&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;综上所述，任何情况下都应该使用Filebeat作为边车的Log Shipper。Filebeat能满足需求的直接入库到Elasticsearch，不能满足需求的日志进Kafka，然后使用Logstash或其他Consumer来进行转换，最终入库到Elasticsearch。&lt;/p&gt;
&lt;h2 id=&quot;22-架构设计&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1&quot; aria-label=&quot;22 架构设计 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 架构设计&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/log_shipper_arc.jpg&quot; alt=&quot;Architecture&quot;&gt;&lt;/p&gt;
&lt;p&gt;图中的Logstash部分可以替换成自编写的轻量级Consumer。&lt;/p&gt;
&lt;h1 id=&quot;3-filebeat&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-filebeat&quot; aria-label=&quot;3 filebeat permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Filebeat&lt;/h1&gt;
&lt;p&gt;非常细节的使用及配置，可以查看这篇中文的博客：&lt;a href=&quot;https://www.cnblogs.com/cjsblog/p/9495024.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Filebeat 模块与配置&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;31-设计--基础概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E8%AE%BE%E8%AE%A1--%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;31 设计  基础概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 设计 &amp;#x26; 基础概念&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/filebeat.png&quot; alt=&quot;Architecture&quot;&gt;&lt;/p&gt;
&lt;p&gt;这张图看看就好，意义不大。&lt;/p&gt;
&lt;p&gt;Filebeat是一种&lt;a href=&quot;https://www.elastic.co/cn/products/beats&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elastic Beat&lt;/a&gt;，其实现基于&lt;code class=&quot;language-text&quot;&gt;libbeat&lt;/code&gt;框架，更多的可以查看：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/libbeat/7.0/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Beats Platform Reference&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;工作流：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入：从指定的文件进行监控日志增加行为，并触发读取发送&lt;/li&gt;
&lt;li&gt;输出：可直接向Elasticsearch集群发送日志，也可以将日志输出到外部的消息队列（Kafka）里&lt;/li&gt;
&lt;li&gt;模块：对某些日志进行的采集行为及Elasticsearch集群对这些日志进行分析的配置化和固化&lt;/li&gt;
&lt;li&gt;消费：Elasticsearch集群解析日志入库，或从Kafka读取日志然后解析入库&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;32-使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;32 使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 使用&lt;/h2&gt;
&lt;p&gt;部分说明文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装请参照：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/filebeat-installation.html#filebeat-installation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Step 1: Install Filebeat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;配置请参照：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/filebeat-configuration.html#filebeat-configuration&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Step 2: Configure Filebeat&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;容器内运行：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/running-on-docker.html#running-on-docker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Running Filebeat on Docker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;33-模块&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E6%A8%A1%E5%9D%97&quot; aria-label=&quot;33 模块 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 模块&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/filebeat-modules-overview.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Modules overview&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Elasticsearch Ingest Node pipeline definition, which is used to parse the log lines.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;首先明确一点，Filebeat的模块并不是一般意义上的&lt;code class=&quot;language-text&quot;&gt;功能模块&lt;/code&gt;。按软件设计思维来说，模块意味着功能的拓展，意味着根据模块设计的要求（框架）可以将软件本身能做的事情大幅拓展。而Filebeat的模块则不是，在Filebeat里，模块意味着一系列既有行为的组合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nginx有两个日志：access和error&lt;/li&gt;
&lt;li&gt;Nginx在Elasticsearch上处理的Ingest Pipeline是XXX&lt;/li&gt;
&lt;li&gt;Nginx的日志格式是XXX，Elasticsearch里对应的字段是XXX&lt;/li&gt;
&lt;li&gt;Nginx日志对应的Kibana面板有XXX，可以看到XXX数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从上面的例子可见：Filebeat本身并没有做什么，它做的仍旧只是采集日志，发送出去，没了。只不过指定了Elasticsearch集群中处理这个日志的Ingest Pipeline是谁，日志应该怎么入库（事情是在Elasticsearch集群上完成的）。因此在功能性上Filebeat是&lt;code class=&quot;language-text&quot;&gt;不可能替代&lt;/code&gt;Logstash的，它的定位只是轻量级的应用端Log Shipper，如果要在功能上覆盖Logstash的功能点，就需要使用Elasticsearch自身的Ingest Pipeline，仍旧需要Filebeat以外的系统支持。&lt;/p&gt;
&lt;p&gt;部分文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如何创建一个新的模块：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/devguide/7.0/filebeat-modules-devguide.html#filebeat-modules-devguide&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Creating a New Filebeat Module&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;模块清单：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/filebeat-modules.html#filebeat-modules&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;命令行列出模块：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; filebeat &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    elastic/filebeat:7.0.0 modules list&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;34-过滤和丰富&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-%E8%BF%87%E6%BB%A4%E5%92%8C%E4%B8%B0%E5%AF%8C&quot; aria-label=&quot;34 过滤和丰富 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 过滤和丰富&lt;/h2&gt;
&lt;p&gt;Filebeat可以在配置中指定一些受限的过滤和清洗功能：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/filtering-and-enhancing-data.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Filter and enhance the exported data&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;可选的processor清单有：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/defining-processors.html#processors&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Define processors&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;触发的条件：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/defining-processors.html#conditions&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Conditions&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;35-文件状态记录--投递保证&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#35-%E6%96%87%E4%BB%B6%E7%8A%B6%E6%80%81%E8%AE%B0%E5%BD%95--%E6%8A%95%E9%80%92%E4%BF%9D%E8%AF%81&quot; aria-label=&quot;35 文件状态记录  投递保证 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.5 文件状态记录 &amp;#x26; 投递保证&lt;/h2&gt;
&lt;p&gt;Filebeat对于输入的日志文件，会制作一个本地的注册文件，将状态都保存下来，因此在重启或者挂掉重新拉起来之后，Filebeat总是能知道之前发送到哪里。&lt;/p&gt;
&lt;p&gt;Filebeat会保证本地的日志文件至少被输出一次，如果在输出的结果返回之前Filebeat就挂掉的话，在下次Filebeat启动之后，它还会将之前最后的日志再投递一次（对于Filebeat来说，它并不知道自己死前已经投递过一次，并被输出方接收到了）。因此，收取数据的服务端&lt;code class=&quot;language-text&quot;&gt;可能&lt;/code&gt;在某些情况下收到&lt;code class=&quot;language-text&quot;&gt;重复的数据&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;4-elasticsearch&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-elasticsearch&quot; aria-label=&quot;4 elasticsearch permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Elasticsearch&lt;/h1&gt;
&lt;p&gt;2套电子书非常不错：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://fdv.github.io/running-elasticsearch-fun-profit/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Operating Elasticsearch for Fun and Profit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.xiaoleilu.com/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch 权威指南（中文版）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于作为Elasticsearch底层的Lucene有兴趣的，可以查看这篇：&lt;a href=&quot;https://www.infoq.cn/article/ejEG02VRoeGVaLw4j_LL&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Lucene 查询原理及解析&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;41-知识点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E7%9F%A5%E8%AF%86%E7%82%B9&quot; aria-label=&quot;41 知识点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 知识点&lt;/h2&gt;
&lt;p&gt;这一节基本上都是简单的知识点和概念罗列，主要阐明：“这是什么”。详细的内容会在后续的章节里分析。&lt;/p&gt;
&lt;h3 id=&quot;411-基础概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#411-%E5%9F%BA%E7%A1%80%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;411 基础概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.1 基础概念&lt;/h3&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/getting-started-concepts.html#getting-started-concepts&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Basic Concepts&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;提到了几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Near Realtime (NRT)&lt;/li&gt;
&lt;li&gt;Cluster&lt;/li&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;Index&lt;/li&gt;
&lt;li&gt;Document&lt;/li&gt;
&lt;li&gt;Shards &amp;#x26; Replicas&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;412-安装--配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#412-%E5%AE%89%E8%A3%85--%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;412 安装  配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.2 安装 &amp;#x26; 配置&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docker.html#docker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Install Elasticsearch with Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/settings.html#settings&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configuring Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/jvm-options.html#jvm-options&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Setting JVM options&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/important-settings.html#important-settings&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Important Elasticsearch configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/system-config.html#system-config&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Important System Configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面三条对生产环境影响比较大，需要仔细阅读。更贴近实践的范例可以参见：&lt;a href=&quot;#ID_ES_CONFIG&quot;&gt;8.1 Elasticsearch配置&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;413-api&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#413-api&quot; aria-label=&quot;413 api permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.3 API&lt;/h3&gt;
&lt;p&gt;Elasticsearch的API文档相当散，主要是以下几项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docs.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Document APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/search.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Search APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/search-aggregations.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Aggregations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Indices APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/cat.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;cat APIs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/cluster.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Cluster APIs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API最常见的用途是对Elasticsearch集群进行观察，并进行一些例如Index Template设置之类的，超乎于日常日志输入相关业务之外的管理和控制。&lt;/p&gt;
&lt;h3 id=&quot;414-query-dsl&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#414-query-dsl&quot; aria-label=&quot;414 query dsl permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.4 Query DSL&lt;/h3&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Query DSL&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;了解Elasticsearch的人肯定会问：Query DSL和Elasticsearch的基础Lucene之间是什么关系。关于这个知识点可以查看：&lt;a href=&quot;https://stackoverflow.com/questions/27793721/what-is-the-difference-between-lucene-and-elasticsearch&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What is the difference between Lucene and Elasticsearch&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Elasticsearch is a JSON Based, Distributed, web server build over Lucene. Though it’s Lucene who is doing the actual work beneath, Elasticsearch provides us a convenient layer over Lucene. Each shard that gets created in Elasticsearch is a separate Lucene instance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lucene是底层，Elasticsearch是基于Lucene之上的超集开发，而QueryDSL则是用户和Elasticsearch之间交互的桥梁。&lt;/p&gt;
&lt;h3 id=&quot;415-sql&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#415-sql&quot; aria-label=&quot;415 sql permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.5 SQL&lt;/h3&gt;
&lt;p&gt;Elasticsearch还可以使用SQL进行查询：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/xpack-sql.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;SQL access&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;416-ingest节点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#416-ingest%E8%8A%82%E7%82%B9&quot; aria-label=&quot;416 ingest节点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1.6 Ingest节点&lt;/h3&gt;
&lt;p&gt;在整个&lt;a href=&quot;#ID_ARC_CLUSTER&quot;&gt;Elasticsearch集群&lt;/a&gt;中，有一部分节点是用来进行日志过滤、清洗、丰富化的，这些工作在这个设计出现之前是只能在Agent上实现的，一般来说就是Logstash，而现在在服务器节点上也可以处理相对应的工作了。&lt;/p&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/ingest.html#ingest&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ingest Node&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;通过定义Processors来进行日志的解析和处理：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/ingest-processors.html#ingest-processors&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Processors&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;初步了解下来功能应该还算强大，可以使用脚本化代码进行功能拓展：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/script-processor.html#script-processor&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Script Processor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/modules-scripting-using.html#modules-scripting-using&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to use scripts&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外还有插件机制：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/plugins/7.0/ingest.html#ingest&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Ingest Plugins&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;42-文档数据库--索引-id_index&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-%E6%96%87%E6%A1%A3%E6%95%B0%E6%8D%AE%E5%BA%93--%E7%B4%A2%E5%BC%95-id_index&quot; aria-label=&quot;42 文档数据库  索引 id_index permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 文档数据库 &amp;#x26; 索引 {#ID_INDEX}&lt;/h2&gt;
&lt;p&gt;Elasticsearch是一个文档数据库，从本质上来看，它和Mongo其实相当类似。和传统RDBMS比较起来：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Relational DB -&gt; Databases -&gt; Tables  -&gt; Rows      -&gt; Columns
Elasticsearch -&gt; Cluster   -&gt; Indices -&gt; Documents -&gt; Fields&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;简单理解：所谓的索引就是&lt;code class=&quot;language-text&quot;&gt;表名&lt;/code&gt;，用来定位查询以及根据该名字进行分片sharding。&lt;/p&gt;
&lt;p&gt;举个例子：
PUT /employee/1&lt;/p&gt;
&lt;p&gt;Index：&lt;code class=&quot;language-text&quot;&gt;employee&lt;/code&gt;&lt;br&gt;
Document：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;first_name&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;last_name&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;token string&quot;&gt;&quot;Smith&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;age&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;        &lt;span class=&quot;token number&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;about&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;      &lt;span class=&quot;token string&quot;&gt;&quot;I love to go rock climbing&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;interests&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;sports&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;music&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Fields：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;first_name&lt;/li&gt;
&lt;li&gt;last_name&lt;/li&gt;
&lt;li&gt;age&lt;/li&gt;
&lt;li&gt;about&lt;/li&gt;
&lt;li&gt;interests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;索引非常重要，在集群模式（cluster）中，索引是用来进行分区的唯一指标。Elasticsearch会根据Index来决定当前数据落到哪台实际的存储服务器上。&lt;/p&gt;
&lt;p&gt;此外，需要注意，Index可以被Reindex，但不可以Reshard。换句话说，在Index被创建出来的时候，其shards数量就已经被固定下来了，以后不可更改。如果有这样的需求的话，必须使用Reindex来重新分配并平衡Index，已经创建出来的就没办法了。而Replicas则可以随时更改数量。&lt;/p&gt;
&lt;p&gt;关于索引的细节，以及一些集群相关的索引知识，可以查看：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docs-index_.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Index API&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;421-index-template&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#421-index-template&quot; aria-label=&quot;421 index template permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.1 Index Template&lt;/h3&gt;
&lt;p&gt;和索引（&lt;code class=&quot;language-text&quot;&gt;Index&lt;/code&gt;）息息相关的有一个概念叫：&lt;code class=&quot;language-text&quot;&gt;Index Template&lt;/code&gt;。这部分比较重要也稍微有点复杂，后面会结合实际实践一并解释，会更容易理解：&lt;a href=&quot;#ID_INDEX_TEMPLATE&quot;&gt;6.3 Index Template&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;422-设置index生命周期&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#422-%E8%AE%BE%E7%BD%AEindex%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F&quot; aria-label=&quot;422 设置index生命周期 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.2 设置index生命周期&lt;/h3&gt;
&lt;p&gt;一般实践的时候，建议不要向单个Index内放入过多的文档，这会对写入和查询都造成比较大的压力。比较常见的做法是对输出端进行设置，将日志的输出索引设置成按日划分：&lt;code class=&quot;language-text&quot;&gt;index: &quot;dist-%{[fields.app]}-%{[fields.module]}-%{[agent.version]}-%{+yyyy.MM.dd}&quot;&lt;/code&gt;，这样就有一个最基本的保障。但这样做的缺陷一样非常明显，当单日的业务量上涨之后，单日的日志量可能就比较夸张。&lt;/p&gt;
&lt;p&gt;在Elasticsearch中，Index的生命周期有另外的管理方法：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/getting-started-index-lifecycle-management.html#getting-started-index-lifecycle-management&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Getting started with index lifecycle management&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;同时需要在Filebeat端进行配合：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/ilm.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configure index lifecycle management&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;423-index的自动创建设置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#423-index%E7%9A%84%E8%87%AA%E5%8A%A8%E5%88%9B%E5%BB%BA%E8%AE%BE%E7%BD%AE&quot; aria-label=&quot;423 index的自动创建设置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2.3 Index的自动创建设置&lt;/h3&gt;
&lt;p&gt;在大部分情况下Elasticsearch都是允许自动创建Index的。在某些情况下可能需要关闭自动创建的允许权限，可以参见文档：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docs-index_.html#index-creation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Automatic Index Creation&lt;/a&gt;，来查看如何操作。&lt;/p&gt;
&lt;h2 id=&quot;43-存储-id_storage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E5%AD%98%E5%82%A8-id_storage&quot; aria-label=&quot;43 存储 id_storage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 存储 {#ID_STORAGE}&lt;/h2&gt;
&lt;p&gt;在官方手册文档中，并没有关于存储相关的设计及实现的详细内容。在Blog中找到一篇：&lt;a href=&quot;https://www.elastic.co/blog/found-dive-into-elasticsearch-storage&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;A Dive into the Elasticsearch Storage&lt;/a&gt;，不过时间也稍微有点久，但还算可以用来一窥存储相关的技术点。&lt;/p&gt;
&lt;p&gt;此外，&lt;strong&gt;shards：Lucene segments&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Each Elasticsearch index is divided into shards. Shards are both logical and physical division of an index. Each Elasticsearch shard is a Lucene index. The maximum number of documents you can have in a Lucene index is 2,147,483,519. The Lucene index is divided into smaller files called segments. A segment is a small Lucene index. Lucene searches in all segments sequentially.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/elk_shards.png&quot; alt=&quot;elk_shards&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;44-集群-id_arc_cluster&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E9%9B%86%E7%BE%A4-id_arc_cluster&quot; aria-label=&quot;44 集群 id_arc_cluster permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 集群 {#ID_ARC_CLUSTER}&lt;/h2&gt;
&lt;p&gt;关于架构和集群的基础概念可以阅读官方的一份PPT：&lt;a href=&quot;https://www.elastic.co/pdf/architecture-best-practices.pdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch Best Practice Architecture&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;主要是了解下Elasticsearch集群的节点分类：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/elk_node_types.png&quot; alt=&quot;elk_node_types&quot;&gt;&lt;/p&gt;
&lt;p&gt;然后看下之前提到过的ELK整体集群拓扑：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/elk_arch.png&quot; alt=&quot;elk_arch&quot;&gt;&lt;/p&gt;
&lt;p&gt;此外推荐一篇：&lt;a href=&quot;https://thoughts.t37.net/designing-the-perfect-elasticsearch-cluster-the-almost-definitive-guide-e614eabc1a87&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Designing the Perfect Elasticsearch Cluster: the (almost) Definitive Guide&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在官方的文档库中我并没有找到比较新版本的文档有讲解到分布式和高可用之类的架构设计内容，大部分的文档都是各种API和各种细节。在老的版本中倒是找到一点信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/guide/current/_how_primary_and_replica_shards_interact.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How Primary and Replica Shards Interact&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/guide/current/distrib-write.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Creating, Indexing, and Deleting a Document&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，中文书里的内容也可以阅读：&lt;a href=&quot;https://es.xiaoleilu.com/020_Distributed_Cluster/00_Intro.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;集群内部工作方式&lt;/a&gt;，注意这本中文书的版本已经相当老了，里面的内容有部分和现在的版本明显不同。&lt;/p&gt;
&lt;p&gt;几点整理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;replica与数据主节点并不一定是1：1的关系（并不一定一个master拖一个slave这样的设计），这个replica节点数量是可设置的，一个主节点可能有多份完全一致的replica&lt;/li&gt;
&lt;li&gt;当你的replica设置越多，写入速度就越慢（参与的节点多），主节点写入完毕之后还要让所有的replica写入，全部都完成才会返回客户端完成&lt;/li&gt;
&lt;li&gt;当你的replica设置越多，查询（读取）速度就越快（参与的节点多）&lt;/li&gt;
&lt;li&gt;当发生查询请求时，查询请求是会落到所有的shard上的，所以集群shards做的越多，整个集群的查询性能开销就越大，这里就有一个平衡的问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;45-监控--高可用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#45-%E7%9B%91%E6%8E%A7--%E9%AB%98%E5%8F%AF%E7%94%A8&quot; aria-label=&quot;45 监控  高可用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5 监控 &amp;#x26; 高可用&lt;/h2&gt;
&lt;h3 id=&quot;451-监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#451-%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;451 监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.1 监控&lt;/h3&gt;
&lt;p&gt;对于Elasticsearch的监控，官方有一套解决方案（Elasticsearch算是一个生态了，在上游和下游都有完整的处理）。可以查阅下官方文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/es-monitoring.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Monitoring Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/setup-xpack.html#setup-xpack&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Set up X-Pack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/getting-started-cluster-health.html#getting-started-cluster-health&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Cluster Health&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然也可以选用Prometheus作为监控：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vvanholl/elasticsearch-prometheus-exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus Exporter Plugin for Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;452-监控实践&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#452-%E7%9B%91%E6%8E%A7%E5%AE%9E%E8%B7%B5&quot; aria-label=&quot;452 监控实践 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.2 监控实践&lt;/h3&gt;
&lt;p&gt;除了官方插件之外，还有更好用的Prometheus集成工具，由justwatch提供的一整套：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exporter：
&lt;ul&gt;
&lt;li&gt;代码：&lt;a href=&quot;https://github.com/justwatchcom/elasticsearch_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;justwatchcom/elasticsearch_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;镜像：&lt;a href=&quot;https://hub.docker.com/r/justwatch/elasticsearch_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;justwatch/elasticsearch_exporter&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;justwatch/elasticsearch_exporter:1.1.0rc1&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard：&lt;a href=&quot;https://grafana.com/dashboards/2322&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ElasticSearch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只需要在Elasticsearch集群之外启动一个Exporter镜像，并提供Elasticsearch集群的访问地址即可获得所有的metrics，然后在Grafana内导入justwatch提供的Dashboard就可以将数据可视化。整个过程不需要代码介入，直接使用即可，非常完美。&lt;/p&gt;
&lt;h3 id=&quot;453-高可用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#453-%E9%AB%98%E5%8F%AF%E7%94%A8&quot; aria-label=&quot;453 高可用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.5.3 高可用&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;数据节点数量选择&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://thoughts.t37.net/resizing-your-elasticsearch-indexes-in-production-d7a0402d137e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Resizing your Elasticsearch Indexes in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.signalfx.com/blog/scaling-elasticsearch-sharding-availability-hundreds-millions-documents/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Scaling Elasticsearch: Sharding and Availability for Hundreds Of Millions of Documents&lt;/a&gt;：这篇当中有一段讲解了&lt;code class=&quot;language-text&quot;&gt;Resharding With Zero Downtime&lt;/code&gt;，这是非常有价值的一个topic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;可恢复的集群最低配置&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 locations to host your nodes. 2 locations to run half of your cluster, and one for the backup master node.&lt;/li&gt;
&lt;li&gt;3 master nodes. You need an odd number of eligible master nodes to avoid split brains when you lose a whole data center. Put one master node in each location so you hopefully never lose the quorum.&lt;/li&gt;
&lt;li&gt;2 http nodes, one in each primary data center.&lt;/li&gt;
&lt;li&gt;As many data nodes as you need, split evenly between both main locations.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;故障恢复&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Elasticsearch在集群中分主节点shard和复制节点replica，当集群的设置足够多（数据冗余充分）的情况下，当某个物理节点不可用时，Elasticsearch会自动进行选举，将丢失的主节点shard的replica节点设置成主节点，并重新对集群进行平衡。举个例子：&lt;/p&gt;
&lt;p&gt;事故发生前：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一共有3个物理节点&lt;/li&gt;
&lt;li&gt;一共有3个主节点shard&lt;/li&gt;
&lt;li&gt;每个主节点shard有2个复制节点replica&lt;/li&gt;
&lt;li&gt;当前物理节点1是作为整个集群的master节点进行服务的&lt;/li&gt;
&lt;li&gt;后续事故会发生在物理节点1，这个节点会下线&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/elk_ha_01.png&quot; alt=&quot;Before&quot;&gt;&lt;/p&gt;
&lt;p&gt;事故发生后：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;master节点下线了，因此集群重新开始选取master节点，设定为物理节点2&lt;/li&gt;
&lt;li&gt;0号主节点shard（P0）本来就在物理节点3上，因此不受影响&lt;/li&gt;
&lt;li&gt;1号和2号主节点shard之前在物理节点1上，全部丢失，集群将物理节点2上的2号shard的replica（R2）提升为主节点shard（P2），并将物理节点3上的1号shard的replica（R1）提升为主节点shard（P1）&lt;/li&gt;
&lt;li&gt;此时所有的主节点shard都已恢复，且各主节点shard都存在一份replica&lt;/li&gt;
&lt;li&gt;后续集群会继续为各主节点shard复制缺失的一份replica&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/elk_ha_02.png&quot; alt=&quot;After&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;46-性能调优&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#46-%E6%80%A7%E8%83%BD%E8%B0%83%E4%BC%98&quot; aria-label=&quot;46 性能调优 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.6 性能调优&lt;/h2&gt;
&lt;p&gt;Ebay有一篇非常细节非常棒的设计及性能优化分析博文：&lt;a href=&quot;https://www.ebayinc.com/stories/blogs/tech/elasticsearch-performance-tuning-practice-at-ebay/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch Performance Tuning Practice at eBay&lt;/a&gt;。从时间上来看，这篇文章也还算近：&lt;code class=&quot;language-text&quot;&gt;2018-01-08&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;这篇博文分析了大规模Elasticsearch集群会面临的挑战，以及解决方案，还按实际的应用Scenario进行了问题分析以及给出了解决范例，很棒。&lt;/p&gt;
&lt;h1 id=&quot;5-kibana&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-kibana&quot; aria-label=&quot;5 kibana permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Kibana&lt;/h1&gt;
&lt;p&gt;Kibana这块相对来说比较简单。一些关键文档位置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/docker.html#docker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Running Kibana on Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/settings.html#settings&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configuring Kibana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/kuery-query.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kibana Query Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/lucene-query.html#lucene-query&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Lucene Query Syntax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;51-index-pattern-id_index_pattern&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-index-pattern-id_index_pattern&quot; aria-label=&quot;51 index pattern id_index_pattern permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 Index Pattern {#ID_INDEX_PATTERN}&lt;/h2&gt;
&lt;p&gt;在打开Kibana页面进行任何查询和设置之前，必须进行&lt;code class=&quot;language-text&quot;&gt;Index Pattern&lt;/code&gt;的设置。这是使用的前提。该设置是用来告知Kibana，Elasticsearch集群中的哪些Index是需要进行解析和观察的，作为后续所有查询的数据来源。&lt;/p&gt;
&lt;p&gt;官方文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/index-patterns.html#index-patterns&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Index Patterns&lt;/a&gt; &lt;a href=&quot;https://www.elastic.co/guide/cn/kibana/current/index-patterns.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;中文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/tutorial-define-index.html#tutorial-define-index&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Defining your index patterns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;官方对于自动化的支持做的不太好，如果需要在Elasticsearch集群启动之后自动化对Kibana内设置Index Pattern的话，该需求是没有官方的解决方案的。找了一圈有一些hack方案，但都不稳定，非常容易因版本更新的原因后续就无法使用了。这方面后面只能说有需要再临时找对应版本的hack。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/elastic/kibana/issues/3709&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Index pattern creation API #3709&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;52-使用简介&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E4%BD%BF%E7%94%A8%E7%AE%80%E4%BB%8B&quot; aria-label=&quot;52 使用简介 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 使用简介&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;如果只是要简单过滤下数据进行简单的统计或者进行临时的debug日志搜索，那么在&lt;code class=&quot;language-text&quot;&gt;Discover&lt;/code&gt;页面直接使用条件搜索过滤即可：&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/tutorial-discovering.html#tutorial-discovering&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Discovering your data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;如果需要对一个常用的搜索或数值结果进行定义，方便后续直接查看，那么可以使用&lt;code class=&quot;language-text&quot;&gt;Visualize&lt;/code&gt;页面制作图表，这里的Visualize是和Grafana里的&lt;code class=&quot;language-text&quot;&gt;Panel&lt;/code&gt;同样的概念：&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/tutorial-visualizing.html#tutorial-visualizing&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Visualizing your data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;如果需要定义一系列常用的图表进行观察，则可以使用&lt;code class=&quot;language-text&quot;&gt;Dashboard&lt;/code&gt;页面进行设置，这里的Dashboard是和Grafana里的&lt;code class=&quot;language-text&quot;&gt;Dashboard&lt;/code&gt;同样的概念：&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/tutorial-dashboard.html#tutorial-dashboard&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Displaying your visualizations in a dashboard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一般如果将Elasticsearch作为日志聚合debug工具的话，不需要很复杂的设置，直接使用Discover即可。偶尔会有些例如同时在线或最近请求数量之类的观测需求，那么简单设置下Visualize即可。&lt;/p&gt;
&lt;h2 id=&quot;53-qa&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#53-qa&quot; aria-label=&quot;53 qa permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3 Q&amp;#x26;A&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/47370280/whats-the-difference-between-the-field-and-field-keyword-fields-in-kibana&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What’s the difference between the ‘field’ and ‘field.keyword’ fields in Kibana?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;6-filebeat直连elasticsearch实践&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-filebeat%E7%9B%B4%E8%BF%9Eelasticsearch%E5%AE%9E%E8%B7%B5&quot; aria-label=&quot;6 filebeat直连elasticsearch实践 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Filebeat直连Elasticsearch实践&lt;/h1&gt;
&lt;h2 id=&quot;61-直连流程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-%E7%9B%B4%E8%BF%9E%E6%B5%81%E7%A8%8B&quot; aria-label=&quot;61 直连流程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 直连流程&lt;/h2&gt;
&lt;p&gt;在实际应用的场景中，大部分情况下我们需要的这是将本地日志的内容分类传送到Elasticsearch集群中，按条件定位到不同的索引内。最多也就是对日志里的字段进行一些简单的丰富化或转换。而完成这样的需求其实是不需要Logstash这样的工具，仅使用Filebeat就可以独立完成。这样做的好处是节约了大量系统资源（Golang vs Java），同时还兼具了高可用和性能。&lt;/p&gt;
&lt;p&gt;流程也非常简单：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Filebeat监听本地日志变化&lt;/li&gt;
&lt;li&gt;Filebeat将新产生的日志内容按JSON进行解析&lt;/li&gt;
&lt;li&gt;Filebeat根据日志内的字段内容，进行&lt;code class=&quot;language-text&quot;&gt;processors&lt;/code&gt;处理，进行丰富化或进行格式转换&lt;/li&gt;
&lt;li&gt;Filebeat根据根据&lt;code class=&quot;language-text&quot;&gt;Elasticsearch template setting&lt;/code&gt;，启用在Elasticsearch集群上设置好的Index Template（只有这步是依赖Elasticsearch集群的，需要预先在Elasticsearch集群中设置好Template）&lt;/li&gt;
&lt;li&gt;Filebeat根据设置，将日志传输到Elasticsearch集群中不同的Index里&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基本上全部的处理都是在Filebeat里完成了，不需要Ingest Pipeline做什么，更不需要Logstash出马。&lt;/p&gt;
&lt;p&gt;实际操作下来，还是有很多细节问题，后面一一细说。&lt;/p&gt;
&lt;h2 id=&quot;62-应用场景&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-%E5%BA%94%E7%94%A8%E5%9C%BA%E6%99%AF&quot; aria-label=&quot;62 应用场景 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 应用场景&lt;/h2&gt;
&lt;p&gt;先描述下应用场景，否则后面的一些配置和细节都不好说明。&lt;/p&gt;
&lt;p&gt;系统有三个应用程序：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;web&lt;/li&gt;
&lt;li&gt;service&lt;/li&gt;
&lt;li&gt;consumer&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个应用程序都会输出一份日志：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;web：/tmp/logs/app/app.web.stdout.log&lt;/li&gt;
&lt;li&gt;service：/tmp/logs/app/app.service.stdout.log&lt;/li&gt;
&lt;li&gt;consumer：/tmp/logs/app/app.consumer.stdout.log&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;每个应用除了自身的业务日志之外，也会有一些使用中的组件会在对应的日志内输出内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;web：
&lt;ul&gt;
&lt;li&gt;web：自身业务日志&lt;/li&gt;
&lt;li&gt;gin：web框架gin的日志&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;service：
&lt;ul&gt;
&lt;li&gt;service：自身业务日志&lt;/li&gt;
&lt;li&gt;gorm：数据库orm框架的日志&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;consumer：
&lt;ul&gt;
&lt;li&gt;consumer：自身业务日志&lt;/li&gt;
&lt;li&gt;gorm：数据库orm框架的日志&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需求是跟踪、解析这三份日志文件，将输出的日志根据应用以及组件分发到Elasticsearch不同的Index中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;web：
&lt;ul&gt;
&lt;li&gt;web：分发到 dist-web-web-*&lt;/li&gt;
&lt;li&gt;gin：分发到 dist-web-gin-*&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;service：
&lt;ul&gt;
&lt;li&gt;service：分发到 dist-service-service-*&lt;/li&gt;
&lt;li&gt;gorm：分发到 dist-service-gorm-*&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;consumer：
&lt;ul&gt;
&lt;li&gt;consumer：分发到 dist-consumer-consumer-*&lt;/li&gt;
&lt;li&gt;gorm：分发到 dist-consumer-gorm-*&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;解决方案：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用input配置下的fields配置，根据输入的文件，添加自定义字段：&lt;code class=&quot;language-text&quot;&gt;fields.app: web|service|consumer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;使用processors，解析JSON日志内容、字段，添加自定义字段：&lt;code class=&quot;language-text&quot;&gt;fields.module: web|gin|service|consumer|gorm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;根据字段&lt;code class=&quot;language-text&quot;&gt;fields.app``fields.module&lt;/code&gt;输出日志到不同的Index：&lt;code class=&quot;language-text&quot;&gt;dist-%{[fields.app]}-%{[fields.module]}-%{[agent.version]}-%{+yyyy.MM.dd}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;63-index-template-id_index_template&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#63-index-template-id_index_template&quot; aria-label=&quot;63 index template id_index_template permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3 Index Template {#ID_INDEX_TEMPLATE}&lt;/h2&gt;
&lt;p&gt;中间还需要补一个Elasticsearch的概念：&lt;code class=&quot;language-text&quot;&gt;Index Template&lt;/code&gt;。官方文档在：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Index Templates&lt;/a&gt;，也有一份&lt;a href=&quot;https://www.elastic.co/guide/cn/elasticsearch/guide/current/index-templates.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;中文&lt;/a&gt;的。&lt;/p&gt;
&lt;p&gt;之前在&lt;a href=&quot;#ID_INDEX&quot;&gt;4.2 文档数据库 &amp;#x26; 索引&lt;/a&gt;已经讲到了，Index即相当于RDBMS里的&lt;code class=&quot;language-text&quot;&gt;表名&lt;/code&gt;，且在Elasticsearch中是用来进行sharding的重要字段。而同时我们之前也提到过了，在大部分的情况下，Index是自动创建的，按某些格式：&lt;code class=&quot;language-text&quot;&gt;dist-%{[fields.app]}-%{[fields.module]}-%{[agent.version]}-%{+yyyy.MM.dd}&lt;/code&gt;。所以如果要针对每一个Index进行单独的配置，这基本上是不可能的。在Elasticsearch中，为了应对这样的需求，就有了&lt;code class=&quot;language-text&quot;&gt;Index Template&lt;/code&gt;这个设置。新创建的Index都会根据名字套用上某个Template（如果有匹配到的话），达到对Index进行设置的目的。&lt;/p&gt;
&lt;p&gt;此外，Index Template里还设置了很多细节（这些设置都会在名字匹配的Index上生效）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Index的shards数量&lt;/li&gt;
&lt;li&gt;Index的replicas数量&lt;/li&gt;
&lt;li&gt;Index如何分词、如何过滤&lt;/li&gt;
&lt;li&gt;Index对应日志中的字段应该怎么解析，分别都是什么类型的字段（如果不设置的话，Elasticsearch会根据第一次出现的值进行猜测，以后将不再更改，除非使用API手动重设）&lt;/li&gt;
&lt;li&gt;等等&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果某个新创建的Index不符合任何Elasticsearch集群上已知的所有Template，则该Index内的所有设置都会按默认值来。一般来说这种情况下最严重的问题是：该Index将只会存在一个shard，且只会有一份replica。&lt;/p&gt;
&lt;p&gt;所以，一般来说都需要在正式使用之前将需要的Index Template创建好，才可能开始向Elasticsearch输入日志，否则创建出来的Index会有问题，至少分片就不对。&lt;/p&gt;
&lt;p&gt;额外的资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有一份中文的博文，讲解的很好，后续可以看下：&lt;a href=&quot;https://www.jianshu.com/p/1f67e4436c37&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;初探 Elasticsearch Index Template（索引模板)&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;官方社区有一个讨论帖，里面有comment对如何操作自定义Index Template有比较详细的步骤讲解：&lt;a href=&quot;https://discuss.elastic.co/t/custom-filebeat-template-for-json-log-lines/114761/5&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Custom filebeat template for JSON log lines&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;64-issues&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#64-issues&quot; aria-label=&quot;64 issues permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4 Issues&lt;/h2&gt;
&lt;h3 id=&quot;641-filebeat字段层级&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#641-filebeat%E5%AD%97%E6%AE%B5%E5%B1%82%E7%BA%A7&quot; aria-label=&quot;641 filebeat字段层级 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.1 Filebeat字段层级&lt;/h3&gt;
&lt;p&gt;Filebeat默认将日志JSON解析出来的内容放到&lt;code class=&quot;language-text&quot;&gt;message&lt;/code&gt;字段下，见下图的message字段内容：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/filebeat_json_no_root.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果不知道这点的话，在使用&lt;code class=&quot;language-text&quot;&gt;processors&lt;/code&gt;时候会发现设定的条件因字段没有找到而没有被触发。调试的时候会非常痛苦。&lt;/p&gt;
&lt;p&gt;这里需要了解filebeat的设置：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/filebeat-input-log.html#filebeat-input-log-config-json&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Log input &gt; json&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;有几项配置需要了解下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;filebeat.inputs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; log
    &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /&lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;json.keys_under_root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;json.overwrite_keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;json.message_key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; message
    &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;json.keys_under_root: true&lt;/code&gt;：将之前存放在message字段里的JSON释放到根节点，效果见下图，可以和上面的图做下比对；一般来说这也是用户希望的效果&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;json.overwrite_keys: true&lt;/code&gt;：是否在冲突的时候使用释放出来的字段的值覆盖根目录下同Key的值，一般也需要配置&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;json.message_key: message&lt;/code&gt;：这项一般不要改，留默认的&lt;code class=&quot;language-text&quot;&gt;message&lt;/code&gt;即可，后面会解释原因&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/filebeat_json_root.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果不配置&lt;code class=&quot;language-text&quot;&gt;json.keys_under_root: true&lt;/code&gt;也不是不可以，但在查找日志JSON内容的时候就需要到message字段下去查找，而不是根节点。&lt;/p&gt;
&lt;h3 id=&quot;642-kibana-message字段&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#642-kibana-message%E5%AD%97%E6%AE%B5&quot; aria-label=&quot;642 kibana message字段 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.2 Kibana message字段&lt;/h3&gt;
&lt;p&gt;Kibana页面上的原始日志页面，显示的是filebeat传输到Elasticsearch日志内容中的&lt;code class=&quot;language-text&quot;&gt;message&lt;/code&gt;字段内容，且显示的仅只有message字段的内容。并且，当Kibana发现Elasticsearch中存放的日志不存在message字段的时候，还会显示错误：&lt;code class=&quot;language-text&quot;&gt;failed to find message&lt;/code&gt;。因此之前提到，不要随意更改：&lt;code class=&quot;language-text&quot;&gt;json.message_key: message&lt;/code&gt;。要更改Kibana的行为也不是不可以，参见：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://discuss.elastic.co/t/log-ui-failed-to-format-message-from/163196&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Log UI failed to format message from&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/elastic/kibana/pull/26579/files#diff-3d8e25bfa60ef76c1ce7b5e7a68232f2R9&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;[InfraOps] Update docs with data source configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实际效果可以参见下面两张图的比对，第一张是没有使用&lt;code class=&quot;language-text&quot;&gt;json.keys_under_root: true&lt;/code&gt;的情况，第二张则是释放之后的情况：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/filebeat_logs_msg_no_root.png&quot; alt=&quot;&quot;&gt;
&lt;img src=&quot;/media/posts/2019/04/elasticsearch-note/filebeat_logs_msg_root.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;643-input--processors-fields&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#643-input--processors-fields&quot; aria-label=&quot;643 input  processors fields permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.3 input | processors fields&lt;/h3&gt;
&lt;p&gt;在filebeat的input配置中，可以根据日志输入向日志内容中添加自定义的字段：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;filebeat.inputs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; log
    &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /tmp/app/logs/app.web.stdout.log
    &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web
    &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在processors配置中，也可以根据条件向日志内容中添加自定义的字段：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;processors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;add_fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WEB.Handler&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;web&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;但有一点需要明确，这些添加的字段，都会存放在根节点下的&lt;code class=&quot;language-text&quot;&gt;fields&lt;/code&gt;字段里。上面例子里的两个设置，会产生：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;fields.app: web&lt;/li&gt;
&lt;li&gt;fields.module: web&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以看下之前6.4.1图中的字段列表。&lt;/p&gt;
&lt;h3 id=&quot;644-index-template设置-id_filebeat_index_template&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#644-index-template%E8%AE%BE%E7%BD%AE-id_filebeat_index_template&quot; aria-label=&quot;644 index template设置 id_filebeat_index_template permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.4 Index Template设置 {#ID_FILEBEAT_INDEX_TEMPLATE}&lt;/h3&gt;
&lt;p&gt;Index Template虽然是在Elasticsearch上创建的（见：&lt;a href=&quot;#ID_INDEX_TEMPLATE&quot;&gt;6.3 Index Template&lt;/a&gt;），但在filebeat端还是需要做设置的。主要是需要在filebeat端加载Elasticsearch上存在的Index Template，然后后续在filebeat向Elasticsearch传输日志的时候，就会应用这些Template。如果配置不正确的话，诸如shards数量之类的配置就会出错、不生效。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;filebeat中关于Index Template的配置项：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/configuration-template.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Load the Elasticsearch index template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;filebeat中如何加载Index Template：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/filebeat-template.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Step 4: Load the index template in Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;此外，该功能一般和输出相关配置有关：&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/elasticsearch-output.html#indices-option-es&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configure the Elasticsearch output &gt; indices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果不想在Elasticsearch端创建自定义的Index Template，那么可以使用的Template只有一个，就是filebeat默认的：&lt;code class=&quot;language-text&quot;&gt;filebeat-%{[agent.version]}-%{+yyyy.MM.dd}&lt;/code&gt;，在当前的版本下就是：&lt;code class=&quot;language-text&quot;&gt;filebeat-7.0.0-2019-05-29&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;该默认的Template在Elastcsearch上的配置可以通过API &lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/indices-templates.html#getting&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Getting templates&lt;/a&gt; 进行观察：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;filebeat-7.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;order&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;index_patterns&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;filebeat-7.0.0-*&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;settings&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;index&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;lifecycle&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;filebeat-7.0.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;rollover_alias&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;filebeat-7.0.0&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;mapping&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;total_fields&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;limit&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;refresh_interval&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;number_of_shards&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到，该Template的名字匹配pattern是：&lt;code class=&quot;language-text&quot;&gt;filebeat-7.0.0-*&lt;/code&gt;，所以如果要利用这个默认的Template的话，名字一定不能搞错。我之前做实验的时候使用过：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;filebeat-web-web-7.0.0-*&lt;/li&gt;
&lt;li&gt;filebeat-web-gin-7.0.0-*&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;之类的，就因为名字不匹配导致没有套用上这个Template，最后shards数量之类的就全错了。&lt;/p&gt;
&lt;h3 id=&quot;645-切片数量&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#645-%E5%88%87%E7%89%87%E6%95%B0%E9%87%8F&quot; aria-label=&quot;645 切片数量 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.5 切片数量&lt;/h3&gt;
&lt;p&gt;查看集群Index切片状态，可以通过API &lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/cat-shards.html#cat-shards&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;cat shards&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;范例集群的切片设置为：&lt;code class=&quot;language-text&quot;&gt;主节点&lt;/code&gt;数量3，&lt;code class=&quot;language-text&quot;&gt;replica&lt;/code&gt;数量1。也就是说一个Index的切片总数为：&lt;code class=&quot;language-text&quot;&gt;primary * (1 + replica)&lt;/code&gt; = 6。公式括号中的1就是primary，每一份切片只会有一个primary。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;curl&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;-X&lt;/span&gt; GET &lt;span class=&quot;token string&quot;&gt;&quot;http://127.0.0.1:9201/_cat/shards&quot;&lt;/span&gt;
dist-consumer-gorm-7.0.0-2019.05.29     &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-consumer-gorm-7.0.0-2019.05.29     &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-consumer-gorm-7.0.0-2019.05.29     &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-consumer-gorm-7.0.0-2019.05.29     &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-consumer-gorm-7.0.0-2019.05.29     &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;.2kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-consumer-gorm-7.0.0-2019.05.29     &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;.2kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-web-gin-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-web-gin-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-web-gin-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;.3kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-web-gin-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;.3kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-web-gin-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;.3kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-web-gin-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;.3kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-service-gorm-7.0.0-2019.05.29      &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;33&lt;/span&gt;.4kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-service-gorm-7.0.0-2019.05.29      &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;33&lt;/span&gt;.4kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-service-gorm-7.0.0-2019.05.29      &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;.6kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-service-gorm-7.0.0-2019.05.29      &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;.6kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-service-gorm-7.0.0-2019.05.29      &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-service-gorm-7.0.0-2019.05.29      &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-consumer-consumer-7.0.0-2019.05.29 &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;.6kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-consumer-consumer-7.0.0-2019.05.29 &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;.6kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-consumer-consumer-7.0.0-2019.05.29 &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-consumer-consumer-7.0.0-2019.05.29 &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-consumer-consumer-7.0.0-2019.05.29 &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;.6kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-consumer-consumer-7.0.0-2019.05.29 &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;.6kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
.kibana_1                               &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;.2kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
.kibana_1                               &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;.2kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-service-service-7.0.0-2019.05.29   &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-service-service-7.0.0-2019.05.29   &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-service-service-7.0.0-2019.05.29   &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;28&lt;/span&gt;.2kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-service-service-7.0.0-2019.05.29   &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;.9kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-service-service-7.0.0-2019.05.29   &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;.9kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-service-service-7.0.0-2019.05.29   &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;.9kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
.kibana_task_manager                    &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;45&lt;/span&gt;.4kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
.kibana_task_manager                    &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;45&lt;/span&gt;.4kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-web-web-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt;.9kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
dist-web-web-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;27&lt;/span&gt;.9kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-web-web-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;   14kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-web-web-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;   14kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
dist-web-web-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;   14kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
dist-web-web-7.0.0-2019.05.29           &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;   14kb &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
filebeat-7.0.0-2019.05.29-000001        &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
filebeat-7.0.0-2019.05.29-000001        &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
filebeat-7.0.0-2019.05.29-000001        &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.2 es_3
filebeat-7.0.0-2019.05.29-000001        &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1
filebeat-7.0.0-2019.05.29-000001        &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; p STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.4 es_2
filebeat-7.0.0-2019.05.29-000001        &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; r STARTED &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;   230b &lt;span class=&quot;token number&quot;&gt;172.20&lt;/span&gt;.0.3 es_1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;输出的内容有几列，这里解释下含义：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Index名&lt;/code&gt;：dist-consumer-gorm-7.0.0-2019.05.29&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;节点编号&lt;/code&gt;：切片在当前Index的切片组中的编号，从0开始，一个primary占用一个编号，所有该primary的从属replicas和primary共享同一个编号&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;节点类型&lt;/code&gt;：只有&lt;code class=&quot;language-text&quot;&gt;p&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;r&lt;/code&gt;，表示是primary还是replica&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;节点状态&lt;/code&gt;：正常状态为&lt;code class=&quot;language-text&quot;&gt;STARTED&lt;/code&gt;，启动中为&lt;code class=&quot;language-text&quot;&gt;INITIALIZING&lt;/code&gt;，错误状态为&lt;code class=&quot;language-text&quot;&gt;UNASSIGNED&lt;/code&gt;；unassigned相关参见：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/cat-shards.html#reason-unassigned&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Reasons for unassigned shard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;文档数量&lt;/code&gt;：存储在该节点内的文档数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;节点容量&lt;/code&gt;：节点占用的磁盘容量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;节点IP&lt;/code&gt;：节点的IP地址&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;节点名&lt;/code&gt;：节点在Elasticsearch集群中的名字&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;646-kibana-timestamp&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#646-kibana-timestamp&quot; aria-label=&quot;646 kibana timestamp permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.6 Kibana @timestamp&lt;/h3&gt;
&lt;p&gt;Filebeat向Elasticsearch传输的日志内容会添加一个字段：&lt;code class=&quot;language-text&quot;&gt;@timestamp&lt;/code&gt;。而Kibana在设置Index Pattern（&lt;a href=&quot;#ID_INDEX_PATTERN&quot;&gt;5.1 Index Pattern&lt;/a&gt;）的时候，强制需要选择一项日志内的时间字段作为后续时间相关过滤的指标。如果用户没有自己的时间字段的话，一般都会选择&lt;code class=&quot;language-text&quot;&gt;@timestamp&lt;/code&gt;字段，因为该段总是存在的。&lt;/p&gt;
&lt;p&gt;不过这里有一项需要注意：&lt;/p&gt;
&lt;p&gt;@timestamp 是日志被filebeat处理的时间点，而不是日志发生的时间点。一般来说这两者可以混用，但在日志有堆积，处理比较慢的情况下，就不合适了。千万需要小心，一般来说尽量选择业务日志自带的时间字段，就不会有问题了。&lt;/p&gt;
&lt;h3 id=&quot;647-elasticsearch-预创建数据&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#647-elasticsearch-%E9%A2%84%E5%88%9B%E5%BB%BA%E6%95%B0%E6%8D%AE&quot; aria-label=&quot;647 elasticsearch 预创建数据 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.7 Elasticsearch 预创建数据&lt;/h3&gt;
&lt;p&gt;一般来说，在Elasticsearch启动的时候都会有创建一些预设配置的需求，特别是在docker中运行的时候，因为docker本来就具有高度自动化的特征，也就格外需要这样的预设数据。这方面只能说官方仍旧没有提供非常完备的支持，只能自行处理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://discuss.elastic.co/t/best-practice-for-creating-an-index-when-an-es-docker-container-starts/126651&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Best practice for creating an index when an ES docker container starts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/35526532/how-to-add-an-elasticsearch-index-during-docker-build&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to add an elasticsearch index during docker build&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;7-实践范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-%E5%AE%9E%E8%B7%B5%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;7 实践范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. 实践范例&lt;/h1&gt;
&lt;p&gt;和之前做Prometheus实验的时候一样，因为需要把握一些细节，所以实验使用的还是下载下来的Elasticsearch、Kibana以及Filebeat。作为配角的Nginx使用的则是镜像版本。&lt;/p&gt;
&lt;p&gt;范例代码可以在Github查看：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/experiment/elasticsearch&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/experiment/elasticsearch/&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这则例子非常简单，基本上没有涉及任何比较核心的使用，粗略看下启动还是可以的。&lt;/p&gt;
&lt;h1 id=&quot;8-docker集群部署&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-docker%E9%9B%86%E7%BE%A4%E9%83%A8%E7%BD%B2&quot; aria-label=&quot;8 docker集群部署 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. Docker集群部署&lt;/h1&gt;
&lt;p&gt;仍旧是使用docker-compose进行群组的编辑和启动，可运行范例可以查看：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/conf/dev/elk-cluster.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/conf/dev/elk-cluster.yaml&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;启动脚本：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/bash/dev/docker_elasticsearch.sh&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/bash/dev/docker_elasticsearch.sh&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;下面会根据职责一一解析配置文件。&lt;/p&gt;
&lt;h2 id=&quot;81-elasticsearch配置-id_es_config&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#81-elasticsearch%E9%85%8D%E7%BD%AE-id_es_config&quot; aria-label=&quot;81 elasticsearch配置 id_es_config permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1 Elasticsearch配置 {#ID_ES_CONFIG}&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;elk-cluster.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;x-es-environment-defaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;C1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;&amp;amp;DISCOVERY_SEED_HOSTS&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;discovery.seed_hosts=es_1:9300,es_2:9300,es_3:9300&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 集群中的所有可用节点，这个配置中需要完整给出节点的HOST和PORT&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;C2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;&amp;amp;CLUSTER_INITIAL_MASTER_NODES&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cluster.initial_master_nodes=es_1,es_2,es_3&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 集群初始化的master节点，这个配置中只需要给节点名，即 node.name=es_1 里面设置的名字&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;C4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;&amp;amp;ES_JAVA_OPTS&lt;/span&gt; &quot;ES_JAVA_OPTS=\
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;Xms256m \
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt;Xmx256m \
    &quot;

&lt;span class=&quot;token key atrule&quot;&gt;x-es-ulimit-defaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;&amp;amp;ES_ULIMIT_DEFAULTS&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;nproc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;65535&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;nofile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;soft&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;65535&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;hard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;65535&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;memlock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;soft&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;-1&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;hard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;-1&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;x-es-logging-defaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;&amp;amp;ES_LOGGING_DEFAULTS&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;json-file&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;max-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;512m&quot;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;net&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bridge&quot;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;es_vol_1_logs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;local&quot;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;es_vol_1_data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;driver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;local&quot;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;es_1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;elasticsearch:7.0.0&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_1&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_1&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; es_vol_1_data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/usr/share/elasticsearch/data
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; es_vol_1_logs&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/usr/share/elasticsearch/logs
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /private/tmp/elasticsearch.yaml&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/usr/share/elasticsearch/config/elasticsearch.yml
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;net&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9201:9201&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 该PORT是给外部访问使用的，比如Kibana、Filebeat，以及客户端查询API&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;expose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;9300&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 该PORT是给集群内部流量使用的，所以只要expose即可&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;always&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*ES_LOGGING_DEFAULTS&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node.name=es_1 &lt;span class=&quot;token comment&quot;&gt;# 节点名必须设置且不可重复&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; http.port=9201 &lt;span class=&quot;token comment&quot;&gt;# 这个PORT同上&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node.master=true &lt;span class=&quot;token comment&quot;&gt;# 如果需要该节点作为master角色提供服务，则这里设置成true&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node.data=true &lt;span class=&quot;token comment&quot;&gt;# 如果需要该节点作为数据节点提供服务（数据存储），则这里设置成true&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*DISCOVERY_SEED_HOSTS&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*CLUSTER_INITIAL_MASTER_NODES&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*ES_JAVA_OPTS&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;ulimits&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*ES_ULIMIT_DEFAULTS&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;elasticsearch.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;cluster.name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; es_cluster
&lt;span class=&quot;token key atrule&quot;&gt;path.data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /usr/share/elasticsearch/data
&lt;span class=&quot;token key atrule&quot;&gt;path.logs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; /usr/share/elasticsearch/logs
&lt;span class=&quot;token key atrule&quot;&gt;bootstrap.memory_lock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;network.host&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0.0.0.0
&lt;span class=&quot;token key atrule&quot;&gt;transport.tcp.port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9300&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;相关文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官方文档及范例配置文件：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docker.html#docker-cli-run-prod-mode&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Install Elasticsearch with Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;理解Elasticsearch的集群发现：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/modules-discovery-hosts-providers.html#modules-discovery-hosts-providers&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Discovery&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;全局变量配置的使用：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/settings.html#_environment_variable_substitution&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment variable substitution&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;同上，不同的做法：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docker.html#docker-configuration-methods&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configuring Elasticsearch with Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;一些比较常见的问题：&lt;a href=&quot;https://www.jianshu.com/p/fa31f38d241e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用ElasticSearch踩过的坑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;一个非常完整的搭建例子：&lt;a href=&quot;https://www.infvie.com/ops-notes/elkstack-beats&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ELK Stack+Beats 搭建分布式日志平台&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;大杂烩：&lt;a href=&quot;https://www.jianshu.com/p/6a700cc61913&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch安装配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;带说明的非docker安装：&lt;a href=&quot;https://logz.io/blog/elasticsearch-cluster-tutorial/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Creating an Elasticsearch Cluster: Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;811-环境变量配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#811-%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;811 环境变量配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1.1 环境变量配置&lt;/h3&gt;
&lt;p&gt;Elasticsearch的环境变量配置要求使用配置文件中的配置项字符串，完全不用改动，全部都是小写，然后使用&lt;code class=&quot;language-text&quot;&gt;=&lt;/code&gt;连接配置项的值。此外需要注意，数组的配置和配置文件中有所不同，直接使用以&lt;code class=&quot;language-text&quot;&gt;,&lt;/code&gt;分隔的字符串即可：&lt;code class=&quot;language-text&quot;&gt;discovery.seed_hosts=es_1:9300,es_2:9300,es_3:9300&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node.name=es_1
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; http.port=9201
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node.master=true
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; node.data=true
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;812-多节点配置的共享&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#812-%E5%A4%9A%E8%8A%82%E7%82%B9%E9%85%8D%E7%BD%AE%E7%9A%84%E5%85%B1%E4%BA%AB&quot; aria-label=&quot;812 多节点配置的共享 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1.2 多节点配置的共享&lt;/h3&gt;
&lt;p&gt;Elasticsearch docker compose的配置中，需要把environment配置成数组，而YAML则恰恰不支持数组的Anchor Merge。这是YAML的一个功能性问题，不支持Array的平铺Merge：&lt;a href=&quot;https://github.com/yaml/yaml/issues/35&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Merge arrays #35&lt;/a&gt;。社区的方案一般都需要在原生的YAML之外，再使用工具把嵌套的Array整平：&lt;a href=&quot;https://stackoverflow.com/questions/4948933/is-there-a-way-to-alias-anchor-an-array-in-yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Is there a way to alias/anchor an array in YAML?&lt;/a&gt;，这就在我的接受范围之外了，我不希望使用任何第三方工具来修改yaml文件。&lt;/p&gt;
&lt;p&gt;最后方案为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;把不怎么需要在运行时修改的共通变量写入配置文件&lt;/li&gt;
&lt;li&gt;使用bind mount的方法加载配置文件到容器里&lt;/li&gt;
&lt;li&gt;在yaml中设置变量&lt;/li&gt;
&lt;li&gt;在多节点中使用变量，至少里面的值只需要改一个地方就可以生效了&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;813-集群发现相关配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#813-%E9%9B%86%E7%BE%A4%E5%8F%91%E7%8E%B0%E7%9B%B8%E5%85%B3%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;813 集群发现相关配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1.3 集群发现相关配置&lt;/h3&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/discovery-settings.html#discovery-settings&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Important discovery and cluster formation settings&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;集群发现主要依赖两项配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;discovery.seed_hosts=es_1:9300,es_2:9300,es_3:9300&lt;/li&gt;
&lt;li&gt;cluster.initial_master_nodes=es_1,es_2,es_3&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;discovery.seed_hosts&lt;/code&gt;用来告知Elasticsearch组成集群的所有节点都是谁，分别HOST和PORT是什么。无论是否是master节点，或者是否仅仅只是data节点，都需要列在这个选项中，告知给Elasticsearch。这个选项里的配置是常规的&lt;code class=&quot;language-text&quot;&gt;host:port&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;cluster.initial_master_nodes&lt;/code&gt;用来告知Elasticsearch，集群启动的时候初期可用的master节点是哪几个，之后Elasticsearch会从这些节点中选出master节点。列在这个配置中的节点，其&lt;code class=&quot;language-text&quot;&gt;node.master=true&lt;/code&gt;必须为true。&lt;/p&gt;
&lt;p&gt;然后，这个配置有个坑，非常非常坑，这个配置中的所有字符串，列的都是节点的名字，即必须和&lt;code class=&quot;language-text&quot;&gt;node.name=es_1&lt;/code&gt;里的名字一致，不需要配置成&lt;code class=&quot;language-text&quot;&gt;host:port&lt;/code&gt;，只需要&lt;code class=&quot;language-text&quot;&gt;node_name&lt;/code&gt;。官方文档中的&lt;a href=&quot;https://www.elastic.co/guide/en/elasticsearch/reference/7.0/docker.html#docker-cli-run-prod-mode&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;例子&lt;/a&gt;因为是docker，所以节点的名字和docker network中的container名字是一致的，而且官方的例子用的都是默认port，所有的port都没写，所以我一开始误认为这个选项里的配置也是&lt;code class=&quot;language-text&quot;&gt;host:port&lt;/code&gt;，然后各种无法组成集群。而且Elasticsearch针对这种错误给的错误信息非常暧昧，完全找不到有用的信息。最后找了半天才在官方论坛的一个帖子里找到线索。我填了这个坑之后貌似官方文档就更新了。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://discuss.elastic.co/t/elastic-search-7-unable-to-bootstrap-the-cluster-due-to-master-not-discovered-yet/182073/2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elastic Search 7 unable to bootstrap the cluster due to master not discovered yet&lt;/a&gt;（这个comment离我找到它只隔了3天，超级新的问题）：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Remove the port from the cluster.initial_master_nodes setting, and it will work. We have updated the docs recently to make it clearer that either node name, or ip/port is to be used. Node name/port is not a valid combination.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://discuss.elastic.co/t/elastic-search-7-unable-to-bootstrap-the-cluster-due-to-master-not-discovered-yet/182073/4&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;另一个comment&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It is intentional. This setting does not denote a hostname, but the node name or the advertised publish address. In particular, it is not an address that is resolved or actively connected to. The discovery.seed_hosts setting is used for that. The cluster.initial_master_nodes setting is used to determine the identities of the subset of master-eligible nodes that participate in the bootstrapping process after discovery.seed_hosts has established a connection to the nodes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在后续的实践中遇到了新问题，之前测试因为都一直使用一个物理机，并将所有的es节点都部署在同一个docker network下，因此没有发现问题。&lt;/p&gt;
&lt;p&gt;问题描述：如果将不同的容器放入并非同一个而是分开的单独network中，集群的组建就不能依赖docker network当中内部的host，而是需要手动设定，否则集群无法组建起来。&lt;/p&gt;
&lt;p&gt;这个问题和kafka集群的INSIDE、OUTSIDE设置，需要配置不同的HOST是一样的道理。为了让es集群各节点能在隔离的网络下互相访问，需要在设置中指明内部流量应该通过什么地址进行相互发现。上文中关于集群组建的相关配置一个都不能少，也不需要改动，这里需要做的配置改动是引进一个新的配置项：&lt;code class=&quot;language-text&quot;&gt;network.publish_host&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;参见：&lt;a href=&quot;https://www.elastic.co/cn/blog/docker-networking&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Docker Networking&lt;/a&gt;：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When running Elasticsearch, you will need to ensure it publishes to an IP address that is reachable from outside the container; this can be configured via the setting network.publish_host.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个配置项配置为：&lt;code class=&quot;language-text&quot;&gt;${物理主机HOST/IP}:${内部流量PORT}&lt;/code&gt;即可，e.g &lt;code class=&quot;language-text&quot;&gt;192.168.3.111:9300&lt;/code&gt;。这样集群里的各节点就可以相互发现并组成集群了。&lt;/p&gt;
&lt;h2 id=&quot;82-kibana配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#82-kibana%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;82 kibana配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2 Kibana配置&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;kibana&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;kibana:7.0.0&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;kibana&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;kibana&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_1&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_2&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_3&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;net&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;ports&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5601:5601&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;always&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*ES_LOGGING_DEFAULTS&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SERVER_PORT=5601
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SERVER_HOST=0.0.0.0
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; SERVER_NAME=es_cluster
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ELASTICSEARCH_HOSTS=&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://es_1:9201&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; KIBANA_INDEX=.kibana
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; DIBANA_DEFAULTAPPID=home
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ELASTICSEARCH_PINGTIMEOUT=1500
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ELASTICSEARCH_REQUESTTIMEOUT=10000
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ELASTICSEARCH_LOGQUERIES=false&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;相关文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/docker.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Running Kibana on Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/kibana/7.0/docker.html#environment-variable-config&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment variable configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kibana环境变量的配置和Elasticsearch不一致：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Elasticsearch使用的是数组，常量的键使用的直接是配置文件中的键，不需要转大写和下划线&lt;/li&gt;
&lt;li&gt;Kibana使用的是数组，常量的键使用的是配置文件中的键转大写，且将点转换成下划线&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当前版本有一个配置项相关非常严重的BUG：&lt;a href=&quot;https://github.com/elastic/kibana/issues/32303&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kibana fails to validate config if elasticsearch.hosts is not a string #32303&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;简单来说就是&lt;code class=&quot;language-text&quot;&gt;ELASTICSEARCH_HOSTS&lt;/code&gt;这项配置，如果写成下面的任何一种，都不正确，Kibana会报错告知找不到Elasticsearch集群：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;ELASTICSEARCH_HOSTS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//es_1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9201&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//es_2&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9202&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;//es_3&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9203&lt;/span&gt;

ELASTICSEARCH_HOSTS=&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://es_1:9201&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://es_2:9202&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http://es_3:9203&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

ELASTICSEARCH_HOSTS=es_1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9201&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;es_2&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9202&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;es_3&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9203&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;虽然上面的写法其实理论上来说都是合法的，但现在就是会出错。现在唯一的写法是：&lt;code class=&quot;language-text&quot;&gt;ELASTICSEARCH_HOSTS=[&quot;http://es_1:9201&quot;]&lt;/code&gt;。写成数组格式，但里面只能放一个节点，这样就不会出错。&lt;/p&gt;
&lt;h2 id=&quot;83-filebeat配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#83-filebeat%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;83 filebeat配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.3 Filebeat配置&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;elk-cluster.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;services&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;filebeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;elastic/filebeat:7.0.0&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;container_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;filebeat&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;hostname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;filebeat&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;depends_on&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_1&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_2&quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;es_3&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;networks&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;net&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;volumes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /private/tmp/filebeat.yaml&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/usr/share/filebeat/filebeat.yml
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /private/tmp/logs/app&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;/tmp/app/logs
    &lt;span class=&quot;token key atrule&quot;&gt;restart&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;always&quot;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;logging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*ES_LOGGING_DEFAULTS&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;environment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; ES_HOSTS=es_1&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;es_2&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;es_3&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;9200&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; LOGGING_LEVEL=debug &lt;span class=&quot;token comment&quot;&gt;# error, warning, info, debug&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; NUM_OF_OUTPUT_WORKERS=9 &lt;span class=&quot;token comment&quot;&gt;# workers会均匀分配到node：如果有3个ES的node，那么每个node会分到3个workers&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; NUM_OF_SHARDS=3
      &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; NUM_OF_REPLICAS=1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;filebeat.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;filebeat.inputs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; log
  &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /tmp/app/logs/app.web.stdout.log
  &lt;span class=&quot;token key atrule&quot;&gt;json.keys_under_root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 释放日志JSON到根节点&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; web &lt;span class=&quot;token comment&quot;&gt;# 根据日志文件，添加不同的app字段值，后续会使用该值进行不同的Index分发&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; log
  &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /tmp/app/logs/app.service.stdout.log
  &lt;span class=&quot;token key atrule&quot;&gt;json.keys_under_root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service

&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; log
  &lt;span class=&quot;token key atrule&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; /tmp/app/logs/app.consumer.stdout.log
  &lt;span class=&quot;token key atrule&quot;&gt;json.keys_under_root&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean important&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; consumer

&lt;span class=&quot;token key atrule&quot;&gt;logging.level&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;${LOGGING_LEVEL}&apos;&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;logging.selectors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;processors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;add_fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;WEB.Handler&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 根据日志内容，进行条件匹配&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;web&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 根据不同的匹配，添加不同的module字段值，后续会使用该值进行不同的Index分发&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;add_fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;7c4b822813e7&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# &quot;logger&quot;:&quot;zap@v0.0.0-20190405225521-7c4b822813e7/zap.go:46&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gin&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;add_fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gorm&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;gorm&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;add_fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Service.Rpc&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;add_fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;when&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Consumer&quot;&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;fields&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;consumer&quot;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;setup.template.name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dist&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 启用的Elasticsearch Index Template，注意这个Template必须在Elasticsearch中存在&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;setup.template.pattern&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dist-*&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Index名字匹配模式&lt;/span&gt;
&lt;span class=&quot;token key atrule&quot;&gt;setup.template.settings&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;index.number_of_shards&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;${NUM_OF_SHARDS}&apos;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;index.number_of_replicas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;${NUM_OF_REPLICAS}&apos;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;output.elasticsearch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;hosts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;${ES_HOSTS}&apos;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;worker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;${NUM_OF_OUTPUT_WORKERS}&apos;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;indices&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 根据之前添加的字段，决定应该发送日志到什么Index&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;dist-%{[fields.app]}-%{[fields.module]}-%{[agent.version]}-%{+yyyy.MM.dd}&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 注意这里使用到的Index名字需要匹配Index Template&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;elk-index-template.json&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;order&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;index_patterns&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;dist-*&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;settings&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;index&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;number_of_shards&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;number_of_replicas&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;refresh_interval&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;5s&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;相关文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/running-on-docker.html#_configure_filebeat_on_docker&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configure Filebeat on Docker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.elastic.co/guide/en/beats/filebeat/7.0/using-environ-vars.html#using-environ-vars&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Use environment variables in the configuration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Filebeat的环境变量配置和Kibana还有Elasticsearch都不一致，明明是一家公司的三个组件，居然相互之间的做法各不相同，也是服了。Filebeat的做法是在启动时设置环境变量，但这个环境变量不会自动转换并覆盖配置文件中的值，而是需要在配置文件中使用&lt;code class=&quot;language-text&quot;&gt;${ENV_KEY}&lt;/code&gt;这样的方法来使用环境变量的值。&lt;/p&gt;
&lt;p&gt;此外，关于非常重要的Index Template设置，参见：&lt;a href=&quot;#ID_FILEBEAT_INDEX_TEMPLATE&quot;&gt;6.4.4 Index Template设置&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;9-todo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#9-todo&quot; aria-label=&quot;9 todo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;9. TODO&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Elasticsearch集群及一些基本观察用的API熟悉&lt;/li&gt;
&lt;li&gt;Elasticsearch JVM相关参数和实践研究&lt;/li&gt;
&lt;li&gt;Elasticsearch reshard的策略，最佳实践&lt;/li&gt;
&lt;li&gt;Elasticsearch reshard时候的CPU、磁盘、内存，还有特别是网络的影响&lt;/li&gt;
&lt;li&gt;Elasticsearch reshard在各种集群规模下的耗时&lt;/li&gt;
&lt;li&gt;Elasticsearch的性能指标研究&lt;/li&gt;
&lt;li&gt;Elasticsearch性能测试&lt;/li&gt;
&lt;li&gt;Kibana使用深入&lt;/li&gt;
&lt;li&gt;添加Logstash部分内容，这块由于时间问题暂时不准备展开&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://sematext.com/blog/logstash-alternatives/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;5 Logstash Alternatives&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gist.github.com/StevenACoffman/4e267f0f60c8e7fcb3f77b9e504f3bd7&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;StevenACoffman/fluent-filebeat-comparison.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/fluent/fluentd/issues/1657&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Fluentd retains excessive amounts of memory after handling traffic peaks #1657&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cnblogs.com/cjsblog/p/9495024.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Filebeat 模块与配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://fdv.github.io/running-elasticsearch-fun-profit/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Operating Elasticsearch for Fun and Profit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.xiaoleilu.com/index.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch 权威指南（中文版）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/ejEG02VRoeGVaLw4j_LL&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Lucene 查询原理及解析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/27793721/what-is-the-difference-between-lucene-and-elasticsearch&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What is the difference between Lucene and Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thoughts.t37.net/designing-the-perfect-elasticsearch-cluster-the-almost-definitive-guide-e614eabc1a87&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Designing the Perfect Elasticsearch Cluster: the (almost) Definitive Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://es.xiaoleilu.com/020_Distributed_Cluster/00_Intro.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;集群内部工作方式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vvanholl/elasticsearch-prometheus-exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus Exporter Plugin for Elasticsearch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thoughts.t37.net/resizing-your-elasticsearch-indexes-in-production-d7a0402d137e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Resizing your Elasticsearch Indexes in Production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.signalfx.com/blog/scaling-elasticsearch-sharding-availability-hundreds-millions-documents/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Scaling Elasticsearch: Sharding and Availability for Hundreds Of Millions of Documents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ebayinc.com/stories/blogs/tech/elasticsearch-performance-tuning-practice-at-ebay/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch Performance Tuning Practice at eBay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/elastic/kibana/issues/3709&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Index pattern creation API #3709&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/47370280/whats-the-difference-between-the-field-and-field-keyword-fields-in-kibana&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What’s the difference between the ‘field’ and ‘field.keyword’ fields in Kibana?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/1f67e4436c37&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;初探 Elasticsearch Index Template（索引模板)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://discuss.elastic.co/t/custom-filebeat-template-for-json-log-lines/114761/5&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Custom filebeat template for JSON log lines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://discuss.elastic.co/t/log-ui-failed-to-format-message-from/163196&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Log UI failed to format message from&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/elastic/kibana/pull/26579/files#diff-3d8e25bfa60ef76c1ce7b5e7a68232f2R9&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;[InfraOps] Update docs with data source configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://discuss.elastic.co/t/best-practice-for-creating-an-index-when-an-es-docker-container-starts/126651&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Best practice for creating an index when an ES docker container starts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/35526532/how-to-add-an-elasticsearch-index-during-docker-build&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to add an elasticsearch index during docker build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/fa31f38d241e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用ElasticSearch踩过的坑&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infvie.com/ops-notes/elkstack-beats&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ELK Stack+Beats 搭建分布式日志平台&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/6a700cc61913&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elasticsearch安装配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://logz.io/blog/elasticsearch-cluster-tutorial/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Creating an Elasticsearch Cluster: Getting Started&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/yaml/yaml/issues/35&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Merge arrays #35&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/4948933/is-there-a-way-to-alias-anchor-an-array-in-yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Is there a way to alias/anchor an array in YAML?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://discuss.elastic.co/t/elastic-search-7-unable-to-bootstrap-the-cluster-due-to-master-not-discovered-yet/182073/2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Elastic Search 7 unable to bootstrap the cluster due to master not discovered yet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/elastic/kibana/issues/32303&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Kibana fails to validate config if elasticsearch.hosts is not a string #32303&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://qbox.io/blog/optimizing-elasticsearch-how-many-shards-per-index&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Optimizing Elasticsearch: How Many Shards per Index?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Jaeger Notes]]></title><link>https://xenojoshua.com/posts/2019/04/jaeger-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/jaeger-note</guid><pubDate>Wed, 17 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-opentracing&quot;&gt;2. OpenTracing&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-trace&quot;&gt;2.1 Trace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-span&quot;&gt;2.2 Span&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#221-trace%E4%B8%8Espan%E5%85%B3%E7%B3%BB&quot;&gt;2.2.1 Trace与Span关系&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#222-span%E5%B1%9E%E6%80%A7&quot;&gt;2.2.2 Span属性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#223-span-context%E5%B1%9E%E6%80%A7&quot;&gt;2.2.3 Span Context属性&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#224-span%E9%97%B4%E5%85%B3%E7%B3%BB&quot;&gt;2.2.4 Span间关系&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-jaeger%E6%9E%B6%E6%9E%84&quot;&gt;3. Jaeger架构&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-jaeger-client&quot;&gt;3.1 Jaeger Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-jaeger-agent&quot;&gt;3.2 Jaeger Agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-jaeger-collector&quot;&gt;3.3 Jaeger Collector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-data-store&quot;&gt;3.4 Data Store&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#341-elasticsearch%E6%94%AF%E6%8C%81&quot;&gt;3.4.1 ElasticSearch支持&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-jaeger-query&quot;&gt;3.5 Jaeger Query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#36-jaeger-ingester&quot;&gt;3.6 Jaeger Ingester&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#37-%E6%97%A5%E5%BF%97%E6%A8%A1%E5%BC%8F&quot;&gt;3.7 日志模式&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-jaeger%E4%BD%BF%E7%94%A8&quot;&gt;4. Jaeger使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-jaeger-collector%E5%8D%95%E7%8B%AC%E5%90%AF%E5%8A%A8&quot;&gt;4.1 Jaeger Collector单独启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-jaeger-agent%E5%8D%95%E7%8B%AC%E5%90%AF%E5%8A%A8&quot;&gt;4.2 Jaeger Agent单独启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-jaeger-query%E5%8D%95%E7%8B%AC%E5%90%AF%E5%8A%A8&quot;&gt;4.3 Jaeger Query单独启动&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-jaeger%E9%AB%98%E5%8F%AF%E7%94%A8&quot;&gt;5. Jaeger高可用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-metrics&quot;&gt;5.1 Metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-components&quot;&gt;5.2 Components&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#521-client&quot;&gt;5.2.1 Client&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#522-agent&quot;&gt;5.2.2 Agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#523-collector&quot;&gt;5.2.3 Collector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#524-data-store&quot;&gt;5.2.4 Data Store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-jaeger%E9%87%87%E6%A0%B7&quot;&gt;6. Jaeger采样&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-client%E9%85%8D%E7%BD%AE&quot;&gt;6.1 Client配置&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#611-constant&quot;&gt;6.1.1 Constant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#612-probabilistic&quot;&gt;6.1.2 Probabilistic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#613-rate-limiting&quot;&gt;6.1.3 Rate Limiting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#614-remote&quot;&gt;6.1.4 Remote&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-collector%E9%85%8D%E7%BD%AE&quot;&gt;6.2 Collector配置&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-jaeger%E7%9B%91%E6%8E%A7&quot;&gt;7. Jaeger监控&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#71-exporter&quot;&gt;7.1 Exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#72-grafana-dashboard&quot;&gt;7.2 Grafana Dashboard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-docker%E9%9B%86%E7%BE%A4%E5%AE%9E%E8%B7%B5&quot;&gt;8. Docker集群实践&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#81-docker%E9%9B%86%E7%BE%A4%E9%85%8D%E7%BD%AE&quot;&gt;8.1 Docker集群配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#82-storage-schema&quot;&gt;8.2 Storage Schema&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#821-%E4%BD%BF%E7%94%A8cqlsh%E5%AF%BC%E5%85%A5&quot;&gt;8.2.1 使用cqlsh导入&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#822-%E5%B7%A5%E5%85%B7%E9%95%9C%E5%83%8F%E5%AF%BC%E5%85%A5&quot;&gt;8.2.2 工具镜像导入&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#83-opentracing-coding-tutorial&quot;&gt;8.3 Opentracing Coding Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#84-client-coding&quot;&gt;8.4 Client Coding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#9-todo&quot;&gt;9. TODO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#help&quot;&gt;Help&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-agent---help&quot;&gt;jaeger-agent —help&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-collector-memory---help&quot;&gt;jaeger-collector memory —help&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-query---help&quot;&gt;jaeger-query —help&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#metrics&quot;&gt;Metrics&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-agent-metrics&quot;&gt;jaeger-agent metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-collector-metrics&quot;&gt;jaeger-collector metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-query-metrics&quot;&gt;jaeger-query metrics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Tracing是最近才慢慢开始普及起来的一个概念。现在越来越多的系统转向微服务，或者类似于微服务设计的分布式系统，系统内部的复杂度越来越高，导致观察某一个请求的整个生命周期非常困难，查错也很困难。为了解决这样的问题，Tracing这个需求就被慢慢提出来了。最早的解决方案是一个开源项目被称为：&lt;a href=&quot;https://zipkin.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Zipkin&lt;/a&gt;。后来CNCF对Tracing做了一个规范：&lt;a href=&quot;https://opentracing.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OpenTracing&lt;/a&gt;，在CNCF里也孵化了一个项目：&lt;a href=&quot;https://www.jaegertracing.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Jaeger&lt;/a&gt;。现在基本上有这方面需求的，都会使用Jaeger，前浪死在沙滩上啊。&lt;/p&gt;
&lt;p&gt;关于监控、追踪、日志三者的区别，可以查看：&lt;a href=&quot;/2019/04/monitoring-tracing-logging/&quot;&gt;Compare: Monitoring | Tracing | Logging&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;以下所有针对Jaeger的讨论都基于版本：&lt;code class=&quot;language-text&quot;&gt;1.11.0&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;外部链接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;阿里云的一篇博文很不错，可以看下：&lt;a href=&quot;https://yq.aliyun.com/articles/514488&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开放分布式追踪（OpenTracing）入门与 Jaeger 实现&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/a963ad0bbe3e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OpenTracing语义标准规范及实现&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-opentracing&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-opentracing&quot; aria-label=&quot;2 opentracing permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. OpenTracing&lt;/h1&gt;
&lt;p&gt;OpenTracing在CNCF里有其站点：&lt;a href=&quot;https://opentracing.io&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;opentracing.io&lt;/a&gt;，这个站点主要是进行一些大概念的介绍，基本上没什么可用的实现，而实现可以看上面提到过的Jaeger，当然本文后面也会介绍。&lt;/p&gt;
&lt;p&gt;该站点的文档中，有意义的部分从：&lt;a href=&quot;https://opentracing.io/docs/overview/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OpenTracing Overview&lt;/a&gt;开始。文档概念性的部分过完之后，其他部分基本上就可以忽略了。&lt;/p&gt;
&lt;p&gt;OpenTracing有官方的Specification：&lt;a href=&quot;https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/specification.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CN汉化版&lt;/a&gt;，以及&lt;a href=&quot;https://opentracing.io/specification/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;EN原版&lt;/a&gt;。既然是SPEC，里面也就包含了所有需要了解的信息，有时间的可以通读一遍。&lt;/p&gt;
&lt;p&gt;这里需要注意，SPEC是有明确版本的，当前的版本为：&lt;code class=&quot;language-text&quot;&gt;1.1&lt;/code&gt; - &lt;code class=&quot;language-text&quot;&gt;19 Sep 2018&lt;/code&gt;。&lt;br&gt;
前一版本为：1.0 - 23 Dec 2016，可以看到版本基本上很稳定。&lt;/p&gt;
&lt;p&gt;此外，对于SPEC，有一些&lt;a href=&quot;https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/semantic_conventions.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;语义惯例&lt;/a&gt;可以看下。&lt;/p&gt;
&lt;p&gt;主要需要遵循的有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/semantic_conventions.md#span-tag-%E6%B8%85%E5%8D%95&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Span tag 清单&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/semantic_conventions.md#log-field-%E6%B8%85%E5%8D%95&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Log field 清单&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/opentracing-contrib/opentracing-specification-zh/blob/master/semantic_conventions.md#%E5%85%B8%E5%9E%8B%E5%9C%BA%E6%99%AF%E5%BB%BA%E6%A8%A1&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;典型场景建模&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果应用场景符合上述范例中定义的情况，则务必需要遵循这些规范。这有点类似于写代码的时候的Coding Style，虽然代码编译执行可能没有任何问题，但为了统一编码的可读性还是需要遵循规范。&lt;/p&gt;
&lt;p&gt;下文会从组成Tracing的一些概念着手开始逐步介绍。&lt;/p&gt;
&lt;h2 id=&quot;21-trace&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-trace&quot; aria-label=&quot;21 trace permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 Trace&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Trace: The description of a transaction as it moves through a distributed system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Trace：一个在分布式系统内运作的事务。&lt;/p&gt;
&lt;p&gt;Trace代表着一个完整的事务，举个例子来说，如果有一个复杂的API系统，内部的API后台由大量的微服务实现，而一个可能需要十来个甚至更多的微服务协同处理的&lt;code class=&quot;language-text&quot;&gt;API请求&lt;/code&gt;，就是一个&lt;code class=&quot;language-text&quot;&gt;Trace&lt;/code&gt;。而这个例子中每一个微服务，其所作的工作就可以被认为是一个&lt;code class=&quot;language-text&quot;&gt;Span&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&quot;22-span&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-span&quot; aria-label=&quot;22 span permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 Span&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Span: A named, timed operation representing a piece of the workflow. Spans accept key:value tags as well as fine-grained, timestamped, structured logs attached to the particular span instance.
Span context: Trace information that accompanies the distributed transaction, including when it passes the service to service over the network or through a message bus. The span context contains the trace identifier, span identifier, and any other data that the tracing system needs to propagate to the downstream service.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Span：一个被命名、被计时，代表着一段工作流的操作。Spans实例接受键值对的tags，以及含有细节的、计时的、结构化的日志内容。&lt;/p&gt;
&lt;p&gt;Span context：伴随着分布式事务产生的Trace相关的信息，包含了该事务通过网络或消息总线在服务之间传递的时间。此外还包含了：trace标识符、span标识符，以及其他任何tracing系统需要用来衍生下游服务所需要的数据。&lt;/p&gt;
&lt;h3 id=&quot;221-trace与span关系&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#221-trace%E4%B8%8Espan%E5%85%B3%E7%B3%BB&quot; aria-label=&quot;221 trace与span关系 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.1 Trace与Span关系&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/jaeger-note/spans-traces.png&quot; alt=&quot;Relationship&quot;&gt;&lt;/p&gt;
&lt;p&gt;上图是一个Trace和Span的关系范例图。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从时间轴上可以看到，A覆盖了所有下面子条目的时间，这很容易理解：所有的Span组成一个Trace，而每个Span实际上都消耗了时间，这些时间的总合就是Trace的时间消耗&lt;/li&gt;
&lt;li&gt;Span有父子级别概念：B和C以及D的关系就是父子，而C和D则不是父子关系，父子的时间是&lt;code class=&quot;language-text&quot;&gt;重合&lt;/code&gt;的，就类似所有子Span和Trace之间的时间关系，B消耗的时间是C和D的时间总合，而A消耗的时间则是B和E的总合&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;图中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Trace &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt;中，&lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;E&lt;/code&gt;是&lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt;的子Span&lt;/li&gt;
&lt;li&gt;在Trace &lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt;中，&lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;E&lt;/code&gt;顺序执行，&lt;code class=&quot;language-text&quot;&gt;E&lt;/code&gt;的执行需要等待&lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;的完成&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;A&lt;/code&gt;的消耗时长为&lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;E&lt;/code&gt;的总合（这里都是理想情况）&lt;/li&gt;
&lt;li&gt;在Span &lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;中，&lt;code class=&quot;language-text&quot;&gt;C&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;D&lt;/code&gt;是&lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;的子Span&lt;/li&gt;
&lt;li&gt;在Span &lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;中，&lt;code class=&quot;language-text&quot;&gt;C&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;D&lt;/code&gt;顺序执行，&lt;code class=&quot;language-text&quot;&gt;D&lt;/code&gt;的执行需要等待&lt;code class=&quot;language-text&quot;&gt;C&lt;/code&gt;的完成&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;B&lt;/code&gt;的消耗时长为&lt;code class=&quot;language-text&quot;&gt;C&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;D&lt;/code&gt;的总合（这里都是理想情况）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;222-span属性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#222-span%E5%B1%9E%E6%80%A7&quot; aria-label=&quot;222 span属性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.2 Span属性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;An operation name&lt;/code&gt;，操作名称&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;A start timestamp&lt;/code&gt;，起始时间&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;A finish timestamp&lt;/code&gt;，结束时间&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Span Tag&lt;/code&gt;，一组键值对构成的Span标签集合。键值对中，键必须为string，值可以是字符串，布尔，或者数字类型&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Span Log&lt;/code&gt;，一组span的日志集合
&lt;ul&gt;
&lt;li&gt;每次log操作包含一个键值对，以及一个时间戳&lt;/li&gt;
&lt;li&gt;键值对中，键必须为string，值可以是任意类型&lt;/li&gt;
&lt;li&gt;但是需要注意，不是所有的支持OpenTracing的Tracer，都需要支持所有的值类型&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SpanContext&lt;/code&gt;，Span上下文对象&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;References&lt;/code&gt;，Span间关系，相关的零个或者多个Span（Span间通过SpanContext建立这种关系）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Span Tag 范例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;db.instance:“jdbc:mysql://127.0.0.1:3306/customers”&lt;/li&gt;
&lt;li&gt;db.statement:“SELECT * FROM mytable WHERE foo=‘bar’;”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Span Logs 范例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;message:“Can’t connect to mysql server on ‘127.0.0.1’(10061)”&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;223-span-context属性&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#223-span-context%E5%B1%9E%E6%80%A7&quot; aria-label=&quot;223 span context属性 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.3 Span Context属性&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;任何一个OpenTracing的实现，都需要将当前调用链的状态（例如：trace和span的id），依赖一个独特的Span去跨进程边界传输&lt;/li&gt;
&lt;li&gt;Baggage Items，Trace的随行数据，是一个键值对集合，它存在于trace中，也需要跨进程边界传输&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SpanContext 范例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;trace_id:“abc123”&lt;/li&gt;
&lt;li&gt;span_id:“xyz789”&lt;/li&gt;
&lt;li&gt;Baggage Items:
&lt;ul&gt;
&lt;li&gt;special_id:“vsid1738”&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;224-span间关系&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#224-span%E9%97%B4%E5%85%B3%E7%B3%BB&quot; aria-label=&quot;224 span间关系 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2.4 Span间关系&lt;/h3&gt;
&lt;p&gt;一个Span可以与一个或者多个SpanContexts存在因果关系。OpenTracing目前定义了两种关系：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChildOf（父子）&lt;/li&gt;
&lt;li&gt;FollowsFrom（跟随）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ChildOf引用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个RPC调用的服务端的span，和RPC服务客户端的span构成ChildOf关系&lt;/li&gt;
&lt;li&gt;一个sql insert操作的span，和ORM的save方法的span构成ChildOf关系&lt;/li&gt;
&lt;li&gt;很多span可以并行工作（或者分布式工作）都可能是一个父级的span的子项，他会合并所有子span的执行结果，并在指定期限内返回&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-jaeger架构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-jaeger%E6%9E%B6%E6%9E%84&quot; aria-label=&quot;3 jaeger架构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Jaeger架构&lt;/h1&gt;
&lt;p&gt;官网上（&lt;a href=&quot;https://www.jaegertracing.io/docs/1.11/architecture/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Architecture&lt;/a&gt;）有一张架构图，可以先看下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/jaeger-note/architecture.png&quot; alt=&quot;Architecture&quot;&gt;&lt;/p&gt;
&lt;p&gt;图上的内容主要分几个部分，下面一个个说。&lt;/p&gt;
&lt;h2 id=&quot;31-jaeger-client&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-jaeger-client&quot; aria-label=&quot;31 jaeger client permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 Jaeger Client&lt;/h2&gt;
&lt;p&gt;Jaeger client是之前提到的OpenTracing API的多语言实现。这部分是嵌在你的应用程序里的一个&lt;code class=&quot;language-text&quot;&gt;类库&lt;/code&gt;，它就是你的应用程序的一部分，使用它你就可以在收到Request的时候创建对应的Span，并向下游Request输出对应的Trace上下文。&lt;/p&gt;
&lt;p&gt;Jaeger Client可以直接向Collector发送Trace信息，也可以结合本地的Agent协同工作，降低性能开销。实际上这部分的性能开销不会很大。&lt;/p&gt;
&lt;h2 id=&quot;32-jaeger-agent&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-jaeger-agent&quot; aria-label=&quot;32 jaeger agent permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 Jaeger Agent&lt;/h2&gt;
&lt;p&gt;Jaeger Agent是和目标应用程序并行部署的一个组件，可以理解为边车设计中的&lt;code class=&quot;language-text&quot;&gt;边车&lt;/code&gt;的组成部分之一。它是一个长期启动的守护进程，通过监听UDP网络接收Client发送过来的Trace信息，并批量向Collector发送。在设计上，Agent可以将路由和服务发现相关的业务从Client里解耦出来。&lt;/p&gt;
&lt;h2 id=&quot;33-jaeger-collector&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-jaeger-collector&quot; aria-label=&quot;33 jaeger collector permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 Jaeger Collector&lt;/h2&gt;
&lt;p&gt;Jaeger Collector可以说是Jaeger的&lt;code class=&quot;language-text&quot;&gt;服务器&lt;/code&gt;，接收从Agent发送过来的Trace信息，并对其进行验证、索引、转换，并最终将其存储起来。&lt;/p&gt;
&lt;h2 id=&quot;34-data-store&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-data-store&quot; aria-label=&quot;34 data store permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 Data Store&lt;/h2&gt;
&lt;p&gt;Jaeger的数据存储是可插拔式组件设计，有多种数据后端可选：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cassandra&lt;/li&gt;
&lt;li&gt;Elasticsearch&lt;/li&gt;
&lt;li&gt;Kafka (only as a buffer)，即并不能把Kafka当做最终存储设施&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;存储选择是个问题，我简单搜索了下，没有找到非常权威的帖子对这三者进行横向比较，也可能是因为这块的技术比较新发展比较快。就我来看，个人建议是熟悉什么用什么，以不增加系统复杂度为第一要务。猜想：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cassandra大概是稳定性最好的，大数据量的选择应该是这个&lt;/li&gt;
&lt;li&gt;功能上大概是ELK最好，本来它就是以全文搜索为功能设计出来的系统&lt;/li&gt;
&lt;li&gt;性能上应该是Kafka最高，毕竟Kafka的吞吐量是有口皆碑的（中间通道）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从官方的文档口径上来看，最推荐的应该是使用Kafka和Ingester组成通道，然后使用Cassandra作为存储设备。&lt;/p&gt;
&lt;h3 id=&quot;341-elasticsearch支持&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#341-elasticsearch%E6%94%AF%E6%8C%81&quot; aria-label=&quot;341 elasticsearch支持 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4.1 ElasticSearch支持&lt;/h3&gt;
&lt;p&gt;Jaeger最佳支持的后端存储是Cassandra，Elasticsearch是第二个官方支持的存储设施。文档在：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/blob/master/plugin/storage/es/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ElasticSearch Support&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;需要注意的是，当前版本&lt;code class=&quot;language-text&quot;&gt;1.11.x&lt;/code&gt;是不支持Elasticsearch最新版本&lt;code class=&quot;language-text&quot;&gt;7.x&lt;/code&gt;的：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/1474&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Support Elasticsearch 7.x #1474&lt;/a&gt;，而且看情况短期内应该也不会支持。后面我做practice的时候就直接选择cassandra作为存储了，毕竟存储还是安全第一。&lt;/p&gt;
&lt;h2 id=&quot;35-jaeger-query&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#35-jaeger-query&quot; aria-label=&quot;35 jaeger query permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.5 Jaeger Query&lt;/h2&gt;
&lt;p&gt;Jaeger的查询引擎，UI发送查询请求到该组件，然后查询引擎会查询后台数据仓库，返回结果。该组件启动的时候已经附带启动了HTTP的UI界面。&lt;/p&gt;
&lt;h2 id=&quot;36-jaeger-ingester&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#36-jaeger-ingester&quot; aria-label=&quot;36 jaeger ingester permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.6 Jaeger Ingester&lt;/h2&gt;
&lt;p&gt;组件上还有个Ingester，但基本上没找到什么相关信息。官方介绍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ingester is a service that reads from Kafka topic and writes to another storage backend (Cassandra, Elasticsearch).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;感觉应该是一个解决吞吐量的中间件。&lt;/p&gt;
&lt;h2 id=&quot;37-日志模式&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#37-%E6%97%A5%E5%BF%97%E6%A8%A1%E5%BC%8F&quot; aria-label=&quot;37 日志模式 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.7 日志模式&lt;/h2&gt;
&lt;p&gt;按照Jaeger当前的设计，Client和Agent之间是使用UDP进行通讯，必须是实时连接的，这就对Agent的健壮性提出了要求，如果当前Agent已挂，Client就基本上不可用了。而日志文件化的好处就是将Client和Agent彻底解耦，使用操作系统的磁盘IO来解决Tracing生成的问题，而这方面，官方&lt;code class=&quot;language-text&quot;&gt;并没有计划&lt;/code&gt;要这么做，没有任何关于这方面的设计讨论（至少我没找到）。&lt;/p&gt;
&lt;p&gt;而官方倒是有讨论：如果有一个外部存储已经存放了Tracing相关数据，能不能直接使用Query连接上去进行Tracing数据的展示和分析。见：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/649&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Integration with external logs storage when displaying traces #649&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果这个实现的话，实际上就完全绕过了Jaeger的整个生命周期：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不再需要在应用程序中嵌入Jaeger的Client（直接使用日志组件将Tracing打成日志）&lt;/li&gt;
&lt;li&gt;不再需要在边车中放置Jaeger的Agent（只要有日志聚合的Agent即可：Logstash、Filebeat）&lt;/li&gt;
&lt;li&gt;不再需要启动Collector集群（直接由日志聚合Agent发送到Elaticsearch）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只需要直接沿用（如果在用的话）ELK系列日志聚合系统，然后用Jaeger的Query直接连接到Elasticsearch上进行Tracing对应的日志分析就可以了。这样即减少了系统的整体复杂度（不需要Jaeger的一整套东西了），又降低了系统整体负载（磁盘IO永远是最便宜的东西）。&lt;/p&gt;
&lt;p&gt;就看今后发展了。不过如果这真的实现了，Jaeger项目还有必要存在么。。。&lt;/p&gt;
&lt;h1 id=&quot;4-jaeger使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-jaeger%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;4 jaeger使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Jaeger使用&lt;/h1&gt;
&lt;p&gt;初步入门可以查看官方文档：&lt;a href=&quot;https://www.jaegertracing.io/docs/1.11/getting-started/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Getting started&lt;/a&gt;。实际生产环境的安装和部署，需要仔细阅读官方文档：&lt;a href=&quot;https://www.jaegertracing.io/docs/1.11/deployment/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deployment&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;如果使用&lt;code class=&quot;language-text&quot;&gt;all-in-one&lt;/code&gt;范例镜像的话，可以：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run -d --name jaeger \
  -e COLLECTOR_ZIPKIN_HTTP_PORT=9411 \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  -p 16686:16686 \
  -p 14268:14268 \
  -p 9411:9411 \
  jaegertracing/all-in-one:1.11.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里主要要了解下一堆端口：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;Port&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Protocol&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Component&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Function&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;5775&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;UDP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;agent&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;accept zipkin.thrift over compact thrift protocol (deprecated, used by legacy clients only)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;6831&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;UDP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;agent&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;accept jaeger.thrift over compact thrift protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;6832&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;UDP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;agent&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;accept jaeger.thrift over binary thrift protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;5778&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTTP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;agent&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;serve configs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;16686&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTTP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;query&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;serve frontend&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;16687&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTTP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;query&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;The http port for the health check service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;14267&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;TChannel&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;collector&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;The TChannel port for the collector service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;14268&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTTP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;collector&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;accept jaeger.thrift directly from clients&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;14269&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTTP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;collector&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;The http port for the health check service&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;14250&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;gRPC&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;collector&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;accept model.proto&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;9411&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;HTTP&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;collector&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;Zipkin compatible endpoint (optional)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;p&gt;&lt;strong&gt;部分补充：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jaegertracing.io/docs/1.11/getting-started/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Getting started&lt;/a&gt;范例的官方文档里缺一个端口&lt;code class=&quot;language-text&quot;&gt;14267&lt;/code&gt;。这个端口的Protocol被描述成&lt;code class=&quot;language-text&quot;&gt;TChannel&lt;/code&gt;，可搜索文档&lt;a href=&quot;https://www.jaegertracing.io/docs/1.11/deployment/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Deployment&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run \
  -e SPAN_STORAGE_TYPE=memory \
  jaegertracing/jaeger-collector:1.11.0 \
  --help

...
--collector.port int    The TChannel port for the collector service (default 14267)
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;此外，端口&lt;code class=&quot;language-text&quot;&gt;14250&lt;/code&gt;的说明也不够清楚，实际上它的Protocol是gRPC，也就是HTTP2：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;...
--collector.grpc-port int    The gRPC port for the collector service (default 14250)
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;以及，&lt;code class=&quot;language-text&quot;&gt;14268&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;...
--collector.http-port int    The HTTP port for the collector service (default 14268)
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;41-jaeger-collector单独启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-jaeger-collector%E5%8D%95%E7%8B%AC%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;41 jaeger collector单独启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 Jaeger Collector单独启动&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;#jaeger-collector-memory---help&quot;&gt;jaeger-collector memory —help&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run -d --name jaeger-collector \
  -e SPAN_STORAGE_TYPE=memory \
  -p 14267:14267 \
  -p 14268:14268 \
  -p 14250:14250 \
  jaegertracing/jaeger-collector:1.11.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;42-jaeger-agent单独启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-jaeger-agent%E5%8D%95%E7%8B%AC%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;42 jaeger agent单独启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 Jaeger Agent单独启动&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;#jaeger-agent---help&quot;&gt;jaeger-agent —help&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run -d --name jaeger-agent \
  --link jaeger-collector \
  -p 5775:5775/udp \
  -p 6831:6831/udp \
  -p 6832:6832/udp \
  -p 5778:5778 \
  jaegertracing/jaeger-agent:1.11.0 \
  --reporter.type=grpc \
  --reporter.grpc.host-port=jaeger-collector:14250&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;43-jaeger-query单独启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-jaeger-query%E5%8D%95%E7%8B%AC%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;43 jaeger query单独启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 Jaeger Query单独启动&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;#jaeger-query---help&quot;&gt;jaeger-query —help&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run -d --name jaeger-query \
  --link jaeger-collector \
  -e SPAN_STORAGE_TYPE=memory \
  -p 16686:16686 \
  jaegertracing/jaeger-query:1.11.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;5-jaeger高可用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-jaeger%E9%AB%98%E5%8F%AF%E7%94%A8&quot; aria-label=&quot;5 jaeger高可用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Jaeger高可用&lt;/h1&gt;
&lt;h2 id=&quot;51-metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-metrics&quot; aria-label=&quot;51 metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 Metrics&lt;/h2&gt;
&lt;p&gt;Jaeger也兼容Prometheus格式的指标输出，有两个命令行参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--metrics-backend&lt;/code&gt;：metrics暴露的格式，默认为&lt;code class=&quot;language-text&quot;&gt;prometheus&lt;/code&gt;，&lt;code class=&quot;language-text&quot;&gt;expvar&lt;/code&gt;可选&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--metrics-http-route&lt;/code&gt;：metrics暴露的endpoint，默认为&lt;code class=&quot;language-text&quot;&gt;/metrics&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，几个端口需要了解下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;Component&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;Port&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;jaeger-agent&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;5778&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;jaeger-collector&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;14268&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;jaeger-query&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;16686&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;jaeger-ingester&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;14271&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;p&gt;范例都在本文下面的资料部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-agent-metrics&quot;&gt;jaeger-agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-collector-metrics&quot;&gt;jaeger-collector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jaeger-query-metrics&quot;&gt;jaeger-query&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;jaeger-ingester（这块启动需要的依赖太重，暂时没做尝试）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;52-components&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-components&quot; aria-label=&quot;52 components permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 Components&lt;/h2&gt;
&lt;p&gt;先说结论，Jaeger在高可用这块的设计和实现基本上是空白，很可能在某些极端情况下丢失Tracing的数据。&lt;/p&gt;
&lt;h3 id=&quot;521-client&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#521-client&quot; aria-label=&quot;521 client permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2.1 Client&lt;/h3&gt;
&lt;p&gt;Client因为只是应用程序的Lib部分，因此不涉及到任何高可用的概念。&lt;/p&gt;
&lt;h3 id=&quot;522-agent&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#522-agent&quot; aria-label=&quot;522 agent permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2.2 Agent&lt;/h3&gt;
&lt;p&gt;Agent部分就只是一个转发机关，我查了下对应的文档和网络没找到高可用的设计，此外错误处理基本上也是没有的。也就是说，如果Agent出问题，所有当前未发送缓存中的数据都会丢失，且从Client传输到Agent的数据也会丢失。&lt;/p&gt;
&lt;p&gt;见：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/1255&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What happens when the jaeger-agent is down on a machine? #1255&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/1430&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Jaeger Agent does not buffer spans when the Collector is unavailable #1430&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;523-collector&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#523-collector&quot; aria-label=&quot;523 collector permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2.3 Collector&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The collectors are stateless and thus many instances of jaeger-collector can be run in parallel.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这和我一开始的理解有点不同。我之前认为对同个Trace的多个子Span的识别和清洗过滤等行为是在Collector这个环节处理的，但既然官方文档都说明Collector是无状态的了，那就不是了。Collector应该只负责简单的Validation然后就直接存储到后台的Data Store里了。&lt;/p&gt;
&lt;p&gt;如果对Agent配置了以&lt;code class=&quot;language-text&quot;&gt;,&lt;/code&gt;分隔的多台无状态Collectors，而其中某台Down了会发生什么，后面需要做测试，按现在Jaeger对错误处理和可用性的支持来看，估计就是直接丢数据了。&lt;/p&gt;
&lt;p&gt;同个Trace的多个组成部分Span是否都到达，是否缺失了一部分，看来是没有任何处理和保证的。这也就是说：可能会有部分Trace在UI中可以查到，但其中组成部分的Spans是不完整的，部分缺失的。说实在的，这还蛮致命的。&lt;/p&gt;
&lt;h3 id=&quot;524-data-store&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#524-data-store&quot; aria-label=&quot;524 data store permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2.4 Data Store&lt;/h3&gt;
&lt;p&gt;这块就完全由选择的后台数据存储设施自己负责了，Cassandra是出了名的好用，Kafka在扩展上也不错，但Kafka仅只能作为中间通道使用，官方文档描述为：&lt;code class=&quot;language-text&quot;&gt;kafka (only as a buffer)&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;6-jaeger采样&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-jaeger%E9%87%87%E6%A0%B7&quot; aria-label=&quot;6 jaeger采样 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Jaeger采样&lt;/h1&gt;
&lt;p&gt;在&lt;a href=&quot;/2019/04/monitoring-tracing-logging/&quot;&gt;Compare: Monitoring | Tracing | Logging&lt;/a&gt;里我已经提到过，tracing是一件频度相当高，且数据量很庞大的工作，因此其性能很可能有问题。Jaeger给了一个新的思路，就是按规则采样，而不是将所有发生的事件全部都发送并存储。&lt;/p&gt;
&lt;p&gt;这里需要说明的是采样的决策。如果一个链路很长的Trace，其中每一个Span都有权决定当前信息是否需要被采样，那么你就永远看不到一个完整的Trace了。组成Trace的A、B、C，Span A决定采样，B决定不采样，C决定采样，结果Trace就丢失了B部分数据。&lt;/p&gt;
&lt;p&gt;Jaeger采样的决策是在链路的第一节点就决定好了的，当前的Trace是否需要被采样，该决策做出之后，后续整个链路中所有的Span都需要按整个决策执行。这样就不会丢失数据了。&lt;/p&gt;
&lt;p&gt;见：&lt;a href=&quot;https://www.jaegertracing.io/docs/1.11/sampling/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Sampling&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The sampling decision will be propagated with the requests to B and to C, so those services will not be making the sampling decision again but instead will respect the decision made by the top service A. This approach guarantees that if a trace is sampled, all its spans will be recorded in the backend. If each service was making its own sampling decision we would rarely get complete traces in the backend.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;关于采样的策略，官方也看到了不少问题，后续有一个正在制作中的功能&lt;code class=&quot;language-text&quot;&gt;Adaptive Sampling&lt;/code&gt;，具体的问题和设计可以看：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/365&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Adaptive Sampling #365&lt;/a&gt;。简单来说就是可以按更复杂的策略进行采样的决策。&lt;/p&gt;
&lt;h2 id=&quot;61-client配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-client%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;61 client配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 Client配置&lt;/h2&gt;
&lt;p&gt;最基础的策略，采样是按&lt;code class=&quot;language-text&quot;&gt;Client&lt;/code&gt;的配置进行执行的，记住，这种情况下采样是在客户端做的，而不是服务器，而且每个客户端都可以做不同的策略。&lt;/p&gt;
&lt;p&gt;此外，光阅读文档可能会理解不全，可以查看issue来加深理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/832&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How sampler.type=remote works #832&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;611-constant&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#611-constant&quot; aria-label=&quot;611 constant permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1.1 Constant&lt;/h3&gt;
&lt;p&gt;常量决策。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类型：&lt;code class=&quot;language-text&quot;&gt;sampler.type=const&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;值：
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sampler.param=1&lt;/code&gt;：全部采样&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sampler.param=0&lt;/code&gt;：全部丢弃&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;612-probabilistic&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#612-probabilistic&quot; aria-label=&quot;612 probabilistic permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1.2 Probabilistic&lt;/h3&gt;
&lt;p&gt;概率决策。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类型：&lt;code class=&quot;language-text&quot;&gt;sampler.type=probabilistic&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;值：&lt;code class=&quot;language-text&quot;&gt;sampler.param=0.1&lt;/code&gt;表示 采样 1/10&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;613-rate-limiting&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#613-rate-limiting&quot; aria-label=&quot;613 rate limiting permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1.3 Rate Limiting&lt;/h3&gt;
&lt;p&gt;频次策略。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类型：&lt;code class=&quot;language-text&quot;&gt;sampler.type=ratelimiting&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;值：&lt;code class=&quot;language-text&quot;&gt;sampler.param=2.0&lt;/code&gt;表示 每秒 采样2次&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;614-remote&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#614-remote&quot; aria-label=&quot;614 remote permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1.4 Remote&lt;/h3&gt;
&lt;p&gt;远端决策。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;类型：&lt;code class=&quot;language-text&quot;&gt;sampler.type=remote&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种情况下，Client会把请求发到Agent，而Agent则会进行判断是否进行采样。实际的配置则是放在Collector上，参见下面的&lt;code class=&quot;language-text&quot;&gt;6.2&lt;/code&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;sampler consults Jaeger agent for the appropriate sampling strategy to use in the current service.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;62-collector配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-collector%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;62 collector配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 Collector配置&lt;/h2&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://www.jaegertracing.io/docs/1.11/sampling/#collector-sampling-configuration&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Collector Sampling Configuration&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;在&lt;code class=&quot;language-text&quot;&gt;Client&lt;/code&gt;采样策略配置为：&lt;code class=&quot;language-text&quot;&gt;sampler.type=remote&lt;/code&gt;的情况下，Agent会向Collector进行采样策略询问，这部分配置是放在&lt;code class=&quot;language-text&quot;&gt;Collector&lt;/code&gt;上的。需要在Collector启动的时候指定配置文件：&lt;code class=&quot;language-text&quot;&gt;--sampling.strategies-file&lt;/code&gt;。见：&lt;a href=&quot;#ID_APP_COLLECTOR_HELP&quot;&gt;jaeger-collector memory —help&lt;/a&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This option requires a path to a json file which have the sampling strategies defined.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;service_strategies&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;service&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;probabilistic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;param&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;operation_strategies&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;operation&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;op1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;probabilistic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;param&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;operation&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;op2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;probabilistic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;param&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;service&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;bar&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;ratelimiting&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&quot;param&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;default_strategy&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;probabilistic&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;param&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;service_strategies&lt;/code&gt;定义了服务级别的采样策略，&lt;code class=&quot;language-text&quot;&gt;operation_strategies&lt;/code&gt;则定义了操作级别的采样策略。而实施的采样策略有两种可能：&lt;code class=&quot;language-text&quot;&gt;概率策略&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;频次策略&lt;/code&gt;（注意：操作级别的采样策略 不支持 频次策略）。&lt;code class=&quot;language-text&quot;&gt;default_strategy&lt;/code&gt;定义了上述定义之外的情况下的采样策略。&lt;/p&gt;
&lt;p&gt;在上面的例子中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;所有的&lt;code class=&quot;language-text&quot;&gt;foo&lt;/code&gt;服务，都按0.8的概率策略进行采样&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;op1&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;op2&lt;/code&gt;虽然属于&lt;code class=&quot;language-text&quot;&gt;foo&lt;/code&gt;服务，但因为它们各自有自己的配置，因此按自己的配置实施，分别是0.2和0.4的概率策略&lt;/li&gt;
&lt;li&gt;所有的&lt;code class=&quot;language-text&quot;&gt;bar&lt;/code&gt;服务，都按每分钟5次的频次策略进行采样&lt;/li&gt;
&lt;li&gt;除此之外的所有都按0.5的概率频次进行采样&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;7-jaeger监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-jaeger%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;7 jaeger监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. Jaeger监控&lt;/h1&gt;
&lt;p&gt;也许是因为项目太年轻了，在监控实践的过程中实在是很难找到资料，无论是metrics指标的说明文档，还是实际操作起来的Grafana Dashboard，基本上都是空白。大量工作只能自己手动实践解决。&lt;/p&gt;
&lt;h2 id=&quot;71-exporter&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#71-exporter&quot; aria-label=&quot;71 exporter permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.1 Exporter&lt;/h2&gt;
&lt;p&gt;Jaeger应用官方直接带了metrics输出，这方面就不需要找第三方的Exporter了。&lt;/p&gt;
&lt;p&gt;端口需要简单说明下。metrics输出端口都是各服务的HTTP端口，也就是说，默认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jaeger-agent：5778&lt;/li&gt;
&lt;li&gt;jaeger-collector：14268&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于输出的metrics的说明没有找到对应的文档，官方有一个open的issue表示该工作在进行中：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/1224&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Is there a document to explain the specific meaning of various metrics? #1224&lt;/a&gt;，至少近期是没指望了。&lt;/p&gt;
&lt;p&gt;查找代码可以找到部分指标的简单说明：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/blob/v1.11.0/cmd/collector/app/metrics.go#L30&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jaeger/cmd/collector/app/metrics.go&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;72-grafana-dashboard&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#72-grafana-dashboard&quot; aria-label=&quot;72 grafana dashboard permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7.2 Grafana Dashboard&lt;/h2&gt;
&lt;p&gt;在Grafana Labs简单查找了下，没有找到可以直接使用的Dashboard。确实能搜到几个Dashboard，但时间都比较久远，Jaeger的部分metrics已经改名了，导致这些Dashboard都无法正常使用，因此一般需要手动自制Dashboard。&lt;/p&gt;
&lt;p&gt;官方有意向提供开箱即用的Dashboard，阅读下这个issue：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/789&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Could we provide pre-made Grafana dashboards for Jaeger backend components? #789&lt;/a&gt;，但一样短期内不用指望了。&lt;/p&gt;
&lt;p&gt;Issue中提到的&lt;a href=&quot;https://github.com/grafana/jsonnet-libs/tree/master/jaeger-mixin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jsonnet-libs/jaeger-mixin/&lt;/a&gt;倒是可以花点时间简单过一下。虽然不能直接使用，但对自制Dashboard有点指导帮助。&lt;/p&gt;
&lt;h1 id=&quot;8-docker集群实践&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-docker%E9%9B%86%E7%BE%A4%E5%AE%9E%E8%B7%B5&quot; aria-label=&quot;8 docker集群实践 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. Docker集群实践&lt;/h1&gt;
&lt;h2 id=&quot;81-docker集群配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#81-docker%E9%9B%86%E7%BE%A4%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;81 docker集群配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1 Docker集群配置&lt;/h2&gt;
&lt;p&gt;配置相对来说比较简单，范例地址：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/conf/dev/jaeger-cluster.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/conf/dev/jaeger-cluster.yaml&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;主要搞清楚端口号就行了，jaeger这块开的端口实在是太多了，容易搞混。不过实际上用得多的也就那几个。&lt;/p&gt;
&lt;h2 id=&quot;82-storage-schema&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#82-storage-schema&quot; aria-label=&quot;82 storage schema permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2 Storage Schema&lt;/h2&gt;
&lt;p&gt;Jaeger支持的后端主要是Cassandra，对Elasticsearch的支持有，但只是二等的（版本更新、支持、响应都比Cassandra慢），所以如果可能，尽量使用Cassandra。&lt;/p&gt;
&lt;p&gt;实验项目中使用的后端存储为Cassandra，版本为：&lt;code class=&quot;language-text&quot;&gt;3.11.4&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Jaeger在使用之前，必须对后端存储设施进行Schema的初始化，也就是说要在数据库当中创建表才能使用，下文主要讲述Cassandra作为后端的使用经验，Elasticsearch相关请查阅官方文档：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/blob/master/plugin/storage/es/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ElasticSearch Support&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;使用Cassandra作为后端，其Schema相关的导入代码存放在：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/tree/v1.11.0/plugin/storage/cassandra/schema&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jaeger/plugin/storage/cassandra/schema/&lt;/a&gt;，虽然路径是plugin，但实际上是可以单独使用的。&lt;/p&gt;
&lt;p&gt;路径中存在两份&lt;code class=&quot;language-text&quot;&gt;*.cql.tmpl&lt;/code&gt;，这实际上就是真正导入的SQL，如果不希望使用bash脚本工具，直接使用也是可以的，当然也需要像bash中的内容一样做一些准备和调整。关于cql相关，可以查看文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://cassandra.apache.org/doc/latest/cql/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The Cassandra Query Language (CQL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datastax.com/en/archived/cql/3.3/cql/cql_reference/cqlsh.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Starting cqlsh&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;821-使用cqlsh导入&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#821-%E4%BD%BF%E7%94%A8cqlsh%E5%AF%BC%E5%85%A5&quot; aria-label=&quot;821 使用cqlsh导入 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2.1 使用cqlsh导入&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;不推荐&lt;/code&gt;直接使用cqlsh这种方法，下面的7.2.2有更好的方法。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;-it&lt;/span&gt; &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;--network&lt;/span&gt; dist_net &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    cassandra:3.11.4 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    cqlsh &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;${host}&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${port}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-u&lt;/span&gt; cassandra &lt;span class=&quot;token parameter variable&quot;&gt;-p&lt;/span&gt; cassandra &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
    &lt;span class=&quot;token parameter variable&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;${file_path}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;关于Cassandra的端口号，可以查看：&lt;a href=&quot;https://docs.datastax.com/en/archived/cassandra/3.0/cassandra/configuration/secureFireWall.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configuring firewall port access&lt;/a&gt;。cqlsh连接用的端口号为client用端口号，即：&lt;code class=&quot;language-text&quot;&gt;9042&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;默认的用户名和密码：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;The default user is cassandra. The default password is cassandra. &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;822-工具镜像导入&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#822-%E5%B7%A5%E5%85%B7%E9%95%9C%E5%83%8F%E5%AF%BC%E5%85%A5&quot; aria-label=&quot;822 工具镜像导入 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2.2 工具镜像导入&lt;/h3&gt;
&lt;p&gt;实际上官方有一个docker镜像帮忙协助进行schema的创建，但你直接去看这个镜像你根本就不会知道这个镜像是干嘛的，因为什么文档都没有。官方的文档中也没提到过这个镜像，我是在google的时候搜到jaeger的维护者中某一个人的博客的时候才找到的，哎。。。只能说，怎么说呢，这文档工作。。。jaeger已经算是好的了，实际上。&lt;/p&gt;
&lt;p&gt;镜像：&lt;a href=&quot;https://hub.docker.com/r/jaegertracing/jaeger-cassandra-schema&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jaegertracing/jaeger-cassandra-schema&lt;/a&gt;。使用方法可以查看博客里的范例：&lt;a href=&quot;https://medium.com/jaegertracing/jaeger-and-multitenancy-99dfa1d49dc0&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Jaeger and multitenancy&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;例子已经比较老了，修改如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;docker&lt;/span&gt; run &lt;span class=&quot;token parameter variable&quot;&gt;--rm&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--name&lt;/span&gt; jaeger-cassandra-schema &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;--network&lt;/span&gt; dist_net &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;MODE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;test &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;CQLSH_HOST&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;cas_1 &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;token parameter variable&quot;&gt;-e&lt;/span&gt; &lt;span class=&quot;token assign-left variable&quot;&gt;KEYSPACE&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;jaeger_keyspace &lt;span class=&quot;token punctuation&quot;&gt;\&lt;/span&gt;
  jaegertracing/jaeger-cassandra-schema:1.11.0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;KEYSPACE=jaeger_keyspace&lt;/code&gt;这个名字一定要记住，后面在架设集群的时候是需要提供给collector的。&lt;/p&gt;
&lt;p&gt;具体镜像做了什么，以及这个镜像可用的环境变量设置，可以查看：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/blob/v1.11.0/plugin/storage/cassandra/schema/docker.sh&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jaeger/plugin/storage/cassandra/schema/docker.sh&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;其实这些环境变量最后还是落实到执行的脚本create.sh里，所以需要查看环境变量的作用以及脚本做了什么，可以查看：&lt;a href=&quot;https://github.com/jaegertracing/jaeger/blob/v1.11.0/plugin/storage/cassandra/schema/create.sh&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jaeger/plugin/storage/cassandra/schema/create.sh&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;83-opentracing-coding-tutorial&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#83-opentracing-coding-tutorial&quot; aria-label=&quot;83 opentracing coding tutorial permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.3 Opentracing Coding Tutorial&lt;/h2&gt;
&lt;p&gt;Opentracing Go官方是有Tutorial的：&lt;a href=&quot;https://github.com/yurishkuro/opentracing-tutorial/tree/master/go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OpenTracing Tutorial - Go&lt;/a&gt;。一样在官方文档里只字未提。&lt;/p&gt;
&lt;p&gt;这个tutorial对新了解opentracing的人，以及对需要学习opentracing client编码的人都很有帮助。范例举得相当不错。&lt;/p&gt;
&lt;h2 id=&quot;84-client-coding&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#84-client-coding&quot; aria-label=&quot;84 client coding permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.4 Client Coding&lt;/h2&gt;
&lt;p&gt;Jaeger集群架设完毕还不算结束，后面还需要编写客户端的集成代码。Opentracing的整体流程，以及trace、span等概念，首先需要阅读官方文档，以及7.3中提到的tutorial。&lt;/p&gt;
&lt;p&gt;这里要提一点，jaeger免不了会遇到rpc调用之间的上下文跨实体的情况，遇到这种情况，需要上游将trace相关信息&lt;code class=&quot;language-text&quot;&gt;inject&lt;/code&gt;到请求中，然后在下游将trace信息&lt;code class=&quot;language-text&quot;&gt;extract&lt;/code&gt;出来，根据extract的信息继续走之前的trace，这样才能保证跨实体的请求是在同一个trace中。相关细节可以查看7.3的tutorial中的第三节课。&lt;/p&gt;
&lt;p&gt;客户端代码怎么写，看下下面的文档基本上就了解了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Opentracing官方文档：&lt;a href=&quot;https://opentracing.io/guides/golang/quick-start/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Quick Start&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;gRPC Interceptor插件，官方：&lt;a href=&quot;https://github.com/grpc-ecosystem/go-grpc-middleware/tree/master/tracing/opentracing&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go-grpc-middleware/tracing/opentracing/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;gRPC非官方插件：&lt;a href=&quot;https://github.com/grpc-ecosystem/grpc-opentracing/tree/master/go/otgrpc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-opentracing/go/otgrpc/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于一般的客户端使用看下官方文档就没什么问题了，gRPC稍微有点不同，官方提供了interceptor插件。至于这些插件怎么使用，可以查看范例：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/client/main.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;client/main.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/server/main.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;server/main.go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;9-todo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#9-todo&quot; aria-label=&quot;9 todo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;9. TODO&lt;/h1&gt;
&lt;p&gt;囿于当前使用的深度及项目调研的时间限制，有部分内容做的还不够深入，后续可以考虑补全：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Jaeger自身的几项Metrics深入研究：Agent、Collector、Query&lt;/li&gt;
&lt;li&gt;Jaeger的Benchmark&lt;/li&gt;
&lt;li&gt;特别需要关注Jaeger在高负载情况下的数据丢失情况&lt;/li&gt;
&lt;li&gt;后端Data Store的选择问题&lt;/li&gt;
&lt;li&gt;和gin混用的情况下，gRPC客户端的interceptor不会生效（服务端正常），很奇怪，需要后续debug&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://yq.aliyun.com/articles/514488&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;开放分布式追踪（OpenTracing）入门与 Jaeger 实现&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/a963ad0bbe3e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OpenTracing语义标准规范及实现&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/jaegertracing/the-life-of-a-span-ee508410200b&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The life of a span&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/1255&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What happens when the jaeger-agent is down on a machine? #1255&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/1430&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Jaeger Agent does not buffer spans when the Collector is unavailable #1430&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/365&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Adaptive Sampling #365&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/832&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How sampler.type=remote works #832&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/issues/649&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Integration with external logs storage when displaying traces #649&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cassandra.apache.org/doc/latest/cql/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The Cassandra Query Language (CQL)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datastax.com/en/archived/cql/3.3/cql/cql_reference/cqlsh.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Starting cqlsh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.datastax.com/en/archived/cassandra/3.0/cassandra/configuration/secureFireWall.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configuring firewall port access&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hub.docker.com/r/jaegertracing/jaeger-cassandra-schema&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jaegertracing/jaeger-cassandra-schema&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/jaegertracing/jaeger-and-multitenancy-99dfa1d49dc0&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Jaeger and multitenancy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/yurishkuro/opentracing-tutorial/tree/master/go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OpenTracing Tutorial - Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grpc-ecosystem/grpc-opentracing/tree/master/go/otgrpc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;grpc-opentracing/go/otgrpc/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#help&quot; aria-label=&quot;help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Help&lt;/h2&gt;
&lt;h3 id=&quot;jaeger-agent---help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-agent---help&quot; aria-label=&quot;jaeger agent   help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;jaeger-agent —help&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run --rm jaegertracing/jaeger-agent:1.11.0 --help

Jaeger agent is a daemon program that runs on every host and receives tracing data submitted by Jaeger client libraries.

Usage:
  jaeger-agent [flags]
  jaeger-agent [command]

Available Commands:
  help        Help about any command
  version     Print the version

Flags:
      --collector.host-port string                                Deprecated; comma-separated string representing host:ports of a static list of collectors to connect to directly (e.g. when not using service discovery)
      --config-file string                                        Configuration file in JSON, TOML, YAML, HCL, or Java properties formats (default none). See spf13/viper for precedence.
      --discovery.conn-check-timeout duration                     Deprecated; sets the timeout used when establishing new connections (default 250ms)
      --discovery.min-peers int                                   Deprecated; if using service discovery, the min number of connections to maintain to the backend (default 3)
  -h, --help                                                      help for jaeger-agent
      --http-server.host-port string                              host:port of the http server (e.g. for /sampling point and /baggageRestrictions endpoint) (default &quot;:5778&quot;)
      --log-level string                                          Minimal allowed log Level. For more levels see https://github.com/uber-go/zap (default &quot;info&quot;)
      --metrics-backend string                                    Defines which metrics backend to use for metrics reporting: expvar, prometheus, none (default &quot;prometheus&quot;)
      --metrics-http-route string                                 Defines the route of HTTP endpoint for metrics backends that support scraping (default &quot;/metrics&quot;)
      --processor.jaeger-binary.server-host-port string           host:port for the UDP server (default &quot;:6832&quot;)
      --processor.jaeger-binary.server-max-packet-size int        max packet size for the UDP server (default 65000)
      --processor.jaeger-binary.server-queue-size int             length of the queue for the UDP server (default 1000)
      --processor.jaeger-binary.workers int                       how many workers the processor should run (default 10)
      --processor.jaeger-compact.server-host-port string          host:port for the UDP server (default &quot;:6831&quot;)
      --processor.jaeger-compact.server-max-packet-size int       max packet size for the UDP server (default 65000)
      --processor.jaeger-compact.server-queue-size int            length of the queue for the UDP server (default 1000)
      --processor.jaeger-compact.workers int                      how many workers the processor should run (default 10)
      --processor.zipkin-compact.server-host-port string          host:port for the UDP server (default &quot;:5775&quot;)
      --processor.zipkin-compact.server-max-packet-size int       max packet size for the UDP server (default 65000)
      --processor.zipkin-compact.server-queue-size int            length of the queue for the UDP server (default 1000)
      --processor.zipkin-compact.workers int                      how many workers the processor should run (default 10)
      --reporter.grpc.host-port string                            Comma-separated string representing host:port of a static list of collectors to connect to directly.
      --reporter.grpc.retry.max uint                              Sets the maximum number of retries for a call. (default 3)
      --reporter.grpc.tls                                         Enable TLS.
      --reporter.grpc.tls.ca string                               Path to a TLS CA file. (default use the systems truststore)
      --reporter.grpc.tls.server-name string                      Override the TLS server name.
      --reporter.tchannel.discovery.conn-check-timeout duration   sets the timeout used when establishing new connections (default 250ms)
      --reporter.tchannel.discovery.min-peers int                 if using service discovery, the min number of connections to maintain to the backend (default 3)
      --reporter.tchannel.host-port string                        comma-separated string representing host:ports of a static list of collectors to connect to directly (e.g. when not using service discovery)
      --reporter.tchannel.report-timeout duration                 sets the timeout used when reporting spans (default 1s)
      --reporter.type string                                      Reporter type to use e.g. grpc, tchannel (default &quot;grpc&quot;)

Use &quot;jaeger-agent [command] --help&quot; for more information about a command.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;jaeger-collector-memory---help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-collector-memory---help&quot; aria-label=&quot;jaeger collector memory   help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;jaeger-collector memory —help&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run --rm -e SPAN_STORAGE_TYPE=memory jaegertracing/jaeger-collector:1.11.0 --help

Jaeger collector receives traces from Jaeger agents and runs them through a processing pipeline.

Usage:
  jaeger-collector [flags]
  jaeger-collector [command]

Available Commands:
  env         Help about environment variables
  help        Help about any command
  version     Print the version

Flags:
      --collector.grpc-port int           The gRPC port for the collector service (default 14250)
      --collector.grpc.tls                Enable TLS
      --collector.grpc.tls.cert string    Path to TLS certificate file
      --collector.grpc.tls.key string     Path to TLS key file
      --collector.http-port int           The HTTP port for the collector service (default 14268)
      --collector.num-workers int         The number of workers pulling items from the queue (default 50)
      --collector.port int                The TChannel port for the collector service (default 14267)
      --collector.queue-size int          The queue size of the collector (default 2000)
      --collector.zipkin.http-port int    The HTTP port for the Zipkin collector service e.g. 9411
      --config-file string                Configuration file in JSON, TOML, YAML, HCL, or Java properties formats (default none). See spf13/viper for precedence.
      --health-check-http-port int        The http port for the health check service (default 14269)
  -h, --help                              help for jaeger-collector
      --log-level string                  Minimal allowed log Level. For more levels see https://github.com/uber-go/zap (default &quot;info&quot;)
      --memory.max-traces int             The maximum amount of traces to store in memory
      --metrics-backend string            Defines which metrics backend to use for metrics reporting: expvar, prometheus, none (default &quot;prometheus&quot;)
      --metrics-http-route string         Defines the route of HTTP endpoint for metrics backends that support scraping (default &quot;/metrics&quot;)
      --sampling.strategies-file string   The path for the sampling strategies file in JSON format. See sampling documentation to see format of the file
      --span-storage.type string          Deprecated; please use SPAN_STORAGE_TYPE environment variable. Run this binary with &quot;env&quot; command for help.

Use &quot;jaeger-collector [command] --help&quot; for more information about a command.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;jaeger-query---help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-query---help&quot; aria-label=&quot;jaeger query   help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;jaeger-query —help&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ docker run --rm jaegertracing/jaeger-query:1.11.0 --help

Jaeger query service provides a Web UI and an API for accessing trace data.

Usage:
  jaeger-query [flags]
  jaeger-query [command]

Available Commands:
  env         Help about environment variables
  help        Help about any command
  version     Print the version

Flags:
      --cassandra...
      --config-file string                              Configuration file in JSON, TOML, YAML, HCL, or Java properties formats (default none). See spf13/viper for precedence.
      --health-check-http-port int                      The http port for the health check service (default 16687)
  -h, --help                                            help for jaeger-query
      --log-level string                                Minimal allowed log Level. For more levels see https://github.com/uber-go/zap (default &quot;info&quot;)
      --metrics-backend string                          Defines which metrics backend to use for metrics reporting: expvar, prometheus, none (default &quot;prometheus&quot;)
      --metrics-http-route string                       Defines the route of HTTP endpoint for metrics backends that support scraping (default &quot;/metrics&quot;)
      --query.base-path string                          The base path for all HTTP routes, e.g. /jaeger; useful when running behind a reverse proxy (default &quot;/&quot;)
      --query.port int                                  The port for the query service (default 16686)
      --query.static-files string                       The directory path override for the static assets for the UI
      --query.ui-config string                          The path to the UI configuration file in JSON format
      --span-storage.type string                        Deprecated; please use SPAN_STORAGE_TYPE environment variable. Run this binary with &quot;env&quot; command for help.

Use &quot;jaeger-query [command] --help&quot; for more information about a command.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#metrics&quot; aria-label=&quot;metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Metrics&lt;/h2&gt;
&lt;h3 id=&quot;jaeger-agent-metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-agent-metrics&quot; aria-label=&quot;jaeger agent metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;jaeger-agent metrics&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# HELP go_gc_duration_seconds A summary of the GC invocation durations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE go_gc_duration_seconds summary&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_collector_proxy_total collector-proxy&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_collector_proxy_total counter&lt;/span&gt;
jaeger_agent_collector_proxy_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;baggage&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_collector_proxy_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;baggage&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_collector_proxy_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sampling&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_collector_proxy_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sampling&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_http_server_errors_total http-server.errors&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_http_server_errors_total counter&lt;/span&gt;
jaeger_agent_http_server_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;all&quot;&lt;/span&gt;,status&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_http_server_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;collector-proxy&quot;&lt;/span&gt;,status&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_http_server_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;thrift&quot;&lt;/span&gt;,status&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_http_server_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;source&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;write&quot;&lt;/span&gt;,status&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_http_server_requests_total http-server.requests&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_http_server_requests_total counter&lt;/span&gt;
jaeger_agent_http_server_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;baggage&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_http_server_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sampling&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_http_server_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;type&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;sampling-legacy&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_reporter_batch_size batch_size&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_reporter_batch_size gauge&lt;/span&gt;
jaeger_agent_reporter_batch_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_reporter_batch_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_reporter_batches_failures_total batches.failures&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_reporter_batches_failures_total counter&lt;/span&gt;
jaeger_agent_reporter_batches_failures_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_reporter_batches_failures_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_reporter_batches_submitted_total batches.submitted&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_reporter_batches_submitted_total counter&lt;/span&gt;
jaeger_agent_reporter_batches_submitted_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_reporter_batches_submitted_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_reporter_spans_failures_total spans.failures&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_reporter_spans_failures_total counter&lt;/span&gt;
jaeger_agent_reporter_spans_failures_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_reporter_spans_failures_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_reporter_spans_submitted_total spans.submitted&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_reporter_spans_submitted_total counter&lt;/span&gt;
jaeger_agent_reporter_spans_submitted_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_reporter_spans_submitted_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;grpc&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_thrift_udp_server_packet_size thrift.udp.server.packet_size&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_thrift_udp_server_packet_size gauge&lt;/span&gt;
jaeger_agent_thrift_udp_server_packet_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_packet_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_packet_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_thrift_udp_server_packets_dropped_total thrift.udp.server.packets.dropped&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_thrift_udp_server_packets_dropped_total counter&lt;/span&gt;
jaeger_agent_thrift_udp_server_packets_dropped_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_packets_dropped_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_packets_dropped_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_thrift_udp_server_packets_processed_total thrift.udp.server.packets.processed&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_thrift_udp_server_packets_processed_total counter&lt;/span&gt;
jaeger_agent_thrift_udp_server_packets_processed_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_packets_processed_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_packets_processed_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_thrift_udp_server_queue_size thrift.udp.server.queue_size&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_thrift_udp_server_queue_size gauge&lt;/span&gt;
jaeger_agent_thrift_udp_server_queue_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_queue_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_queue_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_thrift_udp_server_read_errors_total thrift.udp.server.read.errors&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_thrift_udp_server_read_errors_total counter&lt;/span&gt;
jaeger_agent_thrift_udp_server_read_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_read_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_server_read_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_thrift_udp_t_processor_close_time thrift.udp.t-processor.close-time&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_thrift_udp_t_processor_close_time histogram&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_close_time_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_agent_thrift_udp_t_processor_handler_errors_total thrift.udp.t-processor.handler-errors&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_agent_thrift_udp_t_processor_handler_errors_total counter&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_handler_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;binary&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_handler_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_agent_thrift_udp_t_processor_handler_errors_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,protocol&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;compact&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_cpu_seconds_total counter&lt;/span&gt;
process_cpu_seconds_total &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_max_fds Maximum number of open file descriptors.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_max_fds gauge&lt;/span&gt;
process_max_fds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.048576e+06
&lt;span class=&quot;token comment&quot;&gt;# HELP process_open_fds Number of open file descriptors.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_open_fds gauge&lt;/span&gt;
process_open_fds &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_resident_memory_bytes Resident memory size in bytes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_resident_memory_bytes gauge&lt;/span&gt;
process_resident_memory_bytes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.3283328e+07
&lt;span class=&quot;token comment&quot;&gt;# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_start_time_seconds gauge&lt;/span&gt;
process_start_time_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.55540751234e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP process_virtual_memory_bytes Virtual memory size in bytes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_virtual_memory_bytes gauge&lt;/span&gt;
process_virtual_memory_bytes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.22187776e+08&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;jaeger-collector-metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-collector-metrics&quot; aria-label=&quot;jaeger collector metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;jaeger-collector metrics&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# HELP go_gc_duration_seconds A summary of the GC invocation durations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE go_gc_duration_seconds summary&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_batch_size batch-size&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_batch_size gauge&lt;/span&gt;
jaeger_collector_batch_size&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_in_queue_latency in-queue-latency&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_in_queue_latency histogram&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_in_queue_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_queue_length queue-length&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_queue_length gauge&lt;/span&gt;
jaeger_collector_queue_length&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_save_latency save-latency&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_save_latency histogram&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_save_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_spans_dropped_total spans.dropped&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_spans_dropped_total counter&lt;/span&gt;
jaeger_collector_spans_dropped_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_spans_received_total received&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_spans_received_total counter&lt;/span&gt;
jaeger_collector_spans_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_spans_rejected_total rejected&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_spans_rejected_total counter&lt;/span&gt;
jaeger_collector_spans_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_spans_saved_by_svc_total saved-by-svc&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_spans_saved_by_svc_total counter&lt;/span&gt;
jaeger_collector_spans_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_spans_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_spans_serviceNames spans.serviceNames&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_spans_serviceNames gauge&lt;/span&gt;
jaeger_collector_spans_serviceNames&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;host&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1bd33f303256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_traces_received_total received&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_traces_received_total counter&lt;/span&gt;
jaeger_collector_traces_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_received_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_traces_rejected_total rejected&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_traces_rejected_total counter&lt;/span&gt;
jaeger_collector_traces_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;jaeger&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_rejected_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,format&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;zipkin&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_collector_traces_saved_by_svc_total saved-by-svc&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_collector_traces_saved_by_svc_total counter&lt;/span&gt;
jaeger_collector_traces_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;false&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_collector_traces_saved_by_svc_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;debug&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;true&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,svc&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;other-services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_cpu_seconds_total counter&lt;/span&gt;
process_cpu_seconds_total &lt;span class=&quot;token number&quot;&gt;0.71&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_max_fds Maximum number of open file descriptors.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_max_fds gauge&lt;/span&gt;
process_max_fds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.048576e+06
&lt;span class=&quot;token comment&quot;&gt;# HELP process_open_fds Number of open file descriptors.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_open_fds gauge&lt;/span&gt;
process_open_fds &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_resident_memory_bytes Resident memory size in bytes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_resident_memory_bytes gauge&lt;/span&gt;
process_resident_memory_bytes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.9329024e+07
&lt;span class=&quot;token comment&quot;&gt;# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_start_time_seconds gauge&lt;/span&gt;
process_start_time_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.55540675992e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP process_virtual_memory_bytes Virtual memory size in bytes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_virtual_memory_bytes gauge&lt;/span&gt;
process_virtual_memory_bytes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.3008896e+08&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;jaeger-query-metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#jaeger-query-metrics&quot; aria-label=&quot;jaeger query metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;jaeger-query metrics&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# HELP go_gc_duration_seconds A summary of the GC invocation durations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE go_gc_duration_seconds summary&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_query_latency latency&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_query_latency histogram&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_latency_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_query_requests_total requests&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_query_requests_total counter&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_query_responses responses&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_query_responses histogram&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_trace_ids&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;find_traces&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_operations&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_services&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_query_responses_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;operation&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;get_trace&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_baggage_restrictions_updates_total Number of times baggage restrictions were successfully updated&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_baggage_restrictions_updates_total counter&lt;/span&gt;
jaeger_tracer_baggage_restrictions_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_baggage_restrictions_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_baggage_truncations_total Number of times baggage was truncated as per baggage restrictions&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_baggage_truncations_total counter&lt;/span&gt;
jaeger_tracer_baggage_truncations_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_baggage_updates_total Number of times baggage was successfully written or updated on spans&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_baggage_updates_total counter&lt;/span&gt;
jaeger_tracer_baggage_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_baggage_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_finished_spans_total Number of spans finished by this tracer&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_finished_spans_total counter&lt;/span&gt;
jaeger_tracer_finished_spans_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_reporter_queue_length Current number of spans in the reporter queue&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_reporter_queue_length gauge&lt;/span&gt;
jaeger_tracer_reporter_queue_length &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_reporter_spans_total Number of spans successfully reported&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_reporter_spans_total counter&lt;/span&gt;
jaeger_tracer_reporter_spans_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;dropped&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_reporter_spans_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_reporter_spans_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_sampler_queries_total Number of times the Sampler succeeded to retrieve sampling strategy&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_sampler_queries_total counter&lt;/span&gt;
jaeger_tracer_sampler_queries_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_sampler_queries_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_sampler_updates_total Number of times the Sampler succeeded to retrieve and update sampling strategy&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_sampler_updates_total counter&lt;/span&gt;
jaeger_tracer_sampler_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_sampler_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_span_context_decoding_errors_total Number of errors decoding tracing context&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_span_context_decoding_errors_total counter&lt;/span&gt;
jaeger_tracer_span_context_decoding_errors_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_started_spans_total Number of sampled spans started by this tracer&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_started_spans_total counter&lt;/span&gt;
jaeger_tracer_started_spans_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sampled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_started_spans_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sampled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_throttled_debug_spans_total Number of times debug spans were throttled&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_throttled_debug_spans_total counter&lt;/span&gt;
jaeger_tracer_throttled_debug_spans_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_throttler_updates_total Number of times throttler successfully updated&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_throttler_updates_total counter&lt;/span&gt;
jaeger_tracer_throttler_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;err&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_throttler_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;result&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ok&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP jaeger_tracer_traces_total Number of traces started by this tracer as sampled&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE jaeger_tracer_traces_total counter&lt;/span&gt;
jaeger_tracer_traces_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sampled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;n&quot;&lt;/span&gt;,state&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;joined&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_traces_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sampled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;n&quot;&lt;/span&gt;,state&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;started&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_traces_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sampled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;,state&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;joined&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
jaeger_tracer_traces_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;sampled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;y&quot;&lt;/span&gt;,state&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;started&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_cpu_seconds_total Total user and system CPU time spent in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_cpu_seconds_total counter&lt;/span&gt;
process_cpu_seconds_total &lt;span class=&quot;token number&quot;&gt;0.09&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_max_fds Maximum number of open file descriptors.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_max_fds gauge&lt;/span&gt;
process_max_fds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.048576e+06
&lt;span class=&quot;token comment&quot;&gt;# HELP process_open_fds Number of open file descriptors.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_open_fds gauge&lt;/span&gt;
process_open_fds &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP process_resident_memory_bytes Resident memory size in bytes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_resident_memory_bytes gauge&lt;/span&gt;
process_resident_memory_bytes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.4475264e+07
&lt;span class=&quot;token comment&quot;&gt;# HELP process_start_time_seconds Start time of the process since unix epoch in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_start_time_seconds gauge&lt;/span&gt;
process_start_time_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.55540951442e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP process_virtual_memory_bytes Virtual memory size in bytes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE process_virtual_memory_bytes gauge&lt;/span&gt;
process_virtual_memory_bytes &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.31395584e+08&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Compare: Monitoring | Tracing | Logging]]></title><link>https://xenojoshua.com/posts/2019/04/monitoring-tracing-logging</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/monitoring-tracing-logging</guid><pubDate>Fri, 12 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-monitoring--tracing--logging&quot;&gt;1. Monitoring &amp;#x26; Tracing &amp;#x26; Logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-monitoring&quot;&gt;2. Monitoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-tracing&quot;&gt;3. Tracing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-logging&quot;&gt;4. Logging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E6%80%BB%E7%BB%93&quot;&gt;5. 总结&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-monitoring--tracing--logging&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-monitoring--tracing--logging&quot; aria-label=&quot;1 monitoring  tracing  logging permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. Monitoring &amp;#x26; Tracing &amp;#x26; Logging&lt;/h1&gt;
&lt;p&gt;对于一个系统来说，标题中提到的这三者需求都是必然存在的，而有的时候我们会搞不清楚这三者相互之间是什么关系。我之前在做系统设计的时候也考虑过，是不是有必要引入那么多组件，毕竟如果这三者完全分开每一个一项的话，就有三个组件了（事实上就是：Prometheus+Grafana、Jaeger、ELK）。&lt;/p&gt;
&lt;p&gt;因此想做个笔记尝试举例来梳理下。&lt;/p&gt;
&lt;p&gt;外部链接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Metrics, tracing, and logging&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;2-monitoring&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-monitoring&quot; aria-label=&quot;2 monitoring permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. Monitoring&lt;/h1&gt;
&lt;p&gt;Monitoring（监控）举例来说就是：&lt;code class=&quot;language-text&quot;&gt;定期体检&lt;/code&gt;。使用监控系统把需要关注的指标采集起来，形成报告，并对需要关注的异常数据进行分析形成告警。&lt;/p&gt;
&lt;p&gt;特点是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;低频&lt;/li&gt;
&lt;li&gt;定期&lt;/li&gt;
&lt;li&gt;定量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这也是Prometheus的架构做得非常简单的原因，Monitoring的需求并没有包含非常高的并发量和通讯量。反过来说：高并发、大数据量的需求并不适用于Monitoring这个点。&lt;/p&gt;
&lt;h1 id=&quot;3-tracing&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-tracing&quot; aria-label=&quot;3 tracing permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Tracing&lt;/h1&gt;
&lt;p&gt;Tracing（链路追踪）举例来说就是：&lt;code class=&quot;language-text&quot;&gt;对某一项工作的定期汇报&lt;/code&gt;。某个工作开始做了A，制作A事件的报告，收集起来，然后这个工作还有B、C、D等条目，一个个处理，然后都汇总进报告，最终的结果就是一个Tracing。&lt;/p&gt;
&lt;p&gt;特点是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高频&lt;/li&gt;
&lt;li&gt;巨量&lt;/li&gt;
&lt;li&gt;有固定格式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为Tracing是针对某一个事件（一般来说就是一个API），而这个API可能会和很多组件进行沟通，后续的所有的组件沟通无论是内部还是外部的IO，都算作这个API调用的Tracing的一部分。可以想见在一个业务繁忙的系统中，API调用的数量已经是天文数字，而其衍生出来的Tracing记录更是不得了的量。其特点就是高频、巨量，一个API会衍生出大量的子调用。&lt;/p&gt;
&lt;p&gt;也因此适合用来做Monitoring的系统就不一定适合做Tracing了，用Prometheus这样的系统来做Tracing肯定完蛋（Prometheus只有拉模式，全部都是HTTP请求，高并发直接挂掉）。一般来说Tracing系统都会在本地磁盘IO上做日志（最高效、也是最低的Cost），然后再通过本地Agent慢慢把文本日志数据发送到聚合服务器上，甚至可能在聚合服务器和本地的Agent之间还需要做消息队列，让聚合服务器慢慢消化巨量的消息。&lt;/p&gt;
&lt;p&gt;Tracing在现在的业界是有标准的：&lt;code class=&quot;language-text&quot;&gt;OpenTracing&lt;/code&gt;，因此它不是很随意的日志/事件聚合，而是有格式要求的日志/事件聚合，这就是Tracing和Logging最大的不同。&lt;/p&gt;
&lt;h1 id=&quot;4-logging&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-logging&quot; aria-label=&quot;4 logging permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Logging&lt;/h1&gt;
&lt;p&gt;Logging（日志）举例来说就是：&lt;code class=&quot;language-text&quot;&gt;废品回收站&lt;/code&gt;。各种各样的物品都会汇总进入到配品回收站里，然后经过分门别类归纳整理，成为各种可回收资源分别回收到商家那里。一般来说我们在大型系统中提到Logging说的都不是简单的&lt;code class=&quot;language-text&quot;&gt;日志&lt;/code&gt;，而是&lt;code class=&quot;language-text&quot;&gt;日志聚合系统&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;从本质上来说，Monitoring和Tracing都是Logging，Logging是这三者中覆盖面最大的超集，而前两者则是其一部分的子集。Logging最麻烦的是，开发者也不会完全知道最后记录进入到日志系统里的一共会有哪些东西，只有在使用（检索）的时候才可能需要汇总查询总量中的一部分。&lt;/p&gt;
&lt;p&gt;要在一般的Loggin系统中进行Monitoring也是可以的，直接把聚合进来的日志数据提取出来，定期形成数据报告，就是监控了。Tracing也是一样，只要聚合进了Logging系统，有了原始数据，后面要做都是可以做的。因此Logging系统最为通用，其特点和Tracing基本一致，也是需要处理高频并发和巨大的数据量。&lt;/p&gt;
&lt;h1 id=&quot;5-总结&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E6%80%BB%E7%BB%93&quot; aria-label=&quot;5 总结 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 总结&lt;/h1&gt;
&lt;p&gt;这样一看就很清楚了，每个组件都有其存在的必要性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Monitoring系统（Prometheus）从根本的需求和基本设计上就不可能支持Tracing和Logging：低频 vs 高频、低量 vs 高量，其从设计到实现就只为了监控服务&lt;/li&gt;
&lt;li&gt;Tracing系统（Jaeger）对提供的数据有格式要求，且处理方式和一般的Logging也不同，有更限定的应用范围&lt;/li&gt;
&lt;li&gt;Logging系统（ELK）可以处理前两者的需求，但前两者的领域有更专业的工具就不推荐直接使用普通的日志聚合系统了；Logging系统一般用来处理大型系统的日志聚合以及检索查询&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Grafana Notes]]></title><link>https://xenojoshua.com/posts/2019/04/grafana-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/grafana-note</guid><pubDate>Thu, 11 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85--%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE--%E5%90%AF%E5%8A%A8&quot;&gt;2. 安装 &amp;#x26; 文件位置 &amp;#x26; 启动&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E5%AE%89%E8%A3%85&quot;&gt;2.1 安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE&quot;&gt;2.2 文件位置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot;&gt;2.3 配置文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#24-%E5%90%AF%E5%8A%A8&quot;&gt;2.4 启动&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#25-cli&quot;&gt;2.5 CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#26-%E7%99%BB%E5%BD%95--%E8%AE%BF%E9%97%AE&quot;&gt;2.6 登录 &amp;#x26; 访问&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E6%A6%82%E5%BF%B5&quot;&gt;3. 概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8%E7%AE%80%E4%BB%8B&quot;&gt;4. 使用简介&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8&quot;&gt;4.1 日常使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E6%95%B0%E6%8D%AE%E4%BF%9D%E5%AD%98--%E5%AF%BC%E5%87%BA&quot;&gt;4.2 数据保存 &amp;#x26; 导出&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E6%95%B0%E6%8D%AE%E6%BA%90&quot;&gt;4.3 数据源&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87&quot;&gt;5. 监控指标&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-docker%E5%AE%9E%E8%B7%B5&quot;&gt;6. Docker实践&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#61-docker%E5%AE%89%E8%A3%85&quot;&gt;6.1 Docker安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#62-compose%E9%85%8D%E7%BD%AE&quot;&gt;6.2 Compose配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#63-provisioning&quot;&gt;6.3 Provisioning&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#64-dashboard&quot;&gt;6.4 Dashboard&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#641-variables&quot;&gt;6.4.1 Variables&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-todo&quot;&gt;7. TODO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E&quot;&gt;8. 写在最后&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#grafana--h-id_app_grafana_help&quot;&gt;grafana -h {#ID_APP_GRAFANA_HELP}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#grafanametrics-id_app_self_metrics&quot;&gt;grafana/metrics {#ID_APP_SELF_METRICS}&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Grafana常被用作数据展示界面，虽然实际上它还有很多其他相关的功能，但一般都不会使用。在CNCF的项目中，一般Grafana都和Prometheus结合使用。Grafana的最大优势在于其灵活性，它作为数据界面可以利用相当多种类的后台数据源。在我构想中的系统里，ELK也是相当重要的一个组成部分，而Grafana也可以作为ElasticSearch的前台界面，这就相当好用。&lt;/p&gt;
&lt;p&gt;由于其相当于仅只是一个UI，所以本文中架构之类的内容基本上会很少，主要是概念介绍和使用细节方面的。&lt;/p&gt;
&lt;p&gt;下文所有内容都基于版本：&lt;code class=&quot;language-text&quot;&gt;v6.1.2&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ ./bin/grafana-server -v
Version 6.1.2 (commit: de8f6ac, branch: HEAD)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2-安装--文件位置--启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85--%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE--%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;2 安装  文件位置  启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 安装 &amp;#x26; 文件位置 &amp;#x26; 启动&lt;/h1&gt;
&lt;h2 id=&quot;21-安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E5%AE%89%E8%A3%85&quot; aria-label=&quot;21 安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 安装&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://grafana.com/grafana/download&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Download Grafana&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;官方站点做得很好，直接按指示操作即可。MAC安装很方便，使用brew装是最佳选择，另外也可以wget下载tar包，解压即用。Go应用程序就这点，真的太赞了。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;brew update 
brew install grafana

or

wget https://dl.grafana.com/oss/release/grafana-6.1.2.darwin-amd64.tar.gz 
tar -zxvf grafana-6.1.2.darwin-amd64.tar.gz&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;22-文件位置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE&quot; aria-label=&quot;22 文件位置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 文件位置&lt;/h2&gt;
&lt;p&gt;解压出来的Grafana文件夹可以简单看一下，基本上运行的文件位置就是按这个安排的：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;bin                 # grafana-server &amp;amp; grafana-cli
conf                # 配置文件夹
data \              # 运行时产生的文件，刚解压出来时还不存在
     | log          # 日志输出
     | plugins      # 安装的第三方插件等
     | png
     | grafana.db   # sqlite3数据库
public              # 展示相关的内容，HTML、CSS等
scripts             # bash脚本，忽略
tools               # 忽略&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上面的&lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt;文件夹及里面的内容等，都是默认的配置文件的设定，如果没有特殊需求，一般直接这样运行就可以了。&lt;/p&gt;
&lt;p&gt;如果将Grafana的运行文件夹指定在某个位置的话，一些文件夹是可能需要调整（配置文件中）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;data/grafana&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Directory where grafana can store logs&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;logs&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;log&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Directory where grafana will automatically scan and look for plugins&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;plugins&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;data/grafana/plugins&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# folder that contains provisioning config files that grafana will apply on startup and while running.&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;provisioning&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;conf/provisioning&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# the path relative working path&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;static_root_path&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;data/grafana/public&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上面的所有文件夹实际上都是相对路径，相对于Grafana启动时候指定的工作路径：&lt;code class=&quot;language-text&quot;&gt;--homepath&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&quot;23-配置文件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot; aria-label=&quot;23 配置文件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 配置文件&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://grafana.com/docs/installation/configuration/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configuration&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;配置文件中的选项基本上和运行时和监控关系不大，都是一些设置向的内容，配置过一次之后就不需要变动了。一些可能需要关心的选项：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ini&quot;&gt;&lt;pre class=&quot;language-ini&quot;&gt;&lt;code class=&quot;language-ini&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Protocol (http, https, socket)&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;http&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# The ip address to bind to, empty will bind to all interfaces&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;http_addr&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;127.0.0.1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# The http port to use&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;http_port&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;3000&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# The public facing domain name used to access grafana from a browser&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;domain&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;localhost&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Either &quot;mysql&quot;, &quot;postgres&quot; or &quot;sqlite3&quot;, it&apos;s your choice&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;sqlite3&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Server reporting, sends usage counters to stats.grafana.org every 24 hours.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# No ip addresses are being tracked, only simple counters to track&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# running instances, dashboard and error counts. It is very helpful to us.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Change this option to false to disable reporting.&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;reporting_enabled&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Set to false to disable all checks to https://grafana.com&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# for new versions (grafana itself and plugins), check is used&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# in some UI views to notify that grafana or plugin update exists&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# This option does not cause any auto updates, nor send any information&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# only a GET request to https://grafana.com to get latest versions&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;check_for_updates&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# disable user signup / registration&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;allow_sign_up&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Allow non admin users to create organizations&lt;/span&gt;
&lt;span class=&quot;token key attr-name&quot;&gt;allow_org_create&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token value attr-value&quot;&gt;false&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;24-启动&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#24-%E5%90%AF%E5%8A%A8&quot; aria-label=&quot;24 启动 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4 启动&lt;/h2&gt;
&lt;p&gt;启动这块就有个让人很头疼的事情，真的让我始料未及。&lt;/p&gt;
&lt;p&gt;让Grafana作为一个WEB应用启动，需要用到的是&lt;code class=&quot;language-text&quot;&gt;bin/grafana-server&lt;/code&gt;这个命令，其帮助可以在&lt;a href=&quot;#ID_APP_GRAFANA_HELP&quot;&gt;资料&lt;/a&gt;查看。&lt;/p&gt;
&lt;p&gt;有用的参数只有两个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--config&lt;/code&gt;：指定配置文件位置&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;--homepath&lt;/code&gt;：指定Grafana工作的根目录&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果是将下载下来的Grafana直接解包运行，不更改路径的话，那就不需要任何启动参数，直接运行即可。但如果需要更改运行根目录的话，就需要使用&lt;code class=&quot;language-text&quot;&gt;--homepath&lt;/code&gt;这个选项：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ ./bin/grafana-server --homepath &quot;/Users/XXX/.../&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;而我遇到的问题是&lt;code class=&quot;language-text&quot;&gt;--config&lt;/code&gt;这个选项，无论我指定任何内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;相对于&lt;code class=&quot;language-text&quot;&gt;--homepath&lt;/code&gt;的相对文件位置：&lt;code class=&quot;language-text&quot;&gt;config/grafana/grafana.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;相对于&lt;code class=&quot;language-text&quot;&gt;--homepath&lt;/code&gt;的相对文件夹：&lt;code class=&quot;language-text&quot;&gt;config/grafana/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;绝对文件路径：&lt;code class=&quot;language-text&quot;&gt;/Users/XXX/.../config/grafana/grafana.ini&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;绝对文件夹：&lt;code class=&quot;language-text&quot;&gt;/Users/XXX/.../config/grafana/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它都不能正常工作，只会返回给我错误：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Grafana-server Init Failed: Could not find config defaults, make sure homepath command line parameter is set or working directory is homepath&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;真的让人相当恼火，官方文档里还有这块的解说，但说了根本就和没说一个样：&lt;a href=&quot;https://grafana.com/docs/installation/configuration/#config-file-locations&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Config file locations&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;最后只能使用：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Default configuration from $WORKING_DIR/conf/defaults.ini&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;也就是在默认的配置文件位置上放上文件：&lt;code class=&quot;language-text&quot;&gt;${--homepath}/conf/defaults.ini&lt;/code&gt;，才正常工作起来，哎。&lt;/p&gt;
&lt;h2 id=&quot;25-cli&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#25-cli&quot; aria-label=&quot;25 cli permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.5 CLI&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://grafana.com/docs/administration/cli/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grafana CLI&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Grafana还提供了一个命令行工具来辅助admin平时的操作：&lt;code class=&quot;language-text&quot;&gt;bin/grafana-cli&lt;/code&gt;，使用可以看：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ ./bin/grafana-cli -h&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;26-登录--访问&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#26-%E7%99%BB%E5%BD%95--%E8%AE%BF%E9%97%AE&quot; aria-label=&quot;26 登录  访问 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.6 登录 &amp;#x26; 访问&lt;/h2&gt;
&lt;p&gt;默认第一次使用的用户名和密码是：&lt;code class=&quot;language-text&quot;&gt;admin:admin&lt;/code&gt;，第一次登录进去之后系统就会要求更改admin密码。访问地址在配置文件里是可以更改的，默认为：&lt;code class=&quot;language-text&quot;&gt;http://localhost:3000&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;3-概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;3 概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 概念&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;DataSource&lt;/code&gt;：数据源，Grafana仅只是一个UI，真正保存数据的是数据源，根据版本不同支持的数据源可能不尽相同，有需要可以查看官方文档：&lt;a href=&quot;https://grafana.com/docs/features/datasources/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Data Source Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;用户 &amp;#x26; 权限：
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Organization&lt;/code&gt;：组织，用在多个组织部门使用同一个Grafana的情况，可以根据组织的不同区分可访问的面板&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;User&lt;/code&gt;：用户&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Role&lt;/code&gt;：角色，目前暂时只支持固定的角色：Admin、Editor、Read Only Editor、Viewer，相关：&lt;a href=&quot;https://github.com/grafana/grafana/issues/9877&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to create new user roles? #9877&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Panel&lt;/code&gt;：面板，Grafana的核心，实际上负责进行图形展示的单元，类型非常多，有需要可以查看官方文档：&lt;a href=&quot;https://grafana.com/docs/features/panels/graph/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Graph Panel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Row&lt;/code&gt;：行，Dashboard的下级逻辑分隔概念，一个Row里可以放入很多Panel，而且这里需要理解Row并不是物理上的&lt;code class=&quot;language-text&quot;&gt;行&lt;/code&gt;（实际上一个Row可以容纳很多行Panel）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Dashboard&lt;/code&gt;：仪表盘，由大量Panel组成的集合，一般来说Dashboard是按某个目标进行设计的，比如说：机房的当前状况，某个应用的服务状况等&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Plugins&lt;/code&gt;：插件，提供更多的额外功能集成，官方商店在：&lt;a href=&quot;https://grafana.com/plugins&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Plugins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Playlist&lt;/code&gt;：举例来说就是某些大公司在门口做的数据滚动播放展示，类似那样的功能，官方文档：&lt;a href=&quot;https://grafana.com/docs/reference/playlist/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Playlist&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Provisioning&lt;/code&gt;：通过配置文件的方式对DataSource及Dashboard进行设置，这是Grafana在使用API进行相关设置之外的另一种方法，且其不要求Grafana首先启动，使用上更为便利&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Templating&lt;/code&gt;：模板，对某些共性的Panel或Dashboard进行抽象，以便后续进行复用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Provisioning官方文档：&lt;a href=&quot;https://grafana.com/docs/administration/provisioning/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Provisioning Grafana&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在以前的Grafana版本中，你只能使用API来配置数据源和仪表盘，但是，这需要在开始创建仪表板之前运行服务，并且还需要为HTTP API设置证书。在v5.0中，我们决定通过添加使用配置文件的新的活动Provisioning系统来改善这种体验，这将使GitOps更加自然，因为可以通过可以进行版本控制的文件来定义数据源和仪表盘，我们希望扩展此系统以便稍后添加对用户，组织和警报的支持。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1 id=&quot;4-使用简介&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8%E7%AE%80%E4%BB%8B&quot; aria-label=&quot;4 使用简介 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 使用简介&lt;/h1&gt;
&lt;h1 id=&quot;41-日常使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;41 日常使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 日常使用&lt;/h1&gt;
&lt;p&gt;理解了上面的概念之后，日常功能无非就是以下几项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;创建User&lt;/li&gt;
&lt;li&gt;创建organization&lt;/li&gt;
&lt;li&gt;管理User和Organization以及Roles&lt;/li&gt;
&lt;li&gt;创建Dashboard，需要根据实际应用场景进行规划&lt;/li&gt;
&lt;li&gt;创建Rows，如果有必要的话&lt;/li&gt;
&lt;li&gt;在Dashboard上创建Panel&lt;/li&gt;
&lt;li&gt;将Panel及Dashboard做成Templating复用，如果有必要的话&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;42-数据保存--导出&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-%E6%95%B0%E6%8D%AE%E4%BF%9D%E5%AD%98--%E5%AF%BC%E5%87%BA&quot; aria-label=&quot;42 数据保存  导出 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 数据保存 &amp;#x26; 导出&lt;/h1&gt;
&lt;p&gt;Dashboard在面板上面的工具栏里有&lt;code class=&quot;language-text&quot;&gt;Settings&lt;/code&gt;选项，进入之后有一项&lt;code class=&quot;language-text&quot;&gt;JSON Model&lt;/code&gt;，这就是当前Dashboard的所有内容了，都做成了JSON文本进行描述。如果你查看过Grafana的数据库的话，你也可以看到Dashboard表只有一列，是用来存储这个数据的，其他任何地方都没有和Dashboard的内容相关的字段。只要复制了这个字段，也就完成了当前Dashboard的备份，当然也可以将这个JSON字符串做成*.json文件进行备份。&lt;/p&gt;
&lt;p&gt;Panel也有类似的功能，在Panel的Title进行点击，会有下拉菜单，然后&lt;code class=&quot;language-text&quot;&gt;More &gt; Panel Json&lt;/code&gt;就是了。&lt;/p&gt;
&lt;h1 id=&quot;43-数据源&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E6%95%B0%E6%8D%AE%E6%BA%90&quot; aria-label=&quot;43 数据源 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 数据源&lt;/h1&gt;
&lt;p&gt;Grafana支持多种数据源，根据不同数据源有不同的一些细微的功能差别以及配置差别，可以查看官方文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/docs/features/datasources/prometheus/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Using Prometheus in Grafana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://grafana.com/docs/features/datasources/elasticsearch/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Using Elasticsearch in Grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里面最有可能会用得到的就是&lt;code class=&quot;language-text&quot;&gt;Templating&lt;/code&gt;相关内容，在制作数据模板的时候很有用。&lt;/p&gt;
&lt;p&gt;Grafana和ELK相整合的文章可以看这篇：&lt;a href=&quot;https://elkguide.elasticsearch.cn/elasticsearch/other/grafana.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ELKstack 中文指南 &gt; Grafana&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;5-监控指标&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87&quot; aria-label=&quot;5 监控指标 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 监控指标&lt;/h1&gt;
&lt;p&gt;Grafana做的好就好在其和其他监控系统的集成相当好，Grafana自身的相关监控指标也可以和Prometheus一样暴露出来，使用的格式也是Prometheus的格式，默认是在：&lt;code class=&quot;language-text&quot;&gt;http://localhost:3000/metrics&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;我在本文中也留了一份，有必要可以研究下里面的内容：&lt;a href=&quot;#ID_APP_SELF_METRICS&quot;&gt;grafana/metrics&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;6-docker实践&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-docker%E5%AE%9E%E8%B7%B5&quot; aria-label=&quot;6 docker实践 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. Docker实践&lt;/h1&gt;
&lt;p&gt;接下来的章节会从实践的角度来尝试在容器中安装和使用Grafana。数据源皆为Prometheus，此后不再备注。&lt;/p&gt;
&lt;h2 id=&quot;61-docker安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#61-docker%E5%AE%89%E8%A3%85&quot; aria-label=&quot;61 docker安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.1 Docker安装&lt;/h2&gt;
&lt;p&gt;在容器内安装官方有指导文档：&lt;a href=&quot;https://grafana.com/docs/installation/docker/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Installing using Docker&lt;/a&gt;。主要了解几个重点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置文件中的选项如何使用env参数来进行调整，如何进行配置名字映射：&lt;a href=&quot;https://grafana.com/docs/installation/docker/#configuration&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;容器内的一些路径，以及如何调整这些默认路径：&lt;a href=&quot;https://grafana.com/docs/installation/docker/#default-paths&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Default Paths&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;如何在启动时就自动安装插件（保证启动完成立即可用）：&lt;a href=&quot;https://grafana.com/docs/installation/docker/#installing-plugins-for-grafana&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Installing Plugins for Grafana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;映射volume，保证数据不会被清除：&lt;a href=&quot;https://grafana.com/docs/installation/docker/#grafana-container-with-persistent-storage-recommended&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grafana container with persistent storage &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;62-compose配置&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#62-compose%E9%85%8D%E7%BD%AE&quot; aria-label=&quot;62 compose配置 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.2 Compose配置&lt;/h2&gt;
&lt;p&gt;可运行的docker compose配置文件范例，参见：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/conf/dev/prometheus-cluster.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/conf/dev/prometheus-cluster.yaml&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;重点是&lt;code class=&quot;language-text&quot;&gt;environment&lt;/code&gt;部分。&lt;/p&gt;
&lt;h2 id=&quot;63-provisioning&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#63-provisioning&quot; aria-label=&quot;63 provisioning permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.3 Provisioning&lt;/h2&gt;
&lt;p&gt;既然已经要求Grafana在容器内使用，那么一般也就要做到启动即可用。Grafana在使用之前一般需要几步配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户、密码管理&lt;/li&gt;
&lt;li&gt;数据源配置&lt;/li&gt;
&lt;li&gt;Dashboard配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;用户和密码之类的设置，可用通过容器的env配置解决，而数据源和Dashboard就比较麻烦了。Grafana官方提供了一个解决方案，非常好用：&lt;a href=&quot;https://grafana.com/docs/administration/provisioning/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Provisioning Grafana&lt;/a&gt;。简单来说就是提供两个配置文件，一个用来告诉Grafana启动时需要输入的数据源有哪些，另一个告诉Grafana启动时候需要导入的Dashboard有哪些。&lt;/p&gt;
&lt;p&gt;存储provisioning配置文件的指定路径在之前6.1中提到的默认路径中有，一般使用bind mount的方式将本地的provisioning配置文件导入到容器中。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;GF_PATHS_PROVISIONING=/etc/grafana/provisioning&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;数据源配置文件范例，参见：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/vendors/prometheus/grafana/provisioning/datasources/datasource.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/vendors/prometheus/grafana/provisioning/datasources/datasource.yaml&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Dashboard配置文件范例，参见：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/vendors/prometheus/grafana/provisioning/dashboards/providers.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/vendors/prometheus/grafana/provisioning/dashboards/providers.yaml&lt;/a&gt;。实际上就是指定一个文件夹，一般也是用bind mount的方式mapping到容器内即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;64-dashboard&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#64-dashboard&quot; aria-label=&quot;64 dashboard permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4 Dashboard&lt;/h2&gt;
&lt;p&gt;Grafana的灵活和强大在Dashboard上体现无疑，关键好用在于不仅仅界面美观、功能强大，而且还可以模板化，可导入导出，做到一次编写后续自动安装、更新。官方还有一个&lt;a href=&quot;https://grafana.com/dashboards&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grafana Labs &gt; Dashboards&lt;/a&gt;，类似于插件中心的地方，方便社区将做好的Dashboard进行分享。&lt;/p&gt;
&lt;p&gt;一般常用的组件，只要简单搜索下就可以找到可用的Dashboard，大大降低了监控的难度，加速了研发的进程。&lt;/p&gt;
&lt;h3 id=&quot;641-variables&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#641-variables&quot; aria-label=&quot;641 variables permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6.4.1 Variables&lt;/h3&gt;
&lt;p&gt;这里简单说下在进行Dashboard模板化的时候常见的variables设置问题。一般来说，在一个系统中，同角色的设备不会只有单个节点，大多数情况都会有多个节点，比如说web服务器、数据库服务器等。在进行监控的时候，只需要制作一份Grafana Dashboard，将里面的参数变量化，就可以将这个Dashboard模板化，方便后续使用。&lt;/p&gt;
&lt;p&gt;而模板化最关键就是要将节点做成可配置的变量，这里就需要进行Dashboard的variables设置。进入到Dashboard的Setting中，左边列表里就有variables设置的入口，设置方法可以参见下图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/grafana-note/grafana-dashboard-variables.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1 id=&quot;7-todo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-todo&quot; aria-label=&quot;7 todo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. TODO&lt;/h1&gt;
&lt;p&gt;囿于当前使用的深度及项目调研的时间限制，有部分内容做的还不够深入，后续可以考虑补全：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Grafana本身的性能，应该如何衡量&lt;/li&gt;
&lt;li&gt;Grafana暴露出来的&lt;a href=&quot;#ID_APP_SELF_METRICS&quot;&gt;Metrics&lt;/a&gt;需要仔细研究下&lt;/li&gt;
&lt;li&gt;所有的图表全部尝试一遍&lt;/li&gt;
&lt;li&gt;热力图的应用范围及实际使用范例&lt;/li&gt;
&lt;li&gt;常用 &amp;#x26; 有用的插件列表整理&lt;/li&gt;
&lt;li&gt;ELK整合使用必要性调研，Kibana是否够用，是否有必要使用Grafana作为ELK的前台UI&lt;/li&gt;
&lt;li&gt;ELK结合使用范例&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;8-写在最后&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E&quot; aria-label=&quot;8 写在最后 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. 写在最后&lt;/h1&gt;
&lt;p&gt;了解Metrics的含义才是最关键的，就像我在写Prometheus Notes说的，很多exporter会吐出巨量的Metrics数据，你都了解这些Metrics代表的意义吗？如果不了解的话，那些数据即便采集进去了，你又会去用了？说到底Prometheus和Grafana不过就是个工具，关键还是在于工程师想要了解什么，对自己的系统的监控需求是什么。&lt;/p&gt;
&lt;p&gt;监控相关工作的第一步是梳理当前系统的组成组件，将每一个都列出来，将它们负责的职责明确清楚，然后将需要监控的Metrics都枚举出来，将这些Metrics需要做成的表类型都想清楚，最后才是使用Prometheus采集数据，使用Grafana制图。&lt;/p&gt;
&lt;p&gt;和写代码一样，优秀的工程师花的更多的时间是在思考和设计上，而不是实际的编写代码。如果不理解这点，那就永远只能是二流。&lt;/p&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/grafana/grafana/issues/9877&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to create new user roles? #9877&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://elkguide.elasticsearch.cn/elasticsearch/other/grafana.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;ELKstack 中文指南 &gt; Grafana&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kiswo.com/article/1021&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grafana使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/grafana/grafana-panels&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Grafana与数据可视化&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;grafana--h-id_app_grafana_help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#grafana--h-id_app_grafana_help&quot; aria-label=&quot;grafana  h id_app_grafana_help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;grafana -h {#ID_APP_GRAFANA_HELP}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ ./bin/grafana-server -h
Usage of ./bin/grafana-server:
  -config string
    	path to config file
  -homepath string
    	path to grafana install/home path, defaults to working directory
  -packaging string
    	describes the way Grafana was installed (default &quot;unknown&quot;)
  -pidfile string
    	path to pid file
  -profile
    	Turn on pprof profiling
  -profile-port int
    	Define custom port for profiling (default 6060)
  -test.bench regexp
    	run only benchmarks matching regexp
  -test.benchmem
    	print memory allocations for benchmarks
  -test.benchtime d
    	run each benchmark for duration d (default 1s)
  -test.blockprofile file
    	write a goroutine blocking profile to file
  -test.blockprofilerate rate
    	set blocking profile rate (see runtime.SetBlockProfileRate) (default 1)
  -test.count n
    	run tests and benchmarks n times (default 1)
  -test.coverprofile file
    	write a coverage profile to file
  -test.cpu list
    	comma-separated list of cpu counts to run each test with
  -test.cpuprofile file
    	write a cpu profile to file
  -test.failfast
    	do not start new tests after the first test failure
  -test.list regexp
    	list tests, examples, and benchmarks matching regexp then exit
  -test.memprofile file
    	write an allocation profile to file
  -test.memprofilerate rate
    	set memory allocation profiling rate (see runtime.MemProfileRate)
  -test.mutexprofile string
    	write a mutex contention profile to the named file after execution
  -test.mutexprofilefraction int
    	if &gt;= 0, calls runtime.SetMutexProfileFraction() (default 1)
  -test.outputdir dir
    	write profiles to dir
  -test.parallel n
    	run at most n tests in parallel (default 8)
  -test.run regexp
    	run only tests and examples matching regexp
  -test.short
    	run smaller test suite to save time
  -test.testlogfile file
    	write test action log to file (for use only by cmd/go)
  -test.timeout d
    	panic test binary after duration d (default 0, timeout disabled)
  -test.trace file
    	write an execution trace to file
  -test.v
    	verbose: print additional output
  -v	prints current version and exits&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;grafanametrics-id_app_self_metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#grafanametrics-id_app_self_metrics&quot; aria-label=&quot;grafanametrics id_app_self_metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;grafana/metrics {#ID_APP_SELF_METRICS}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_alerting_active_alerts amount of active alerts&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_alerting_active_alerts gauge&lt;/span&gt;
grafana_alerting_active_alerts &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_alerting_execution_time_milliseconds summary of alert exeuction duration&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_alerting_execution_time_milliseconds summary&lt;/span&gt;
grafana_alerting_execution_time_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_alerting_execution_time_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_alerting_execution_time_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_alerting_execution_time_milliseconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_alerting_execution_time_milliseconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_admin_user_created_total api admin user created counter&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_admin_user_created_total counter&lt;/span&gt;
grafana_api_admin_user_created_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_dashboard_get_milliseconds summary for dashboard get duration&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_dashboard_get_milliseconds summary&lt;/span&gt;
grafana_api_dashboard_get_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_get_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_get_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_get_milliseconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_api_dashboard_get_milliseconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_dashboard_save_milliseconds summary for dashboard save duration&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_dashboard_save_milliseconds summary&lt;/span&gt;
grafana_api_dashboard_save_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_save_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_save_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_save_milliseconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_api_dashboard_save_milliseconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_dashboard_search_milliseconds summary for dashboard search duration&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_dashboard_search_milliseconds summary&lt;/span&gt;
grafana_api_dashboard_search_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_search_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_search_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dashboard_search_milliseconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_api_dashboard_search_milliseconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_dashboard_snapshot_create_total dashboard snapshots created&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_dashboard_snapshot_create_total counter&lt;/span&gt;
grafana_api_dashboard_snapshot_create_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_dashboard_snapshot_external_total external dashboard snapshots created&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_dashboard_snapshot_external_total counter&lt;/span&gt;
grafana_api_dashboard_snapshot_external_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_dashboard_snapshot_get_total loaded dashboards&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_dashboard_snapshot_get_total counter&lt;/span&gt;
grafana_api_dashboard_snapshot_get_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_dataproxy_request_all_milliseconds summary for dataproxy request duration&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_dataproxy_request_all_milliseconds summary&lt;/span&gt;
grafana_api_dataproxy_request_all_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dataproxy_request_all_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dataproxy_request_all_milliseconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
grafana_api_dataproxy_request_all_milliseconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_api_dataproxy_request_all_milliseconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_login_oauth_total api login oauth counter&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_login_oauth_total counter&lt;/span&gt;
grafana_api_login_oauth_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_login_post_total api login post counter&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_login_post_total counter&lt;/span&gt;
grafana_api_login_post_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_models_dashboard_insert_total dashboards inserted &lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_models_dashboard_insert_total counter&lt;/span&gt;
grafana_api_models_dashboard_insert_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_org_create_total api org created counter&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_org_create_total counter&lt;/span&gt;
grafana_api_org_create_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_response_status_total api http response status&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_response_status_total counter&lt;/span&gt;
grafana_api_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;200&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_api_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;404&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_api_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_api_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_user_signup_completed_total amount of users who completed the signup flow&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_user_signup_completed_total counter&lt;/span&gt;
grafana_api_user_signup_completed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_user_signup_invite_total amount of users who have been invited&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_user_signup_invite_total counter&lt;/span&gt;
grafana_api_user_signup_invite_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_api_user_signup_started_total amount of users who started the signup flow&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_api_user_signup_started_total counter&lt;/span&gt;
grafana_api_user_signup_started_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_aws_cloudwatch_get_metric_data_total counter for getting metric data time series from aws&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_aws_cloudwatch_get_metric_data_total counter&lt;/span&gt;
grafana_aws_cloudwatch_get_metric_data_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_aws_cloudwatch_get_metric_statistics_total counter for getting metric statistics from aws&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_aws_cloudwatch_get_metric_statistics_total counter&lt;/span&gt;
grafana_aws_cloudwatch_get_metric_statistics_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_aws_cloudwatch_list_metrics_total counter for getting list of metrics from aws&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_aws_cloudwatch_list_metrics_total counter&lt;/span&gt;
grafana_aws_cloudwatch_list_metrics_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_build_info A metric with a constant &apos;1&apos; value labeled by version, revision, branch, and goversion from which Grafana was built.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_build_info gauge&lt;/span&gt;
grafana_build_info&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;branch&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;HEAD&quot;&lt;/span&gt;,edition&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;oss&quot;&lt;/span&gt;,goversion&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;go1.11.5&quot;&lt;/span&gt;,revision&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;de8f6ac&quot;&lt;/span&gt;,version&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;6.1.2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_db_datasource_query_by_id_total counter for getting datasource by id&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_db_datasource_query_by_id_total counter&lt;/span&gt;
grafana_db_datasource_query_by_id_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_info Information about the Grafana. This metric is deprecated. please use `grafana_build_info`&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_info gauge&lt;/span&gt;
grafana_info&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;version&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;6.1.2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_instance_start_total counter for started instances&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_instance_start_total counter&lt;/span&gt;
grafana_instance_start_total &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_page_response_status_total page http response status&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_page_response_status_total counter&lt;/span&gt;
grafana_page_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;200&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_page_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;404&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_page_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_page_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_proxy_response_status_total proxy http response status&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_proxy_response_status_total counter&lt;/span&gt;
grafana_proxy_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;200&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_proxy_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;404&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_proxy_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
grafana_proxy_response_status_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_stat_active_users number of active users&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_stat_active_users gauge&lt;/span&gt;
grafana_stat_active_users &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_stat_total_orgs total amount of orgs&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_stat_total_orgs gauge&lt;/span&gt;
grafana_stat_total_orgs &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_stat_total_playlists total amount of playlists&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_stat_total_playlists gauge&lt;/span&gt;
grafana_stat_total_playlists &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_stat_total_users total amount of users&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_stat_total_users gauge&lt;/span&gt;
grafana_stat_total_users &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP grafana_stat_totals_dashboard total amount of dashboards&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE grafana_stat_totals_dashboard gauge&lt;/span&gt;
grafana_stat_totals_dashboard &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Prometheus Notes]]></title><link>https://xenojoshua.com/posts/2019/04/prometheus-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/prometheus-note</guid><pubDate>Tue, 09 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E7%AB%9E%E5%93%81%E6%AF%94%E8%BE%83&quot;&gt;2. 竞品比较&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-comparison-to-alternatives-%E5%B0%8F%E7%BB%93&quot;&gt;2.1 COMPARISON TO ALTERNATIVES 小结&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E4%BC%98%E5%8A%BF&quot;&gt;2.2 优势&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%9F%BA%E7%A1%80--%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8&quot;&gt;3. 基础 &amp;#x26; 日常使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E8%B5%84%E6%BA%90--%E5%AE%89%E8%A3%85&quot;&gt;3.1 资源 &amp;#x26; 安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E6%A6%82%E5%BF%B5&quot;&gt;3.2 概念&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-metrics-type&quot;&gt;3.3 Metrics Type&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-exporter&quot;&gt;3.4 Exporter&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#341-exporter-%E8%BF%87%E6%BB%A4&quot;&gt;3.4.1 Exporter 过滤&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#342-metric_relabel_configs-%E8%BF%87%E6%BB%A4&quot;&gt;3.4.2 metric_relabel_configs 过滤&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot;&gt;3.5 配置文件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#36-promql&quot;&gt;3.6 PromQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#37-%E5%91%8A%E8%AD%A6&quot;&gt;3.7 告警&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#38-graph&quot;&gt;3.8 Graph&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#381-console-template&quot;&gt;3.8.1 Console Template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#382-grafana&quot;&gt;3.8.2 Grafana&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#39-%E5%AD%98%E5%82%A8&quot;&gt;3.9 存储&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#391-%E6%9C%AC%E5%9C%B0%E5%AD%98%E5%82%A8&quot;&gt;3.9.1 本地存储&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#392-%E8%BF%9C%E7%A8%8B%E5%AD%98%E5%82%A8&quot;&gt;3.9.2 远程存储&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#310-%E9%87%8D%E5%A4%8D%E7%9A%84metrics-name&quot;&gt;3.10 重复的Metrics name&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1&quot;&gt;4. 架构设计&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E6%9E%B6%E6%9E%84%E5%9B%BE&quot;&gt;4.1 架构图&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#42-%E9%9B%86%E7%BE%A4%E5%8C%96&quot;&gt;4.2 集群化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#43-%E8%81%94%E9%82%A6%E9%9B%86%E7%BE%A4-federation&quot;&gt;4.3 联邦集群 federation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#44-%E9%AB%98%E5%8F%AF%E7%94%A8&quot;&gt;4.4 高可用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-prometheus%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87&quot;&gt;5. Prometheus监控指标&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-%E8%8C%83%E4%BE%8B&quot;&gt;6. 范例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-docker%E5%AE%9E%E8%B7%B5&quot;&gt;7. Docker实践&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-%E5%B8%B8%E7%94%A8%E7%9B%91%E6%8E%A7&quot;&gt;8. 常用监控&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#81-prometheus&quot;&gt;8.1 Prometheus&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#82-host-machine&quot;&gt;8.2 Host Machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#83-memcached&quot;&gt;8.3 Memcached&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#84-jmx-exporter&quot;&gt;8.4 JMX Exporter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#9-todo&quot;&gt;9. TODO&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot;&gt;链接&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prometheusmetrics-id_app_self_metrics&quot;&gt;prometheus/metrics {#ID_APP_SELF_METRICS}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prometheus--h-id_app_prometheus_help&quot;&gt;prometheus -h {#ID_APP_PROMETHEUS_HELP}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#comparison-to-alternatives-id_app_cta&quot;&gt;COMPARISON TO ALTERNATIVES {#ID_APP_CTA}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#prometheus-vs-graphite&quot;&gt;Prometheus vs. Graphite&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#scope&quot;&gt;Scope&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#data-model&quot;&gt;Data model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#storage&quot;&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#summary&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prometheus-vs-influxdb&quot;&gt;Prometheus vs. InfluxDB&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#scope-1&quot;&gt;Scope&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#data-model--storage&quot;&gt;Data model / storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#architecture&quot;&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#summary-1&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prometheus-vs-opentsdb&quot;&gt;Prometheus vs. OpenTSDB&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#scope-2&quot;&gt;Scope&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#data-model-1&quot;&gt;Data model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#storage-1&quot;&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#summary-2&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prometheus-vs-nagios&quot;&gt;Prometheus vs. Nagios&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#scope-3&quot;&gt;Scope&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#data-model-2&quot;&gt;Data model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#storage-2&quot;&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#architecture-1&quot;&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#summary-3&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#prometheus-vs-sensu&quot;&gt;Prometheus vs. Sensu&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#scope-4&quot;&gt;Scope&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#data-model-3&quot;&gt;Data model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#storage-3&quot;&gt;Storage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#architecture-2&quot;&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#summary-4&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;对于分布式系统来说，监控是非常重要的，少了精密的监控应用程序的状况就无法得知了，也很难查找问题。而在云原生的年代，监控系统（或者说分布式系统的所有组件）最好是使用Go语言编写的，这样才能做到最小的镜像、最高的性能、最佳的CPU利用。所以监控系统的选择其实也不是那么的难，直接用CNCF的Prometheus就可以了。虽然说是这么说，实际使用之前对于工具的理解还是有必要的，因此有了此文。&lt;/p&gt;
&lt;p&gt;此外，这里简单讲下，官方的文档，怎么说呢，只能说是一个”手册”。假设，Prometheus的作者（这里假设是一个自然人）花了100个小时编完了Prometheus的代码，那么这个官方文档估计也就只花了30分钟，内容完全就是一堆细节的堆砌，完全没动脑子。所以，如果你是一名初学者，建议直接忽略官方的文档，去找第三方的书来看。这份文档只对需要跟着最新版本走的工程师，或者需要查找下一些Prometheus知识点或使用方法的工程师有点用。&lt;/p&gt;
&lt;p&gt;这里推荐一本中文的gitbook：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus-book&lt;/a&gt;。从起始的安装和使用例子，到后面的集群管理以及exporter等等，都做了非常详实的解说，最可贵的是，作者写的内容是基于思考、组织之后的，明确地是为了读者服务的，而不像官方文档，仅仅只是一堆细节的罗列。&lt;/p&gt;
&lt;p&gt;版本申明，后续的所有行文内容都基于Prometheus&lt;code class=&quot;language-text&quot;&gt;v2.8.1&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ prometheus --version
prometheus, version 2.8.1 (branch: HEAD, revision: 4d60eb36dcbed725fcac5b27018574118f12fffb)
  build user:       root@bfdd6a22a683
  build date:       20190328-18:09:49
  go version:       go1.11.6&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2-竞品比较&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E7%AB%9E%E5%93%81%E6%AF%94%E8%BE%83&quot; aria-label=&quot;2 竞品比较 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 竞品比较&lt;/h1&gt;
&lt;p&gt;作为一个领域的后来者，最聪明的做法就是在自己的手册里与各位竞品前辈大佬进行一下横向比较，甚至附上性能的benchmark，这样才能取得新使用者的信任。而Prometheus在官方文档的最开始，就有一篇：&lt;a href=&quot;https://prometheus.io/docs/introduction/comparison/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;COMPARISON TO ALTERNATIVES&lt;/a&gt;（这其实也是了解监控相关软件功能的很好的普及文）。&lt;/p&gt;
&lt;p&gt;文中主要提到了5个工具进行横向比较：&lt;code class=&quot;language-text&quot;&gt;Graphite&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;InfluxDB&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;OpenTSDB&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;Nagios&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;Sensu&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;翻译放在最后的&lt;a href=&quot;#ID_APP_CTA&quot;&gt;资料&lt;/a&gt;部分（继续喷下官方文档，这篇比较也写得不怎么样，看完没get到优势或者劣势的点）。&lt;/p&gt;
&lt;h2 id=&quot;21-comparison-to-alternatives-小结&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-comparison-to-alternatives-%E5%B0%8F%E7%BB%93&quot; aria-label=&quot;21 comparison to alternatives 小结 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 COMPARISON TO ALTERNATIVES 小结&lt;/h2&gt;
&lt;p&gt;简单过一下的话：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nagios和Sensu基本上可以直接忽略&lt;/li&gt;
&lt;li&gt;OpenTSDB是基于Hadoop/HBase的，扩展性应该说不错，但过重，且对于Ops的要求比较高&lt;/li&gt;
&lt;li&gt;InfluxDB相当不错，但其杀手锏功能类似于集群化之类的，都是付费版本才有的，且其维护基于单一的商业公司（言下之意，如果你不用商业版，其实InfluxDB也没什么特别大的优势，而且还是单一公司维护有风险）&lt;/li&gt;
&lt;li&gt;Graphite和Prometheus比起来，Prometheus的功能更丰富更强大&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;22-优势&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E4%BC%98%E5%8A%BF&quot; aria-label=&quot;22 优势 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 优势&lt;/h2&gt;
&lt;p&gt;在docker hub的&lt;a href=&quot;https://hub.docker.com/r/prom/prometheus/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;介绍页面&lt;/a&gt;上，有一段优势描述：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;多维度&lt;/code&gt;的数据模型（由metric名字定义的时序，以及一系列键值对的维度）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;灵活的查询语言&lt;/code&gt;来利用这些维度&lt;/li&gt;
&lt;li&gt;无依赖的分布式存储；&lt;code class=&quot;language-text&quot;&gt;自治的单个服务器节点&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;时序数据采集使用基于HTTP的&lt;code class=&quot;language-text&quot;&gt;拉模式&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;利用中间网关来支持&lt;code class=&quot;language-text&quot;&gt;推送&lt;/code&gt;时序数据&lt;/li&gt;
&lt;li&gt;监控目标的发现是通过&lt;code class=&quot;language-text&quot;&gt;服务发现&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;静态配置&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;多种模式的&lt;code class=&quot;language-text&quot;&gt;图像及报表支持&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;支持分层和水平的&lt;code class=&quot;language-text&quot;&gt;联邦集群（federation）&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-基础--日常使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%9F%BA%E7%A1%80--%E6%97%A5%E5%B8%B8%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;3 基础  日常使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 基础 &amp;#x26; 日常使用&lt;/h1&gt;
&lt;h2 id=&quot;31-资源--安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E8%B5%84%E6%BA%90--%E5%AE%89%E8%A3%85&quot; aria-label=&quot;31 资源  安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 资源 &amp;#x26; 安装&lt;/h2&gt;
&lt;p&gt;Prometheus的官方网站：&lt;a href=&quot;https://prometheus.io/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://prometheus.io/&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;安装一般可以直接根据平台下载，Go应用程序的好处就显示出来了，只要一个可执行文件就能运行：&lt;a href=&quot;https://prometheus.io/download/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://prometheus.io/download/&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;一般来说入门只需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;prometheus：本体&lt;/li&gt;
&lt;li&gt;node_exporter：最基本的exporter&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用help放在附录：&lt;a href=&quot;#ID_APP_PROMETHEUS_HELP&quot;&gt;prometheus -h&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;32-概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;32 概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 概念&lt;/h2&gt;
&lt;p&gt;Prometheus的基本概念不算多，但如果不了解的话，看后面的东西会有障碍，因此建议先把概念了解清楚。&lt;/p&gt;
&lt;p&gt;这里先给出一个简单的exporter吐出来的数据范例：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# HELP node_cpu Seconds the cpus spent in each mode.
# TYPE node_cpu counter
node_cpu{cpu=&quot;cpu0&quot;,mode=&quot;idle&quot;} 362812.7890625
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 3.0703125&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Prometheus是一个&lt;code class=&quot;language-text&quot;&gt;时序数据库&lt;/code&gt;，何谓时序数据库，所有保存在Prometheus里的数据都是按时间戳和值的序列顺序存放的，这被称为&lt;code class=&quot;language-text&quot;&gt;Vector（向量）&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Prometheus的数据采集，每一个&lt;code class=&quot;language-text&quot;&gt;Metrics（指标）&lt;/code&gt;都会有两行以&lt;code class=&quot;language-text&quot;&gt;#&lt;/code&gt;字符起始的文本作为开头：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;其中第一行是&lt;code class=&quot;language-text&quot;&gt;注释&lt;/code&gt;：&lt;code class=&quot;language-text&quot;&gt;# HELP ...&lt;/code&gt;，主要用来说明该指标是什么&lt;/li&gt;
&lt;li&gt;第二行是&lt;code class=&quot;language-text&quot;&gt;定义&lt;/code&gt;：&lt;code class=&quot;language-text&quot;&gt;# TYPE ...&lt;/code&gt;，对当前的指标进行&lt;code class=&quot;language-text&quot;&gt;命名&lt;/code&gt;：&lt;code class=&quot;language-text&quot;&gt;node_load1&lt;/code&gt;，及&lt;code class=&quot;language-text&quot;&gt;类型&lt;/code&gt;的定义：&lt;code class=&quot;language-text&quot;&gt;gauge&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除了名字之外，每一个指标都可以有一系列的&lt;code class=&quot;language-text&quot;&gt;Labels（标签）&lt;/code&gt;来描述更细致的维度：&lt;code class=&quot;language-text&quot;&gt;{cpu=&quot;cpu0&quot;,mode=&quot;idle&quot;}&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;每一次数据采集获得到的即一个&lt;code class=&quot;language-text&quot;&gt;Sample（样本）&lt;/code&gt;，其由三部分组成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Metrics（指标）：包含了Metrics name以及Labels&lt;/li&gt;
&lt;li&gt;Timestamp（时间戳）：当前采样的时间，精度到毫秒&lt;/li&gt;
&lt;li&gt;Value（采样值）：其类型为float64浮点数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;--------------- metric ---------------------&gt;&amp;lt;-timestamp -&gt;&amp;lt;-value-&gt;
http_request_total{status=&quot;200&quot;, method=&quot;GET&quot;}@1434417560938 =&gt; 94355
http_request_total{status=&quot;200&quot;, method=&quot;GET&quot;}@1434417561287 =&gt; 94334

http_request_total{status=&quot;404&quot;, method=&quot;GET&quot;}@1434417560938 =&gt; 38473
http_request_total{status=&quot;404&quot;, method=&quot;GET&quot;}@1434417561287 =&gt; 38544

http_request_total{status=&quot;200&quot;, method=&quot;POST&quot;}@1434417560938 =&gt; 4748
http_request_total{status=&quot;200&quot;, method=&quot;POST&quot;}@1434417561287 =&gt; 4785&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在Prometheus内部有一个预定义的变量&lt;code class=&quot;language-text&quot;&gt;__name__&lt;/code&gt;用来表达&lt;code class=&quot;language-text&quot;&gt;Metrics name&lt;/code&gt;（这里注意，该值只是名字，不含Label），在后续编程及配置文件处理的时候会用得到：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;api_http_requests_total{method=&quot;POST&quot;, handler=&quot;/messages&quot;}
=
{__name__=&quot;api_http_requests_total&quot;，method=&quot;POST&quot;, handler=&quot;/messages&quot;}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Prometheus服务器启动的时候，可以设置从很多端点（endpoint）进行数据采集。比如说：我们有一个主机，主机上运行了3个Go程序，一个Java程序，以及一个数据库。那么我们采集的时候就需要运行6个工作：主机采集、Go采集*3、Java采集、数据库采集。这6个工作，每一个我们都称之为：&lt;code class=&quot;language-text&quot;&gt;Job&lt;/code&gt;。Job可以自由设置采集的IP、端口以及endpoint，因此其自由度相当高，可以采集同服务器的不同服务，也可以采集不同的服务器上的数据，最终都汇总到一台Prometheus服务器上。&lt;/p&gt;
&lt;p&gt;资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/querying/basics/#instant-vector-selectors&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Instant vector selectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.robustperception.io/whats-in-a-__name__&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What’s in a __name__?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;33-metrics-type&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-metrics-type&quot; aria-label=&quot;33 metrics type permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 Metrics Type&lt;/h2&gt;
&lt;p&gt;Prometheus定义了4中不同的Metrics Type（指标类型）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-metrics-types#counter-zhi-zeng-bu-jian-de-ji-shu-qi&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Counter（计数器）&lt;/a&gt;：只增不减的计数器&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-metrics-types#gauge-ke-zeng-ke-jian-de-yi-biao-pan&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gauge（仪表盘）&lt;/a&gt;：可增可减的仪表盘&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-metrics-types#shi-yong-histogram-he-summary-fen-xi-shu-ju-fen-bu-qing-kuang&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Histogram（直方图）&lt;/a&gt;：数据分布情况&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-metrics-types#shi-yong-histogram-he-summary-fen-xi-shu-ju-fen-bu-qing-kuang&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Summary（摘要）&lt;/a&gt;：数据分布情况&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后的两个有点类似，区别在于Histogram描述的是绝对值，而Summary描述的是百分比。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# HELP prometheus_tsdb_compaction_chunk_range Final time range of chunks on their first compaction
# TYPE prometheus_tsdb_compaction_chunk_range histogram
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;100&quot;} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;400&quot;} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;1600&quot;} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;6400&quot;} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;25600&quot;} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;102400&quot;} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;409600&quot;} 0
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;1.6384e+06&quot;} 260
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;6.5536e+06&quot;} 780
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;2.62144e+07&quot;} 780
prometheus_tsdb_compaction_chunk_range_bucket{le=&quot;+Inf&quot;} 780
prometheus_tsdb_compaction_chunk_range_sum 1.1540798e+09
prometheus_tsdb_compaction_chunk_range_count 780&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;# HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.
# TYPE prometheus_tsdb_wal_fsync_duration_seconds summary
prometheus_tsdb_wal_fsync_duration_seconds{quantile=&quot;0.5&quot;} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile=&quot;0.9&quot;} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile=&quot;0.99&quot;} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;34-exporter&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-exporter&quot; aria-label=&quot;34 exporter permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 Exporter&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://prometheus.io/docs/instrumenting/exporters/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;EXPORTERS AND INTEGRATIONS&lt;/a&gt;。以及中文：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;第4章 Exporter详解&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Prometheus的设计是Prometheus服务器进行&lt;code class=&quot;language-text&quot;&gt;拉&lt;/code&gt;操作，而受监控对象则将时序数据吐出来给服务器。为了不影响受监控的应用程序本身，一般是用Sidecar设计，在应用程序之外进行数据的吐出，也就是&lt;code class=&quot;language-text&quot;&gt;Exporter&lt;/code&gt;这个角色（应用程序）。当然，如果需要直接在当前应用程序中进行数据暴露也是可以的，直接使用一些类库引入到应用程序中即可。&lt;/p&gt;
&lt;p&gt;Prometheus流行起来之后，主流的应用程序一般都有对应的Exporter，直接下载使用即可。这里要提一下node_exporter，因为它是针对主机进行监控，因此不建议运行在容器里。容器本身就是和主机进行隔离的，运行在容器之中的话node_exporter无法很好工作。&lt;/p&gt;
&lt;p&gt;这里需要注意的点是：&lt;code class=&quot;language-text&quot;&gt;信息的过滤&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Prometheus的特性是，只要你在配置文件中将某个Exporter设定为Prometheus定时抓取的对象，Prometheus就会将这个Exporter吐出的&lt;code class=&quot;language-text&quot;&gt;所有数据&lt;/code&gt;都定期采集起来，保存到时序数据库中。而实际情况则是，某个Exporter吐出来的数据中有很大一部分其实是我们并不关心的。&lt;/p&gt;
&lt;p&gt;举个例子，Go语言的Exporter会吐出GC、内存、CPU、Goroutine等等一系列数据，而我们可能只关心GC、内存，其他都不关心。这个时候如果还是按默认的行为来进行采集的话，时序数据库里就会有很多无意义（我们不关心）的数据。为了防止这样的情况发生，有两种做法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在启动Exporter的时候将部分指标过滤掉，直接不吐出来&lt;/li&gt;
&lt;li&gt;在Prometheus配置文件中针对采集的Job进行&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;341-exporter-过滤&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#341-exporter-%E8%BF%87%E6%BB%A4&quot; aria-label=&quot;341 exporter 过滤 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4.1 Exporter 过滤&lt;/h3&gt;
&lt;p&gt;举个例子，node_exporter在MAC上启动，默认会吐出如下数据：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;INFO[0000] Enabled collectors:                           source=&quot;node_exporter.go:90&quot;
INFO[0000]  - boottime                                   source=&quot;node_exporter.go:97&quot;
INFO[0000]  - cpu                                        source=&quot;node_exporter.go:97&quot;
INFO[0000]  - diskstats                                  source=&quot;node_exporter.go:97&quot;
INFO[0000]  - filesystem                                 source=&quot;node_exporter.go:97&quot;
INFO[0000]  - loadavg                                    source=&quot;node_exporter.go:97&quot;
INFO[0000]  - meminfo                                    source=&quot;node_exporter.go:97&quot;
INFO[0000]  - netdev                                     source=&quot;node_exporter.go:97&quot;
INFO[0000]  - textfile                                   source=&quot;node_exporter.go:97&quot;
INFO[0000]  - time                                       source=&quot;node_exporter.go:97&quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;我们就可以在启动的时候附加：&lt;code class=&quot;language-text&quot;&gt;--no-collector.time&lt;/code&gt;option（time可置换成其他的），让其不再吐出，当然也可以添加option（—collector.xxx）吐出某些我们需要但默认不开启的数据。不同的Exporter设置可能会有些微不同，建议使用的时候仔细查看其手册。&lt;/p&gt;
&lt;p&gt;这样的设计模式其实是有问题的，在使用的时候需要大量设置，用起来过于复杂：&lt;a href=&quot;https://github.com/prometheus/node_exporter/issues/735&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Question: Disable all collectors?&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;342-metric_relabel_configs-过滤&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#342-metric_relabel_configs-%E8%BF%87%E6%BB%A4&quot; aria-label=&quot;342 metric_relabel_configs 过滤 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4.2 metric_relabel_configs 过滤&lt;/h3&gt;
&lt;p&gt;官方文档在：&lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;&amp;#x3C;metric_relabel_configs&gt;&lt;/a&gt;。讲解可以看一篇英语的：&lt;a href=&quot;https://medium.com/quiq-blog/prometheus-relabeling-tricks-6ae62c56cbda&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus relabeling tricks&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这个配置项的作用主要有几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在入库之前去掉不需要的指标&lt;/li&gt;
&lt;li&gt;将入库的某些指标重新命名（这点很有用，后面会说到）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;该配置项的效果会在数据入库之前生效，因此非常有用，可以显著减少入库的数据量，减少磁盘的容量占用，加快数据查询。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;metric_relabel_configs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;source_labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;__name__&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &quot;(\
      go_gc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;\
      &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;\
      node_memory_wired_bytes\
    )&quot;
    &lt;span class=&quot;token key atrule&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; drop&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;上面的例子里使用了字符串换行，这里需要注意的是需要换行的字符串一定要使用双引号&lt;code class=&quot;language-text&quot;&gt;&quot;&lt;/code&gt;，双引号里的字符是不会被转译的，换行符&lt;code class=&quot;language-text&quot;&gt;\&lt;/code&gt;也就不会失效了。不换行的话，写法是：&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;regex: &quot;(filtered1|filtered2|filtered3)&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;总而言之，在数据过滤方面，Prometheus做的真的不好，无论是在Exporter端做过滤还是在配置文件里做过滤，都需要写不少过滤条目，蛮麻烦的。&lt;/p&gt;
&lt;h2 id=&quot;35-配置文件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#35-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6&quot; aria-label=&quot;35 配置文件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.5 配置文件&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/configuration/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CONFIGURATION&lt;/a&gt;。有一篇中文的译文不错，但不是太全：&lt;a href=&quot;https://www.jianshu.com/p/bedd169676b6&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus的安装和配置&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;配置文件这块，官方的文档细节肯定是最全的，有很多不常用的选项之类的，估计一般也只有官方文档里才找得到。不过官方文档就像我一开始说的，讲解得实在是，光有细节没有脑子。因此建议看一些范例，对配置文件有一个大概的了解之后再去官方文档里查细节会比较好。&lt;/p&gt;
&lt;p&gt;主要的配置大项有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;抓取配置 &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;scrape_configs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;规则配置 &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;recording_rules&lt;/a&gt; &lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/alert/prometheus-recoding-rules#ding-yi-recoding-rules&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;中文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;告警配置 &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;alerting_rules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;36-promql&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#36-promql&quot; aria-label=&quot;36 promql permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.6 PromQL&lt;/h2&gt;
&lt;p&gt;Prometheus这块的设计应该说还算是比较可读的，可以看下中文book里的内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-query-language&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;初识PromQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-promql-operators-v2&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PromQL操作符&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-aggr-ops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PromQL聚合操作&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-promql-functions&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PromQL内置函数&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;37-告警&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#37-%E5%91%8A%E8%AD%A6&quot; aria-label=&quot;37 告警 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.7 告警&lt;/h2&gt;
&lt;p&gt;Prometheus里的告警功能做得非常强大，按规则的组合可以轻松对告警进行规则定义、分组，并可以使用Altermanager进行对应的告警行为。当然使用上就有点复杂，需要花点时间梳理下。具体的细节可以查看：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/alert&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;第3章 Prometheus告警处理&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;38-graph&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#38-graph&quot; aria-label=&quot;38 graph permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.8 Graph&lt;/h2&gt;
&lt;h3 id=&quot;381-console-template&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#381-console-template&quot; aria-label=&quot;381 console template permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.8.1 Console Template&lt;/h3&gt;
&lt;p&gt;Prometheus的服务器有提供集成的图像化解决方案，这被称为：&lt;code class=&quot;language-text&quot;&gt;Console Template&lt;/code&gt;，其实无非就是一个模板引擎然后向其中填充数据。上手还是需要花点时间稍微摸索下，具体的细节可以查看：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/grafana/use-console-template&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用Console Template&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;382-grafana&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#382-grafana&quot; aria-label=&quot;382 grafana permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.8.2 Grafana&lt;/h3&gt;
&lt;p&gt;现在比较主流的图像化做法是数据采集和存储由Prometheus来，然后图像化输出则由Grafana来处理。这块后面会在Grafana的专题里进行讲解。&lt;/p&gt;
&lt;h2 id=&quot;39-存储&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#39-%E5%AD%98%E5%82%A8&quot; aria-label=&quot;39 存储 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.9 存储&lt;/h2&gt;
&lt;h3 id=&quot;391-本地存储&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#391-%E6%9C%AC%E5%9C%B0%E5%AD%98%E5%82%A8&quot; aria-label=&quot;391 本地存储 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.9.1 本地存储&lt;/h3&gt;
&lt;p&gt;Prometheus的时序数据库默认是存储在本地磁盘的，以2小时时间长度为分段，将数据存储到一个Block（块）中。具体的细节可以查看：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/readmd/prometheus-local-storage&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;本地存储&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;392-远程存储&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#392-%E8%BF%9C%E7%A8%8B%E5%AD%98%E5%82%A8&quot; aria-label=&quot;392 远程存储 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.9.2 远程存储&lt;/h3&gt;
&lt;p&gt;本地存储在可用性及高效性上有先天优势，但也有很多问题，最主要的就是本地磁盘的容量问题，本地磁盘容量不足就不能够保存长期数据。因此Prometheus也提供了远程写和远程读的设置，允许开发者将时序数据库的数据存储在远程介质中。具体的细节可以查看：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/readmd/prometheus-remote-storage&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;远程存储&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;310-重复的metrics-name&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#310-%E9%87%8D%E5%A4%8D%E7%9A%84metrics-name&quot; aria-label=&quot;310 重复的metrics name permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.10 重复的Metrics name&lt;/h2&gt;
&lt;p&gt;有一个比较常见的麻烦问题是：在同一个Prometheus服务器节点上，可能会采集到大量重名的指标。&lt;/p&gt;
&lt;p&gt;这里举个例子来说：同一台Linux服务器节点上，有3个Go应用程序在运行，而我们需要把这三个应用程序的Go相关指标都监控起来。这时候你会发现采集上来的3份Go指标数据，其指标名都是重复的。这很正常，因为采集的指标都是同样的东西，只不过吐出数据的应用程序不同而已。&lt;/p&gt;
&lt;p&gt;这时候我们就需要用到之前提到过的：&lt;code class=&quot;language-text&quot;&gt;metric_relabel_configs&lt;/code&gt;。每个Go应用程序肯定是在Prometheus服务器上设置成单独的&lt;code class=&quot;language-text&quot;&gt;Jobs&lt;/code&gt;，而这些不同的Jobs就需要设置各自的metric_relabel_configs，将获取到的同名指标重命名成和应用程序相关的指标，当然指标名的意义需要保持不变。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;job_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; cadvisor
  &lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;metric_relabel_configs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;source_labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.*/(.*)&apos;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;replacement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$1&apos;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;target_label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; id
  &lt;span class=&quot;token punctuation&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;source_labels&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;service&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;regex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ecs-.*:ecs-([a-z]+-*[a-z]*).*:[0-9]+&apos;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;replacement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;$1&apos;&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;target_label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; service&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-架构设计&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1&quot; aria-label=&quot;4 架构设计 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 架构设计&lt;/h1&gt;
&lt;h2 id=&quot;41-架构图&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E6%9E%B6%E6%9E%84%E5%9B%BE&quot; aria-label=&quot;41 架构图 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 架构图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;/media/posts/2019/04/prometheus-note/architecture.png&quot; alt=&quot;Architecture&quot;&gt;&lt;/p&gt;
&lt;p&gt;Prometheus的设计理念就是保证单节点的性能、功能完整性以及单节点的使用便利性。在这个理念下，Prometheus的使用是一件很简单的事情，稍微做点配置调整就可以使用了，而且这个节点上的所有数据都是存储在其本身的物理磁盘上的（有选项可以远程存储，这里按下不表），保证了不会有跨物理节点的各种问题。&lt;/p&gt;
&lt;h2 id=&quot;42-集群化&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#42-%E9%9B%86%E7%BE%A4%E5%8C%96&quot; aria-label=&quot;42 集群化 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.2 集群化&lt;/h2&gt;
&lt;p&gt;Prometheus将单个节点做到极致的设计理念无疑是非常出色的，但万事都没有银弹。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整体的集群庞大到一定程度之后（全局的监控需求）&lt;/li&gt;
&lt;li&gt;单个服务的集群扩展到一定程度（单服务的监控需求）&lt;/li&gt;
&lt;li&gt;跨机房监控需求（单个机房单个Prometheus服务器，但需要有一个跳脱实例机房的节点进行overview）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在这些情况下，单个节点的Prometheus可能就无法胜任了。这时候必然就需要进行水平扩展或引入分布式集群的概念。&lt;/p&gt;
&lt;h2 id=&quot;43-联邦集群-federation&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#43-%E8%81%94%E9%82%A6%E9%9B%86%E7%BE%A4-federation&quot; aria-label=&quot;43 联邦集群 federation permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.3 联邦集群 federation&lt;/h2&gt;
&lt;p&gt;联邦集群是官方提供的Prometheus唯一的集群解决方案。这个名词听上去有点玄乎，其实简单来说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;联邦集群中的Prometheus节点是分层级的&lt;/li&gt;
&lt;li&gt;下级的Prometheus节点采集应用数据&lt;/li&gt;
&lt;li&gt;上级的Prometheus节点从下级的Prometheus节点上采集数据&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有几点需要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下级Prometheus默认在&lt;code class=&quot;language-text&quot;&gt;/federate&lt;/code&gt;endpoint暴露联邦集群的数据采集点，不需要配置&lt;/li&gt;
&lt;li&gt;上级Prometheus必须在配置文件里指定&lt;code class=&quot;language-text&quot;&gt;params:&apos;match[]&apos;:- &apos;{__name__=~&quot;node_.*&quot;}&apos;&lt;/code&gt;这样的采集规则才能真正采集到数据，这方面的行为模式和Prometheus的默认模式是不一样的；默认情况下Prometheus会将暴露出来的所有数据都采集起来，但联邦集群的时候如果上级节点不指定采集的过滤参数的话，默认是什么都不采集（可能考虑到量级会有问题），因此必须手动在配置文件里进行指标名（可以组合标签）的过滤&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;说穿了其实所谓的联邦集群也没什么内容，无非就是在启动的Prometheus节点上默认开了个&lt;code class=&quot;language-text&quot;&gt;/federate&lt;/code&gt;endpoint，允许其他Prometheus从它这里拉取数据。至于联邦集群怎么组建，能玩出什么花来，Prometheus就不管了，让搭建者自己发挥。&lt;/p&gt;
&lt;h2 id=&quot;44-高可用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#44-%E9%AB%98%E5%8F%AF%E7%94%A8&quot; aria-label=&quot;44 高可用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.4 高可用&lt;/h2&gt;
&lt;p&gt;简单的结论是：Prometheus&lt;code class=&quot;language-text&quot;&gt;并不存在高可用&lt;/code&gt;的解决方案。&lt;/p&gt;
&lt;p&gt;官方现在的设计是将单节点的Prometheus做好，并提供联邦集群这个解决方案让用户自己去组建自己的监控拓扑网络。这在规模比较小的时候还算能对付，但在真正规模大起来之后就很容易出错了，维护者必须很清楚联邦集群里每一个节点负责的业务内容是什么，然后各层级节点如何对应汇集数据，这非常考验整个拓扑结构的搭建者的功力，以及维护的流程和工具。&lt;/p&gt;
&lt;p&gt;Prometheus当前的集群设计给我的感觉有点类似于：3.0版本之前的redis的第三方集群解决方案 与 3.0版本之后redis官方提供的集群解决方案 之间的关系。你不能说第三方做的集群解决方案不能用，但和3.0之后官方集群方案提供的高可用相比之下，不得不说就不是一个档次上的了。&lt;/p&gt;
&lt;p&gt;希望今后的Prometheus能在这方面发力。当然可能在组合了K8S之后，联邦集群也够用了，这方面我还没尝试过，就不做判断了。&lt;/p&gt;
&lt;p&gt;这篇可以好好看下：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/part-ii-prometheus-jin-jie/readmd/prometheus-and-high-availability&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus高可用&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;5-prometheus监控指标&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-prometheus%E7%9B%91%E6%8E%A7%E6%8C%87%E6%A0%87&quot; aria-label=&quot;5 prometheus监控指标 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Prometheus监控指标&lt;/h1&gt;
&lt;p&gt;Prometheus对自身的指标也有直接暴露，默认是放在：http://url_of_prometheus_server/metrics。&lt;/p&gt;
&lt;p&gt;附录里我放了一份指标，可以研究下：&lt;a href=&quot;#ID_APP_SELF_METRICS&quot;&gt;prometheus/metrics&lt;/a&gt;。对于Prometheus自身的监控也是必要的。&lt;/p&gt;
&lt;h1 id=&quot;6-范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;6 范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. 范例&lt;/h1&gt;
&lt;p&gt;实际的可运行范例可以查看：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/tree/master/experiment/prometheus/federation&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/experiment/prometheus/federation/&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;7-docker实践&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-docker%E5%AE%9E%E8%B7%B5&quot; aria-label=&quot;7 docker实践 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. Docker实践&lt;/h1&gt;
&lt;p&gt;Prometheus在容器内运行有些难点，主要是配置上的，官方不支持在env中覆写配置文件中的内容，只允许使用bind mount的方式将配置文件加载进容器：&lt;a href=&quot;https://github.com/prometheus/prometheus/issues/2357&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Support for environment variable substitution in configuration file #2357&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;这样一来所有的配置就必须使用配置文件的方式来生效，对于需要动态运行以及容器内集群支持的部署者来说就非常不友好，但官方维护者比较独裁，也没什么办法。&lt;/p&gt;
&lt;p&gt;可运行范例参见：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/dist-system-practice/conf/dev/prometheus-cluster.yaml&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;dist-system-practice/conf/dev/prometheus-cluster.yaml&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;8-常用监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-%E5%B8%B8%E7%94%A8%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;8 常用监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. 常用监控&lt;/h1&gt;
&lt;h2 id=&quot;81-prometheus&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#81-prometheus&quot; aria-label=&quot;81 prometheus permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.1 Prometheus&lt;/h2&gt;
&lt;p&gt;Prometheus自带metrics输出，自己采集自己即可，当然也可以用一个节点的prometheus将整个集群的metrics都采集起来。Grafana这边有一个2.0的Dashboard可以开箱即用，非常方便：&lt;a href=&quot;https://grafana.com/dashboards/3662&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus 2.0 Overview&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;82-host-machine&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#82-host-machine&quot; aria-label=&quot;82 host machine permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.2 Host Machine&lt;/h2&gt;
&lt;p&gt;主机监控需要使用node_exporter：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;代码：&lt;a href=&quot;https://github.com/prometheus/node_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus/node_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;镜像：&lt;a href=&quot;https://hub.docker.com/r/prom/node-exporter/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prom/node-exporter&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;prom/node-exporter:v0.17.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;之前提到过，指标默认基本上全部都开启并输出，如果需要过滤部分非常麻烦：&lt;a href=&quot;https://github.com/prometheus/node_exporter/issues/735&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Question: Disable all collectors?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;不同的操作系统指标名不同，exporter直接将系统的指标名输出出来，因此不同系统还不同，且官方目前来看没有意愿进行抽象统一：&lt;a href=&quot;https://github.com/prometheus/node_exporter/issues/855&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Weird Memory Readings on macOS #855&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Grafana Dashboard：&lt;a href=&quot;https://grafana.com/dashboards/8919&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;1 Node Exporter 0.16—0.18 for Prometheus 监控展示看板&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;depends: grafana-cli plugins install grafana-piechart-panel&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;83-memcached&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#83-memcached&quot; aria-label=&quot;83 memcached permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.3 Memcached&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Exporter代码：&lt;a href=&quot;https://github.com/prometheus/memcached_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus/memcached_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter镜像：&lt;a href=&quot;https://hub.docker.com/r/prom/memcached-exporter/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prom/memcached-exporter&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;prom/memcached-exporter:v0.5.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard：&lt;a href=&quot;https://grafana.com/dashboards/37&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus memcached&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;84-jmx-exporter&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#84-jmx-exporter&quot; aria-label=&quot;84 jmx exporter permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8.4 JMX Exporter&lt;/h2&gt;
&lt;p&gt;官方介绍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;JMX to Prometheus exporter: a collector that can configurably scrape and expose mBeans of a JMX target.&lt;/p&gt;
&lt;p&gt;This exporter is intended to be run as a Java Agent, exposing a HTTP server and serving metrics of the local JVM. It can be also run as an independent HTTP server and scrape remote JMX targets, but this has various disadvantages, such as being harder to configure and being unable to expose process metrics (e.g., memory and CPU usage). Running the exporter as a Java Agent is thus strongly encouraged.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;大部分以JAVA为runtime的应用程序在进行监控的时候都需要使用到这个组件，因此使用频度还是相当高的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Exporter代码：&lt;a href=&quot;https://github.com/prometheus/jmx_exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus/jmx_exporter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Exporter镜像：&lt;a href=&quot;https://hub.docker.com/r/sscaling/jmx-prometheus-exporter&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;sscaling/jmx-prometheus-exporter&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;sscaling/jmx-prometheus-exporter:0.11.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Dashboard：通用的dashboard在这里比较没意义，因为使用java作为runtime的应用程序可能是web、可能是存储，多种多样，使用时需要根据应用程序进行适配的dashboard查找&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;9-todo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#9-todo&quot; aria-label=&quot;9 todo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;9. TODO&lt;/h1&gt;
&lt;p&gt;囿于当前使用的深度及项目调研的时间限制，有部分内容做的还不够深入，后续可以考虑补全：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prometheus自身的Metrics深入研究，以便将Prometheus自身也纳入监控&lt;/li&gt;
&lt;li&gt;Prometheus的Benchmark&lt;/li&gt;
&lt;li&gt;PromQL深入理解&lt;/li&gt;
&lt;li&gt;聚合操作：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-aggr-ops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PromQL聚合操作&lt;/a&gt; &amp;#x26; &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/querying/operators/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;OPERATORS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;内置函数：&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/parti-prometheus-ji-chu/promql/prometheus-promql-functions&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;PromQL内置函数&lt;/a&gt; &amp;#x26; &lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/querying/functions/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;FUNCTIONS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;常用Exporter及其指标含义 及 实际可用的指标公式换算&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;链接&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%93%BE%E6%8E%A5&quot; aria-label=&quot;链接 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;链接&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://yunlzheng.gitbook.io/prometheus-book/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus-book&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://prometheus.io/docs/prometheus/latest/querying/basics/#instant-vector-selectors&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Instant vector selectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.robustperception.io/whats-in-a-__name__&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;What’s in a __name__?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/prometheus/node_exporter/issues/735&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Question: Disable all collectors?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/quiq-blog/prometheus-relabeling-tricks-6ae62c56cbda&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus relabeling tricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/bedd169676b6&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus的安装和配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.servicemesher.com/blog/prometheus-monitor-k8s-1/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus监控Kubernetes系列1——监控框架&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.servicemesher.com/blog/prometheus-monitor-k8s-2/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus监控Kubernetes系列2——监控部署&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.servicemesher.com/blog/prometheus-monitor-k8s-3/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Prometheus监控Kubernetes系列3——业务指标采集&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;prometheusmetrics-id_app_self_metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheusmetrics-id_app_self_metrics&quot; aria-label=&quot;prometheusmetrics id_app_self_metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;prometheus/metrics {#ID_APP_SELF_METRICS}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# HELP net_conntrack_dialer_conn_attempted_total Total number of connections attempted by the given dialer a given name.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE net_conntrack_dialer_conn_attempted_total counter&lt;/span&gt;
net_conntrack_dialer_conn_attempted_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dialer_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# 这里的dialer_name其实就是job名字&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP net_conntrack_dialer_conn_closed_total Total number of connections closed which originated from the dialer of a given name.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE net_conntrack_dialer_conn_closed_total counter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token comment&quot;&gt;# HELP net_conntrack_dialer_conn_established_total Total number of connections successfully established by the given dialer a given name.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE net_conntrack_dialer_conn_established_total counter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token comment&quot;&gt;# HELP net_conntrack_dialer_conn_failed_total Total number of connections failed to dial by the dialer a given name.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE net_conntrack_dialer_conn_failed_total counter&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;. &lt;span class=&quot;token comment&quot;&gt;# 这里的label：{dialer_name=&quot;federate&quot;,reason=&quot;refused|resolution|timeout|unknown&quot;}&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP net_conntrack_listener_conn_accepted_total Total number of connections opened to the listener of a given name.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE net_conntrack_listener_conn_accepted_total counter&lt;/span&gt;
net_conntrack_listener_conn_accepted_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;listener_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;124&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP net_conntrack_listener_conn_closed_total Total number of connections closed that were made to the listener of a given name.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE net_conntrack_listener_conn_closed_total counter&lt;/span&gt;
net_conntrack_listener_conn_closed_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;listener_name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;http&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;122&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_api_remote_read_queries The current number of remote read queries being executed or waiting.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_api_remote_read_queries gauge&lt;/span&gt;
prometheus_api_remote_read_queries &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_build_info A metric with a constant &apos;1&apos; value labeled by version, revision, branch, and goversion from which prometheus was built.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_build_info gauge&lt;/span&gt;
prometheus_build_info&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;branch&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;HEAD&quot;&lt;/span&gt;,goversion&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;go1.11.6&quot;&lt;/span&gt;,revision&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4d60eb36dcbed725fcac5b27018574118f12fffb&quot;&lt;/span&gt;,version&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.8.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_config_last_reload_success_timestamp_seconds Timestamp of the last successful configuration reload.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_config_last_reload_success_timestamp_seconds gauge&lt;/span&gt;
prometheus_config_last_reload_success_timestamp_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.5547790627954009e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_config_last_reload_successful Whether the last configuration reload attempt was successful.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_config_last_reload_successful gauge&lt;/span&gt;
prometheus_config_last_reload_successful &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_engine_queries The current number of queries being executed or waiting.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_engine_queries gauge&lt;/span&gt;
prometheus_engine_queries &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_engine_queries_concurrent_max The max number of concurrent queries.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_engine_queries_concurrent_max gauge&lt;/span&gt;
prometheus_engine_queries_concurrent_max &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_engine_query_duration_seconds Query timings&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_engine_query_duration_seconds summary&lt;/span&gt;
prometheus_engine_query_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;slice&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;inner_eval&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_engine_query_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;slice&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;inner_eval&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_engine_query_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;slice&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;inner_eval&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_engine_query_duration_seconds_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;slice&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;inner_eval&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;.2003e-05
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;. prepare_time &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; queue_time &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; result_sort
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_http_request_duration_seconds Histogram of latencies for HTTP requests.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_http_request_duration_seconds histogram&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;3&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;20&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;60&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;120&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_request_duration_seconds_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.000778872&lt;/span&gt;
prometheus_http_request_duration_seconds_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;. /api/v1/query &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; /graph &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; /static/*filepath &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; /targets
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_http_response_size_bytes Histogram of response size for HTTP requests.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_http_response_size_bytes histogram&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100000&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1e+06&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1e+07&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1e+08&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1e+09&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;,le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_http_response_size_bytes_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;293&lt;/span&gt;
prometheus_http_response_size_bytes_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;handler&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/api/v1/label/:name/values&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;. /api/v1/query &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; /graph &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; /static/*filepath &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; /targets
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_notifications_alertmanagers_discovered The number of alertmanagers discovered and active.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_notifications_alertmanagers_discovered gauge&lt;/span&gt;
prometheus_notifications_alertmanagers_discovered &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_notifications_dropped_total Total number of alerts dropped due to errors when sending to Alertmanager.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_notifications_dropped_total counter&lt;/span&gt;
prometheus_notifications_dropped_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_notifications_queue_capacity The capacity of the alert notifications queue.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_notifications_queue_capacity gauge&lt;/span&gt;
prometheus_notifications_queue_capacity &lt;span class=&quot;token number&quot;&gt;10000&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_notifications_queue_length The number of alert notifications in the queue.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_notifications_queue_length gauge&lt;/span&gt;
prometheus_notifications_queue_length &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_remote_storage_highest_timestamp_in_seconds Highest timestamp that has come into the remote storage via the Appender interface, in seconds since epoch.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_remote_storage_highest_timestamp_in_seconds gauge&lt;/span&gt;
prometheus_remote_storage_highest_timestamp_in_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.554792751e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_remote_storage_samples_in_total Samples in to remote storage, compare to samples out for queue managers.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_remote_storage_samples_in_total counter&lt;/span&gt;
prometheus_remote_storage_samples_in_total &lt;span class=&quot;token number&quot;&gt;123185&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_rule_evaluation_duration_seconds The duration for a rule to execute.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_rule_evaluation_duration_seconds summary&lt;/span&gt;
prometheus_rule_evaluation_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_evaluation_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_evaluation_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_evaluation_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_rule_evaluation_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_rule_evaluation_failures_total The total number of rule evaluation failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_rule_evaluation_failures_total counter&lt;/span&gt;
prometheus_rule_evaluation_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_rule_evaluations_total The total number of rule evaluations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_rule_evaluations_total counter&lt;/span&gt;
prometheus_rule_evaluations_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_rule_group_duration_seconds The duration of rule group evaluations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_rule_group_duration_seconds summary&lt;/span&gt;
prometheus_rule_group_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_group_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_group_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_group_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_group_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_rule_group_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_rule_group_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_rule_group_iterations_missed_total The total number of rule group evaluations missed due to slow rule group evaluation.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_rule_group_iterations_missed_total counter&lt;/span&gt;
prometheus_rule_group_iterations_missed_total &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_rule_group_iterations_total The total number of scheduled rule group evaluations, whether executed or missed.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_rule_group_iterations_total counter&lt;/span&gt;
prometheus_rule_group_iterations_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_azure_refresh_duration_seconds The duration of a Azure-SD refresh in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_azure_refresh_duration_seconds summary&lt;/span&gt;
prometheus_sd_azure_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_azure_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_azure_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_azure_refresh_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_azure_refresh_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_azure_refresh_failures_total Number of Azure-SD refresh failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_azure_refresh_failures_total counter&lt;/span&gt;
prometheus_sd_azure_refresh_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_consul_rpc_duration_seconds The duration of a Consul RPC call in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_consul_rpc_duration_seconds summary&lt;/span&gt;
prometheus_sd_consul_rpc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_consul_rpc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_consul_rpc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_consul_rpc_duration_seconds_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_consul_rpc_duration_seconds_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_consul_rpc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;services&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_consul_rpc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;services&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_consul_rpc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;services&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_consul_rpc_duration_seconds_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;services&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_consul_rpc_duration_seconds_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;call&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;services&quot;&lt;/span&gt;,endpoint&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;catalog&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_consul_rpc_failures_total The number of Consul RPC call failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_consul_rpc_failures_total counter&lt;/span&gt;
prometheus_sd_consul_rpc_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_discovered_targets Current number of discovered targets.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_discovered_targets gauge&lt;/span&gt;
prometheus_sd_discovered_targets&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;config&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;,name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;scrape&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_dns_lookup_failures_total The number of DNS-SD lookup failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_dns_lookup_failures_total counter&lt;/span&gt;
prometheus_sd_dns_lookup_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_dns_lookups_total The number of DNS-SD lookups.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_dns_lookups_total counter&lt;/span&gt;
prometheus_sd_dns_lookups_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_ec2_refresh_duration_seconds The duration of a EC2-SD refresh in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_ec2_refresh_duration_seconds summary&lt;/span&gt;
prometheus_sd_ec2_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_ec2_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_ec2_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_ec2_refresh_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_ec2_refresh_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_ec2_refresh_failures_total The number of EC2-SD scrape failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_ec2_refresh_failures_total counter&lt;/span&gt;
prometheus_sd_ec2_refresh_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_file_read_errors_total The number of File-SD read errors.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_file_read_errors_total counter&lt;/span&gt;
prometheus_sd_file_read_errors_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_file_scan_duration_seconds The duration of the File-SD scan in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_file_scan_duration_seconds summary&lt;/span&gt;
prometheus_sd_file_scan_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_file_scan_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_file_scan_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_file_scan_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_file_scan_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_gce_refresh_duration The duration of a GCE-SD refresh in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_gce_refresh_duration summary&lt;/span&gt;
prometheus_sd_gce_refresh_duration&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_gce_refresh_duration&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_gce_refresh_duration&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_gce_refresh_duration_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_gce_refresh_duration_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_gce_refresh_failures_total The number of GCE-SD refresh failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_gce_refresh_failures_total counter&lt;/span&gt;
prometheus_sd_gce_refresh_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_last_resource_version Last resource version from the Kubernetes API.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_last_resource_version gauge&lt;/span&gt;
prometheus_sd_kubernetes_cache_last_resource_version &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_list_duration_seconds Duration of a Kubernetes API call in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_list_duration_seconds summary&lt;/span&gt;
prometheus_sd_kubernetes_cache_list_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_cache_list_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_list_items Count of items in a list from the Kubernetes API.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_list_items summary&lt;/span&gt;
prometheus_sd_kubernetes_cache_list_items_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_cache_list_items_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_list_total Total number of list operations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_list_total counter&lt;/span&gt;
prometheus_sd_kubernetes_cache_list_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_short_watches_total Total number of short watch operations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_short_watches_total counter&lt;/span&gt;
prometheus_sd_kubernetes_cache_short_watches_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_watch_duration_seconds Duration of watches on the Kubernetes API.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_watch_duration_seconds summary&lt;/span&gt;
prometheus_sd_kubernetes_cache_watch_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_cache_watch_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_watch_events Number of items in watches on the Kubernetes API.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_watch_events summary&lt;/span&gt;
prometheus_sd_kubernetes_cache_watch_events_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_cache_watch_events_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_cache_watches_total Total number of watch operations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_cache_watches_total counter&lt;/span&gt;
prometheus_sd_kubernetes_cache_watches_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_kubernetes_events_total The number of Kubernetes events handled.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_kubernetes_events_total counter&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;add&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;endpoints&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;add&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;add&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;add&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;add&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;delete&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;endpoints&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;delete&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;delete&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;delete&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;delete&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;update&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;endpoints&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;update&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;ingress&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;update&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;node&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;update&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;pod&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_kubernetes_events_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;update&quot;&lt;/span&gt;,role&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;service&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_marathon_refresh_duration_seconds The duration of a Marathon-SD refresh in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_marathon_refresh_duration_seconds summary&lt;/span&gt;
prometheus_sd_marathon_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_marathon_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_marathon_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_marathon_refresh_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_marathon_refresh_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_marathon_refresh_failures_total The number of Marathon-SD refresh failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_marathon_refresh_failures_total counter&lt;/span&gt;
prometheus_sd_marathon_refresh_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_openstack_refresh_duration_seconds The duration of an OpenStack-SD refresh in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_openstack_refresh_duration_seconds summary&lt;/span&gt;
prometheus_sd_openstack_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_openstack_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_openstack_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_openstack_refresh_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_openstack_refresh_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_openstack_refresh_failures_total The number of OpenStack-SD scrape failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_openstack_refresh_failures_total counter&lt;/span&gt;
prometheus_sd_openstack_refresh_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_received_updates_total Total number of update events received from the SD providers.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_received_updates_total counter&lt;/span&gt;
prometheus_sd_received_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;scrape&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_triton_refresh_duration_seconds The duration of a Triton-SD refresh in seconds.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_triton_refresh_duration_seconds summary&lt;/span&gt;
prometheus_sd_triton_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_triton_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_triton_refresh_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_sd_triton_refresh_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_sd_triton_refresh_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_triton_refresh_failures_total The number of Triton-SD scrape failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_triton_refresh_failures_total counter&lt;/span&gt;
prometheus_sd_triton_refresh_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_sd_updates_total Total number of update events sent to the SD consumers.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_sd_updates_total counter&lt;/span&gt;
prometheus_sd_updates_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;scrape&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_interval_length_seconds Actual intervals between scrapes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_interval_length_seconds summary&lt;/span&gt;
prometheus_target_interval_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14.995180776&lt;/span&gt;
prometheus_target_interval_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14.996111038&lt;/span&gt;
prometheus_target_interval_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15.000072502&lt;/span&gt;
prometheus_target_interval_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15.00274162&lt;/span&gt;
prometheus_target_interval_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15.004418161&lt;/span&gt;
prometheus_target_interval_length_seconds_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;41010.099564205055&lt;/span&gt;
prometheus_target_interval_length_seconds_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;interval&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;15s&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2734&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrape_pool_reloads_failed_total Total number of failed scrape loop reloads.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrape_pool_reloads_failed_total counter&lt;/span&gt;
prometheus_target_scrape_pool_reloads_failed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrape_pool_reloads_total Total number of scrape loop reloads.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrape_pool_reloads_total counter&lt;/span&gt;
prometheus_target_scrape_pool_reloads_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrape_pool_sync_total Total number of syncs that were executed on a scrape pool.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrape_pool_sync_total counter&lt;/span&gt;
prometheus_target_scrape_pool_sync_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrape_pools_failed_total Total number of scrape pool creations that failed.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrape_pools_failed_total counter&lt;/span&gt;
prometheus_target_scrape_pools_failed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrape_pools_total Total number of scrape pool creation atttempts.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrape_pools_total counter&lt;/span&gt;
prometheus_target_scrape_pools_total &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrapes_exceeded_sample_limit_total Total number of scrapes that hit the sample limit and were rejected.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrapes_exceeded_sample_limit_total counter&lt;/span&gt;
prometheus_target_scrapes_exceeded_sample_limit_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrapes_sample_duplicate_timestamp_total Total number of samples rejected due to duplicate timestamps but different values&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrapes_sample_duplicate_timestamp_total counter&lt;/span&gt;
prometheus_target_scrapes_sample_duplicate_timestamp_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrapes_sample_out_of_bounds_total Total number of samples rejected due to timestamp falling outside of the time bounds&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrapes_sample_out_of_bounds_total counter&lt;/span&gt;
prometheus_target_scrapes_sample_out_of_bounds_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_scrapes_sample_out_of_order_total Total number of samples rejected due to not being out of the expected order&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_scrapes_sample_out_of_order_total counter&lt;/span&gt;
prometheus_target_scrapes_sample_out_of_order_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_target_sync_length_seconds Actual interval to sync the scrape pool.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_target_sync_length_seconds summary&lt;/span&gt;
prometheus_target_sync_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_target_sync_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_target_sync_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_target_sync_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_target_sync_length_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;,quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_target_sync_length_seconds_sum&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.000219783&lt;/span&gt;
prometheus_target_sync_length_seconds_count&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scrape_job&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;federate&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_template_text_expansion_failures_total The total number of template text expansion failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_template_text_expansion_failures_total counter&lt;/span&gt;
prometheus_template_text_expansion_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_template_text_expansions_total The total number of template text expansions.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_template_text_expansions_total counter&lt;/span&gt;
prometheus_template_text_expansions_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_treecache_watcher_goroutines The current number of watcher goroutines.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_treecache_watcher_goroutines gauge&lt;/span&gt;
prometheus_treecache_watcher_goroutines &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_treecache_zookeeper_failures_total The total number of ZooKeeper failures.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_treecache_zookeeper_failures_total counter&lt;/span&gt;
prometheus_treecache_zookeeper_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_blocks_loaded Number of currently loaded data blocks&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_blocks_loaded gauge&lt;/span&gt;
prometheus_tsdb_blocks_loaded &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_checkpoint_creations_failed_total Total number of checkpoint creations that failed.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_checkpoint_creations_failed_total counter&lt;/span&gt;
prometheus_tsdb_checkpoint_creations_failed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_checkpoint_creations_total Total number of checkpoint creations attempted.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_checkpoint_creations_total counter&lt;/span&gt;
prometheus_tsdb_checkpoint_creations_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_checkpoint_deletions_failed_total Total number of checkpoint deletions that failed.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_checkpoint_deletions_failed_total counter&lt;/span&gt;
prometheus_tsdb_checkpoint_deletions_failed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_checkpoint_deletions_total Total number of checkpoint deletions attempted.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_checkpoint_deletions_total counter&lt;/span&gt;
prometheus_tsdb_checkpoint_deletions_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compaction_chunk_range_seconds Final time range of chunks on their first compaction&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compaction_chunk_range_seconds histogram&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;100&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;400&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1600&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;6400&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;25600&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;102400&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;409600&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1.6384e+06&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;6.5536e+06&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.62144e+07&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_range_seconds_sum &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;.53475943e+08
prometheus_tsdb_compaction_chunk_range_seconds_count &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compaction_chunk_samples Final number of samples on their first compaction&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compaction_chunk_samples histogram&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;6&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;13.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;20.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;30.375&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;45.5625&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;68.34375&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;102.515625&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;153.7734375&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;230.66015625&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;345.990234375&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_sum &lt;span class=&quot;token number&quot;&gt;30343&lt;/span&gt;
prometheus_tsdb_compaction_chunk_samples_count &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compaction_chunk_size_bytes Final size of chunks on their first compaction&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compaction_chunk_size_bytes histogram&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;32&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;48&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;72&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;108&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;162&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;243&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;364.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;546.75&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;820.125&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1230.1875&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;103&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1845.28125&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;106&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2767.921875&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_sum &lt;span class=&quot;token number&quot;&gt;152382&lt;/span&gt;
prometheus_tsdb_compaction_chunk_size_bytes_count &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compaction_duration_seconds Duration of compaction runs&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compaction_duration_seconds histogram&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;4&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;8&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;16&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;32&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;64&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;128&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;256&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;512&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;1.250883887&lt;/span&gt;
prometheus_tsdb_compaction_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compaction_populating_block Set to 1 when a block is currently being written to the disk.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compaction_populating_block gauge&lt;/span&gt;
prometheus_tsdb_compaction_populating_block &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compactions_failed_total Total number of compactions that failed for the partition.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compactions_failed_total counter&lt;/span&gt;
prometheus_tsdb_compactions_failed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compactions_total Total number of compactions that were executed for the partition.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compactions_total counter&lt;/span&gt;
prometheus_tsdb_compactions_total &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_compactions_triggered_total Total number of triggered compactions for the partition.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_compactions_triggered_total counter&lt;/span&gt;
prometheus_tsdb_compactions_triggered_total &lt;span class=&quot;token number&quot;&gt;228&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_active_appenders Number of currently active appender transactions&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_active_appenders gauge&lt;/span&gt;
prometheus_tsdb_head_active_appenders &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_chunks Total number of chunks in the head block.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_chunks gauge&lt;/span&gt;
prometheus_tsdb_head_chunks &lt;span class=&quot;token number&quot;&gt;810&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_chunks_created_total Total number of chunks created in the head&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_chunks_created_total counter&lt;/span&gt;
prometheus_tsdb_head_chunks_created_total &lt;span class=&quot;token number&quot;&gt;957&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_chunks_removed_total Total number of chunks removed in the head&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_chunks_removed_total counter&lt;/span&gt;
prometheus_tsdb_head_chunks_removed_total &lt;span class=&quot;token number&quot;&gt;147&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_gc_duration_seconds Runtime of garbage collection in the head block.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_gc_duration_seconds summary&lt;/span&gt;
prometheus_tsdb_head_gc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_head_gc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_head_gc_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_head_gc_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0.001884575&lt;/span&gt;
prometheus_tsdb_head_gc_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_max_time Maximum timestamp of the head block. The unit is decided by the library consumer.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_max_time gauge&lt;/span&gt;
prometheus_tsdb_head_max_time &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.554792751194e+12
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_max_time_seconds Maximum timestamp of the head block.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_max_time_seconds gauge&lt;/span&gt;
prometheus_tsdb_head_max_time_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.554792751194e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_min_time Minimum time bound of the head block. The unit is decided by the library consumer.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_min_time gauge&lt;/span&gt;
prometheus_tsdb_head_min_time &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.5547824e+12
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_min_time_seconds Minimum time bound of the head block.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_min_time_seconds gauge&lt;/span&gt;
prometheus_tsdb_head_min_time_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.5547824e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_samples_appended_total Total number of appended samples.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_samples_appended_total counter&lt;/span&gt;
prometheus_tsdb_head_samples_appended_total &lt;span class=&quot;token number&quot;&gt;123185&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_series Total number of series in the head block.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_series gauge&lt;/span&gt;
prometheus_tsdb_head_series &lt;span class=&quot;token number&quot;&gt;135&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_series_created_total Total number of series created in the head&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_series_created_total counter&lt;/span&gt;
prometheus_tsdb_head_series_created_total &lt;span class=&quot;token number&quot;&gt;135&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_series_not_found_total Total number of requests for series that were not found.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_series_not_found_total counter&lt;/span&gt;
prometheus_tsdb_head_series_not_found_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_series_removed_total Total number of series removed in the head&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_series_removed_total counter&lt;/span&gt;
prometheus_tsdb_head_series_removed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_truncations_failed_total Total number of head truncations that failed.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_truncations_failed_total counter&lt;/span&gt;
prometheus_tsdb_head_truncations_failed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_head_truncations_total Total number of head truncations attempted.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_head_truncations_total counter&lt;/span&gt;
prometheus_tsdb_head_truncations_total &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_lowest_timestamp Lowest timestamp value stored in the database. The unit is decided by the library consumer.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_lowest_timestamp gauge&lt;/span&gt;
prometheus_tsdb_lowest_timestamp &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.55477867699e+12
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_lowest_timestamp_seconds Lowest timestamp value stored in the database.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_lowest_timestamp_seconds gauge&lt;/span&gt;
prometheus_tsdb_lowest_timestamp_seconds &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;.55477867699e+09
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_reloads_failures_total Number of times the database failed to reload block data from disk.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_reloads_failures_total counter&lt;/span&gt;
prometheus_tsdb_reloads_failures_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_reloads_total Number of times the database reloaded block data from disk.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_reloads_total counter&lt;/span&gt;
prometheus_tsdb_reloads_total &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_size_retentions_total The number of times that blocks were deleted because the maximum number of bytes was exceeded.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_size_retentions_total counter&lt;/span&gt;
prometheus_tsdb_size_retentions_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_storage_blocks_bytes The number of bytes that are currently used for local storage by all blocks.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_storage_blocks_bytes gauge&lt;/span&gt;
prometheus_tsdb_storage_blocks_bytes &lt;span class=&quot;token number&quot;&gt;165474&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_symbol_table_size_bytes Size of symbol table on disk (in bytes)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_symbol_table_size_bytes gauge&lt;/span&gt;
prometheus_tsdb_symbol_table_size_bytes &lt;span class=&quot;token number&quot;&gt;1807&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_time_retentions_total The number of times that blocks were deleted because the maximum time limit was exceeded.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_time_retentions_total counter&lt;/span&gt;
prometheus_tsdb_time_retentions_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_tombstone_cleanup_seconds The time taken to recompact blocks to remove tombstones.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_tombstone_cleanup_seconds histogram&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.005&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.01&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.025&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.05&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.25&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;10&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_bucket&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;le&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;+Inf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_tombstone_cleanup_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_vertical_compactions_total Total number of compactions done on overlapping blocks.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_vertical_compactions_total counter&lt;/span&gt;
prometheus_tsdb_vertical_compactions_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_wal_completed_pages_total Total number of completed pages.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_wal_completed_pages_total counter&lt;/span&gt;
prometheus_tsdb_wal_completed_pages_total &lt;span class=&quot;token number&quot;&gt;42&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_wal_corruptions_total Total number of WAL corruptions.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_wal_corruptions_total counter&lt;/span&gt;
prometheus_tsdb_wal_corruptions_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_wal_fsync_duration_seconds summary&lt;/span&gt;
prometheus_tsdb_wal_fsync_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_wal_fsync_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_wal_fsync_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_wal_fsync_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_wal_fsync_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_wal_page_flushes_total Total number of page flushes.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_wal_page_flushes_total counter&lt;/span&gt;
prometheus_tsdb_wal_page_flushes_total &lt;span class=&quot;token number&quot;&gt;5519&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_wal_truncate_duration_seconds Duration of WAL truncation.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_wal_truncate_duration_seconds summary&lt;/span&gt;
prometheus_tsdb_wal_truncate_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.5&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_wal_truncate_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.9&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_wal_truncate_duration_seconds&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;quantile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.99&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; NaN
prometheus_tsdb_wal_truncate_duration_seconds_sum &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
prometheus_tsdb_wal_truncate_duration_seconds_count &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_wal_truncations_failed_total Total number of WAL truncations that failed.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_wal_truncations_failed_total counter&lt;/span&gt;
prometheus_tsdb_wal_truncations_failed_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP prometheus_tsdb_wal_truncations_total Total number of WAL truncations attempted.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE prometheus_tsdb_wal_truncations_total counter&lt;/span&gt;
prometheus_tsdb_wal_truncations_total &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP promhttp_metric_handler_requests_in_flight Current number of scrapes being served.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE promhttp_metric_handler_requests_in_flight gauge&lt;/span&gt;
promhttp_metric_handler_requests_in_flight &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# HELP promhttp_metric_handler_requests_total Total number of scrapes by HTTP status code.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# TYPE promhttp_metric_handler_requests_total counter&lt;/span&gt;
promhttp_metric_handler_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;200&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
promhttp_metric_handler_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;500&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
promhttp_metric_handler_requests_total&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;code&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;503&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;prometheus--h-id_app_prometheus_help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheus--h-id_app_prometheus_help&quot; aria-label=&quot;prometheus  h id_app_prometheus_help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;prometheus -h {#ID_APP_PROMETHEUS_HELP}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;prometheus -h
usage: prometheus [&amp;lt;flags&gt;]

The Prometheus monitoring server

Flags:
  -h, --help                     Show context-sensitive help (also try --help-long and --help-man).
      --version                  Show application version.
      --config.file=&quot;prometheus.yml&quot;
                                 Prometheus configuration file path.
      --web.listen-address=&quot;0.0.0.0:9090&quot;
                                 Address to listen on for UI, API, and telemetry.
      --web.read-timeout=5m      Maximum duration before timing out read of the request, and closing idle connections.
      --web.max-connections=512  Maximum number of simultaneous connections.
      --web.external-url=&amp;lt;URL&gt;   The URL under which Prometheus is externally reachable (for example, if Prometheus is served via a reverse proxy). Used for generating
                                 relative and absolute links back to Prometheus itself. If the URL has a path portion, it will be used to prefix all HTTP endpoints
                                 served by Prometheus. If omitted, relevant URL components will be derived automatically.
      --web.route-prefix=&amp;lt;path&gt;  Prefix for the internal routes of web endpoints. Defaults to path of --web.external-url.
      --web.user-assets=&amp;lt;path&gt;   Path to static asset directory, available at /user.
      --web.enable-lifecycle     Enable shutdown and reload via HTTP request.
      --web.enable-admin-api     Enable API endpoints for admin control actions.
      --web.console.templates=&quot;consoles&quot;
                                 Path to the console template directory, available at /consoles.
      --web.console.libraries=&quot;console_libraries&quot;
                                 Path to the console library directory.
      --web.page-title=&quot;Prometheus Time Series Collection and Processing Server&quot;
                                 Document title of Prometheus instance.
      --storage.tsdb.path=&quot;data/&quot;
                                 Base path for metrics storage.
      --storage.tsdb.retention=STORAGE.TSDB.RETENTION
                                 [DEPRECATED] How long to retain samples in storage. This flag has been deprecated, use &quot;storage.tsdb.retention.time&quot; instead
      --storage.tsdb.retention.time=STORAGE.TSDB.RETENTION.TIME
                                 How long to retain samples in storage. When this flag is set it overrides &quot;storage.tsdb.retention&quot;. If neither this flag nor
                                 &quot;storage.tsdb.retention&quot; nor &quot;storage.tsdb.retention.size&quot; is set, the retention time defaults to 15d.
      --storage.tsdb.retention.size=STORAGE.TSDB.RETENTION.SIZE
                                 [EXPERIMENTAL] Maximum number of bytes that can be stored for blocks. Units supported: KB, MB, GB, TB, PB. This flag is experimental and
                                 can be changed in future releases.
      --storage.tsdb.no-lockfile
                                 Do not create lockfile in data directory.
      --storage.tsdb.allow-overlapping-blocks
                                 [EXPERIMENTAL] Allow overlapping blocks which in-turn enables vertical compaction and vertical query merge.
      --storage.remote.flush-deadline=&amp;lt;duration&gt;
                                 How long to wait flushing sample on shutdown or config reload.
      --storage.remote.read-sample-limit=5e7
                                 Maximum overall number of samples to return via the remote read interface, in a single query. 0 means no limit.
      --storage.remote.read-concurrent-limit=10
                                 Maximum number of concurrent remote read calls. 0 means no limit.
      --rules.alert.for-outage-tolerance=1h
                                 Max time to tolerate prometheus outage for restoring &apos;for&apos; state of alert.
      --rules.alert.for-grace-period=10m
                                 Minimum duration between alert and restored &apos;for&apos; state. This is maintained only for alerts with configured &apos;for&apos; time greater than
                                 grace period.
      --rules.alert.resend-delay=1m
                                 Minimum amount of time to wait before resending an alert to Alertmanager.
      --alertmanager.notification-queue-capacity=10000
                                 The capacity of the queue for pending Alertmanager notifications.
      --alertmanager.timeout=10s
                                 Timeout for sending alerts to Alertmanager.
      --query.lookback-delta=5m  The delta difference allowed for retrieving metrics during expression evaluations.
      --query.timeout=2m         Maximum time a query may take before being aborted.
      --query.max-concurrency=20
                                 Maximum number of queries executed concurrently.
      --query.max-samples=50000000
                                 Maximum number of samples a single query can load into memory. Note that queries will fail if they would load more samples than this
                                 into memory, so this also limits the number of samples a query can return.
      --web.cors.origin=&quot;.*&quot;     Regex for CORS origin. It is fully anchored. Eg. &apos;https?://(domain1|domain2)\.com&apos;
      --log.level=info           Only log messages with the given severity or above. One of: [debug, info, warn, error]
      --log.format=logfmt        Output format of log messages. One of: [logfmt, json]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;comparison-to-alternatives-id_app_cta&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#comparison-to-alternatives-id_app_cta&quot; aria-label=&quot;comparison to alternatives id_app_cta permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;COMPARISON TO ALTERNATIVES {#ID_APP_CTA}&lt;/h2&gt;
&lt;h3 id=&quot;prometheus-vs-graphite&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheus-vs-graphite&quot; aria-label=&quot;prometheus vs graphite permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Prometheus vs. Graphite&lt;/h3&gt;
&lt;h4 id=&quot;scope&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#scope&quot; aria-label=&quot;scope permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Scope&lt;/h4&gt;
&lt;p&gt;Graphite专注于被动的时序数据库加上查询语言加上展示界面功能。任何其他的功能点都由外部组件提供。&lt;/p&gt;
&lt;p&gt;Prometheus是一个全面的监控和趋势追踪系统，包含了基于时序数据库的内建的主动式获取、存储、查询、图像化以及报警功能。在Prometheus中定义了何谓正确的行为（哪些终端应该存在，哪些时序模式意味着错误，等等），并能够主动查找错误。&lt;/p&gt;
&lt;h4 id=&quot;data-model&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#data-model&quot; aria-label=&quot;data model permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Data model&lt;/h4&gt;
&lt;p&gt;Graphite在命名的时序字段内存储数字化的采样值，这和Prometheus类似。然而，Prometheus的metadata模型更丰富：Graphite的metric由&lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt;分隔的组件组成，并隐式编码维度，而Prometheus则显示地将维度编码为键值对，这被称为labels，并附加在metric上。这使得使用labels进行过滤、分组、匹配更为简单。&lt;/p&gt;
&lt;p&gt;更进一步，特别当Graphite与StatsD结合使用的时候，通常会仅存储所有被监控实例的聚合数据，而不是将实例作为一个维度进行保存，并能够深入挖掘单独的有问题实例。&lt;/p&gt;
&lt;p&gt;举例来说，存储响应码为&lt;code class=&quot;language-text&quot;&gt;500&lt;/code&gt;、方法为&lt;code class=&quot;language-text&quot;&gt;POST&lt;/code&gt;、发送到API服务器上&lt;code class=&quot;language-text&quot;&gt;/tracks&lt;/code&gt;端点的HTTP请求数量，一般在Graphite/StatsD会存储为：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;stats.api-server.tracks.post.500 -&gt; 93&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在Prometheus中，相同的数据则会被编码为（假设有三个API服务器实例）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;api_server_http_requests_total{method=&quot;POST&quot;,handler=&quot;/tracks&quot;,status=&quot;500&quot;,instance=&quot;&amp;lt;sample1&gt;&quot;} -&gt; 34
api_server_http_requests_total{method=&quot;POST&quot;,handler=&quot;/tracks&quot;,status=&quot;500&quot;,instance=&quot;&amp;lt;sample2&gt;&quot;} -&gt; 28
api_server_http_requests_total{method=&quot;POST&quot;,handler=&quot;/tracks&quot;,status=&quot;500&quot;,instance=&quot;&amp;lt;sample3&gt;&quot;} -&gt; 31&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4 id=&quot;storage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#storage&quot; aria-label=&quot;storage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Storage&lt;/h4&gt;
&lt;p&gt;Graphite将时序数据以Whisper格式存储在本地磁盘上，这是一个RDD-style的数据库，要求采样数据以固定间隔存储进入。每个时序数据被存储为单独的文件，而每隔一段固定时长，新的采样数据则会覆盖旧的数据。&lt;/p&gt;
&lt;p&gt;Prometheus也会在本地磁盘按照每个时序数据创建一个本地文件，但允许采样数据按随机的时间间隔进行存储，只要采样行为和规则评估行为发生。由于新的数据会被简单附加在后面，旧的数据会被保存不定时长。Prometheus在处理短存活周期、频繁变动的时序数据时也能很好工作。&lt;/p&gt;
&lt;h4 id=&quot;summary&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#summary&quot; aria-label=&quot;summary permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Summary&lt;/h4&gt;
&lt;p&gt;Prometheus提供了更丰富的数据模型和查询语言，此外还更容易运行并整合进你的环境。但如果你希望一个集群化的解决方案，并希望能长期保存历史数据，那么Graphite会是一个更好的选择。&lt;/p&gt;
&lt;h3 id=&quot;prometheus-vs-influxdb&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheus-vs-influxdb&quot; aria-label=&quot;prometheus vs influxdb permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Prometheus vs. InfluxDB&lt;/h3&gt;
&lt;p&gt;InfluxDB是一个开源的时序数据库，并有一个可扩展和可集群化的商业选项。InfluxDB项目是在Prometheus的研发开始之后一年才被release出来的，因此我们之前无法将其作为一个竞品进行考虑。当然，Prometheus和InfluxDB之间还是有显著区别的，并且双方系统都是朝着不同的用例进行设计实施的。&lt;/p&gt;
&lt;h4 id=&quot;scope-1&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#scope-1&quot; aria-label=&quot;scope 1 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Scope&lt;/h4&gt;
&lt;p&gt;为了公平起见，我们还必须将Kapacitor和InfluxDB一起考虑，将这两者组合起来之后，他们解决的是和Prometheus以及Alertmanager相同的问题领域。&lt;/p&gt;
&lt;p&gt;在scope方面，InfluxDB和Graphite对Prometheus的差异是类似的。除此之外，InfluxDB提供了连续查询（continuous queries），和Prometheus的记录规则（recording rules）是等价的。&lt;/p&gt;
&lt;p&gt;Kapacitor的领域则是Prometheus记录规则（recording rules）、报警规则（alerting rules）以及Alertmanager的通知功能的综合。Prometheus提供了相对来说更强大的查询语言与图像化、报警功能。Prometheus Alertmanager额外提供了分组、去重以及静默功能。&lt;/p&gt;
&lt;h4 id=&quot;data-model--storage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#data-model--storage&quot; aria-label=&quot;data model  storage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Data model / storage&lt;/h4&gt;
&lt;p&gt;和Prometheus类似，InfluxDB数据模型也使用键值对作为labels，在InfluxDB中这被称为tags。此外，InfluxDB拥有一个二级labels被称为fields，这个fields在使用上更受限。InfluxDB支持纳秒级别的timestamps，以及float64、int64、bool、字符串，这几种数据类型。Prometheus，根据约定，支持float64数据类型以及支持受限的字符串，以及毫秒级别的timestamps。&lt;/p&gt;
&lt;p&gt;INfulxDB使用带有预写日志的多样的 log-structured merge tree 来进行存储。这比Prometheus的每种时间序列仅追加的文件方案更加适合进行事件日志。&lt;/p&gt;
&lt;p&gt;日志和Metrics以及图，描述了事件日志和Metrics记录之间的区别。&lt;/p&gt;
&lt;h4 id=&quot;architecture&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#architecture&quot; aria-label=&quot;architecture permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Architecture&lt;/h4&gt;
&lt;p&gt;Prometheus服务器每一个都是单独运行的，与其他服务器分离，并仅依赖它们的本地存储来进行核心功能服务：抓取数据、规则处理，以及警告。开源版本的InfluxDB也是类似的。&lt;/p&gt;
&lt;p&gt;商业版的InfluxDB提供了，按设计所述，一个分布式存储集群，同时有许多集群节点处理存储和查询。&lt;/p&gt;
&lt;p&gt;这意味着商业版的InfluxDB更容易水平扩展，但这也意味着必须一开始就处理一个复杂的分布式存储系统。Prometheus更容易使用，但在某个时间点将必须手动地根据扩展边界来拓展服务器，比如说根据产品、服务、数据中心，或类似的概念。单独的服务器（可以平行运作）也可以给你更好的可靠性以及错误隔离。&lt;/p&gt;
&lt;p&gt;Kapacitor的开源release并没有内建的针对规则、警告、通知的分布式/冗余选项。开源版本可以通过用户手动分割的方式进行扩展，类似于Prometheus。Influx提供了企业版本的Kapacitor，支持高可用/冗余的告警系统。&lt;/p&gt;
&lt;p&gt;Prometheus以及Alertmanager按约定提供了一个完全开源的冗余选项，通过运行冗余的Prometheus复制（replicas），以及使用Alertmanager的高可用模式。&lt;/p&gt;
&lt;h4 id=&quot;summary-1&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#summary-1&quot; aria-label=&quot;summary 1 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Summary&lt;/h4&gt;
&lt;p&gt;Prometheus和InfluxDB系统有诸多相似之处。都具有labels（在InfluxDB里被称为tags）来支持高效的多维度metrics。都使用相同的数据压缩算法。都有扩展集成。都有钩子允许你拓展它们的功能，比如说在统计工具中分析数据或进行自动化处理等。&lt;/p&gt;
&lt;p&gt;InfluxDB做的更好的地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用InfluxDB系统进行事件日志处理&lt;/li&gt;
&lt;li&gt;商业版本提供了系统集群化，对长期的数据存储来说也是更好的选择&lt;/li&gt;
&lt;li&gt;在多个复制之间保持数据的最终一致性&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prometheus做的更好的地方：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用Prometheus系统来进行metrics监控&lt;/li&gt;
&lt;li&gt;更强大的查询语言、报警以及通知功能&lt;/li&gt;
&lt;li&gt;高可用以及图像化的运行时长以及报警&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;InfluxDB是由单一商业公司维护的，其模式为：核心功能开源，提供会员功能比如说闭源的集群功能、托管功能以及支持。Prometheus是一个完全开源且独立的项目，由一系列公司及独立个体进行维护，部分其中的成员也提供商业服务及支持。&lt;/p&gt;
&lt;h3 id=&quot;prometheus-vs-opentsdb&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheus-vs-opentsdb&quot; aria-label=&quot;prometheus vs opentsdb permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Prometheus vs. OpenTSDB&lt;/h3&gt;
&lt;p&gt;OpenTSDB是一个分布式的时序数据库，基于Hadoop以及HBase。&lt;/p&gt;
&lt;h4 id=&quot;scope-2&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#scope-2&quot; aria-label=&quot;scope 2 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Scope&lt;/h4&gt;
&lt;p&gt;在scope方面，其与Prometheus的差别和Graphite一样。&lt;/p&gt;
&lt;h4 id=&quot;data-model-1&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#data-model-1&quot; aria-label=&quot;data model 1 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Data model&lt;/h4&gt;
&lt;p&gt;OpenTSDB的数据模型基本上和Prometheus是一致的：时序由一系列任意的键值对进行识别（OpenTSDB中的tags就是Prometheus中的labels）。针对一个metrics的数据是存储在一起的，限制metrics的基数。也有些微的不同：Prometheus允许label值中存在任意的字符，而OpenTSDB则更具有限制性。OpenTSDB也缺乏一个查询语言，仅允许通过API进行简单的聚合以及数学查询。&lt;/p&gt;
&lt;h4 id=&quot;storage-1&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#storage-1&quot; aria-label=&quot;storage 1 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Storage&lt;/h4&gt;
&lt;p&gt;OpenTSDB的存储是基于Hadoop以及HBase进行实现的。这意味着对OpenTSDB进行水平扩展是容易的，但你必须接受从一开始就运作一个Hadoop/HBase集群的复杂性。&lt;/p&gt;
&lt;p&gt;Prometheus作为初始是非常容易直接开始运作的，但当单节点已经无法承载的时候则需要手动进行进行分片。&lt;/p&gt;
&lt;h4 id=&quot;summary-2&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#summary-2&quot; aria-label=&quot;summary 2 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Summary&lt;/h4&gt;
&lt;p&gt;Prometheus提供了更丰富的查询语言，能处理更高的metrics技术，并胜任一个完整的监控系统。如果你已经有运行中的Hadoop集群，且希望拥有一个长期的数据存储更胜于之前所述的优点，那OpenTSDB就是更好的选择。&lt;/p&gt;
&lt;h3 id=&quot;prometheus-vs-nagios&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheus-vs-nagios&quot; aria-label=&quot;prometheus vs nagios permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Prometheus vs. Nagios&lt;/h3&gt;
&lt;p&gt;Nagios是由NetSaint公司自1990年代开始发起的一个监控系统。&lt;/p&gt;
&lt;h4 id=&quot;scope-3&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#scope-3&quot; aria-label=&quot;scope 3 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Scope&lt;/h4&gt;
&lt;p&gt;Nagios是一个主要基于已经存在的脚本代码进行告警的系统。这些被称为&lt;code class=&quot;language-text&quot;&gt;checks&lt;/code&gt;。可以针对单独的告警进行静默处理，然而并没有分组、路由以及去重。&lt;/p&gt;
&lt;p&gt;Nagios拥有大量的插件。举例来说，使用几K的perfData插件就能允许向一个时序数据库（例如Graphite）输出数据或者使用NRPE就可以在远程机器上运行checks。&lt;/p&gt;
&lt;h4 id=&quot;data-model-2&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#data-model-2&quot; aria-label=&quot;data model 2 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Data model&lt;/h4&gt;
&lt;p&gt;Nagios是基于主机的。每个主机可以有一个或多个服务，然后每个服务可以运行一个check。&lt;/p&gt;
&lt;p&gt;并不存在labels的概念或一个查询语言。&lt;/p&gt;
&lt;h4 id=&quot;storage-2&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#storage-2&quot; aria-label=&quot;storage 2 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Storage&lt;/h4&gt;
&lt;p&gt;Nagios并没有存储，只有状态check。有插件可以存储数据来进行图形化。&lt;/p&gt;
&lt;h4 id=&quot;architecture-1&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#architecture-1&quot; aria-label=&quot;architecture 1 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Architecture&lt;/h4&gt;
&lt;p&gt;Nagios服务器是独立运作的。所有的checks都是通过配置文件来进行管理的。&lt;/p&gt;
&lt;h4 id=&quot;summary-3&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#summary-3&quot; aria-label=&quot;summary 3 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Summary&lt;/h4&gt;
&lt;p&gt;Nagios适合小型的静态的系统的基本监控（基本上是黑盒状态）。&lt;/p&gt;
&lt;p&gt;如果你希望拥有可调整的白盒监控，或拥有一个动态的基于云的环境，那么Prometheus是更好的选择。&lt;/p&gt;
&lt;h3 id=&quot;prometheus-vs-sensu&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#prometheus-vs-sensu&quot; aria-label=&quot;prometheus vs sensu permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Prometheus vs. Sensu&lt;/h3&gt;
&lt;p&gt;Sensu是一个可编组的监控管线，可以复用已经存在的Nagios checks。&lt;/p&gt;
&lt;h4 id=&quot;scope-4&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#scope-4&quot; aria-label=&quot;scope 4 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Scope&lt;/h4&gt;
&lt;p&gt;在scope方面其和Nagios是一致的。&lt;/p&gt;
&lt;p&gt;由客户端socket来支持将临时的check结果推送到Sensu。&lt;/p&gt;
&lt;h4 id=&quot;data-model-3&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#data-model-3&quot; aria-label=&quot;data model 3 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Data model&lt;/h4&gt;
&lt;p&gt;Sensu的数据模型和Nagios一致。&lt;/p&gt;
&lt;h4 id=&quot;storage-3&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#storage-3&quot; aria-label=&quot;storage 3 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Storage&lt;/h4&gt;
&lt;p&gt;Sensu使用Redis来持久化监控数据，包括了Sensu的客户端注册，check结果，check执行历史，以及当前的事件数据。&lt;/p&gt;
&lt;h4 id=&quot;architecture-2&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#architecture-2&quot; aria-label=&quot;architecture 2 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Architecture&lt;/h4&gt;
&lt;p&gt;Sensu有一系列的组件。它使用RabbitMQ来传输数据，Redis来处理当前状态，以及一个单独的服务器来处理访问请求。&lt;/p&gt;
&lt;p&gt;一个Sensu部署的所有组件（RabbitMQ、Redis以及Sensu 服务器/API）可以做成集群化来支持高可用、冗余配置。&lt;/p&gt;
&lt;h4 id=&quot;summary-4&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#summary-4&quot; aria-label=&quot;summary 4 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Summary&lt;/h4&gt;
&lt;p&gt;如果你手头有一个存在的Nagios，且你希望扩展它，或者希望利用Sensu的自动化注册功能，那么Sensu是一个好选择。&lt;/p&gt;
&lt;p&gt;如果你希望进行白盒监控，或希望有动态的基于云的环境，那么Prometheus是一个好的选择。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[也谈996]]></title><link>https://xenojoshua.com/posts/2019/04/996</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/04/996</guid><pubDate>Fri, 05 Apr 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#996%E7%9A%84%E6%9C%AC%E8%B4%A8&quot;&gt;996的本质&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%95%E8%B0%93%E4%BA%BA%E6%89%8D&quot;&gt;何谓人才&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%90%86%E8%A7%A3996&quot;&gt;理解996&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BD%A0%E5%BA%94%E8%AF%A5%E5%81%9A%E4%BB%80%E4%B9%88&quot;&gt;你应该做什么&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;996的本质&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#996%E7%9A%84%E6%9C%AC%E8%B4%A8&quot; aria-label=&quot;996的本质 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;996的本质&lt;/h1&gt;
&lt;p&gt;最近996这个事情因为&lt;a href=&quot;https://github.com/996icu/996.ICU&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;996icu/996.ICU&lt;/a&gt;快速热门起来，作为同行我当年也遭遇过985（当然没996那么惨），因此很清楚这种文化带来的破坏作用。本来其实并没有什么想法要对这个热点做一点感悟笔记的，毕竟我是悲观主义者，对这世道甚至是人类的未来都不看好，理性的、熟悉历史的人差不多都应该是这个状态。读读历史可以看到人类并没有进步，读读阮一峰的&lt;a href=&quot;https://survivor.ruanyifeng.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;未来世界的幸存者&lt;/a&gt;可以看到人类也没有什么未来。所以996这种，再正常不过了，无非就是山崩泥石流里的一颗小石子，对小石子还有什么好评论的呢，是吧？&lt;/p&gt;
&lt;p&gt;但撇开单纯的劳动者权力这种点，放宽到一个个体的人和公司的经营，我倒是有点想法真的觉得应该记录下来。&lt;/p&gt;
&lt;p&gt;我的观点是：其实我还蛮理解这些资本主义老板的，996的本质，在于&lt;code class=&quot;language-text&quot;&gt;符合要求的劳动力不足&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;何谓人才&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E4%BD%95%E8%B0%93%E4%BA%BA%E6%89%8D&quot; aria-label=&quot;何谓人才 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;何谓人才&lt;/h1&gt;
&lt;p&gt;往大了说，开过公司的人，往小了说，带过团队的人，都知道，现代的高精尖公司的关键生产要素不再是百年前的地皮、水电煤、能源这样的物质资源，而是&lt;code class=&quot;language-text&quot;&gt;人才&lt;/code&gt;，亦即所谓的&lt;code class=&quot;language-text&quot;&gt;团队&lt;/code&gt;。煤老板有钱，开个公司，败；投资人有钱，投个公司，烂。为什么？因为没有团队。没有有能力的人，就没有战斗力。市场上招聘，能找到的都是生物学上的人，而不是&lt;code class=&quot;language-text&quot;&gt;人才&lt;/code&gt;，也就是我刚才说的&lt;code class=&quot;language-text&quot;&gt;符合要求的劳动力&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;在我看来，软件公司里的人才，要的其实不是&lt;code class=&quot;language-text&quot;&gt;技术&lt;/code&gt;，而是&lt;code class=&quot;language-text&quot;&gt;解决问题的能力&lt;/code&gt;。这里面有什么差别呢？其实差别很大。大部分的软件从业者都觉得，我只要技术，我就能找到好的工作，实际上并非如此。技术和能力的关系，举个例子，就像是一张死的图纸和从图纸生产产品的之间的关系。有图纸（技术完备），但从图纸到产品，当中还有很多难点很多环节需要去攻克，这时候需要做很多事情。零件哪里来？如何做好零件的品控？组装的车床哪里来？运作车床的厂房和能源哪里来？其中甚至可以说是千山万水。&lt;/p&gt;
&lt;p&gt;光有&lt;code class=&quot;language-text&quot;&gt;技术&lt;/code&gt;其实一点用都没有。商业公司需要的是产品，而制作产品要很多能力：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;划分目标：如何将产品的最终目标分割成一个个小的可实现的节点&lt;/li&gt;
&lt;li&gt;做好管理：如何正确估时进行工作规划，让不同的部门小组之间的规划能够协同起来&lt;/li&gt;
&lt;li&gt;懂得学习：遇到不知道的东西，能不能及时自学攻克难关，并很快应用到生产中&lt;/li&gt;
&lt;li&gt;善于沟通：产品永远不是由一个人完成，人和人、团队和团队之间如何协调协作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外还有很多很多。&lt;/p&gt;
&lt;p&gt;这也是常说的死读书和能做事两种人的区别。我常和下属说，不要轻视你平时在做的工作，能把CRUD工作做到完善都不是一个普通程序员能轻易做到的。同样做一个简单的业务逻辑模块，有的人可以做好编码规范、写好注释、做好文档、编写测试脚本，做到与之对接的其他协作者感叹其尽善尽美；而有的人就可以做到一团糟糕什么都出错，让后续交接的人一头雾水。&lt;/p&gt;
&lt;p&gt;大部分的程序员并不懂这一点。我以前有一个下属，也算是名校毕业，计算机技术和算法等基础都很扎实，但工作上的很多细节点还是做的不够好，平时code review之类的，我也经常对他进行指导。后来有一天他提出离职，想回家学几个月的人工智能算法，以后争取做这方面的工作。我说，你有这样的志向我觉得很好，祝愿你今后能在人工智能这块学到知识，进入大厂做出成绩。但是，我还是建议你在这个团队继续锻炼下，至少做到你平时的工作让我没有话说。如果你今后在做事的细节方面仍旧和现在一样的话，即便你算法方面多出色，你做出来的东西，仍旧是不能让人放心的。读几个月书，看懂所有算法，就能把事情做好做对了？这还是没理解什么是&lt;code class=&quot;language-text&quot;&gt;知识&lt;/code&gt;什么是&lt;code class=&quot;language-text&quot;&gt;能力&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;现如今的技术发展实在是太快了，热门的东西一直都在更迭，我刚从业的时候是J2EE，后来PHP热门，再后来，Flash、Cocos2dx、iOS、Android，等等。如果只看&lt;code class=&quot;language-text&quot;&gt;技术&lt;/code&gt;，那是不是很多人才都过气了？当然不是。就像使用英语还是法语还是汉语写一本小说，本质在于能不能写好小说，而不在于使用的语言是什么。技术这种东西，只要掌握了软件工程的本质，再辅以强大的自学能力，再新奇的东西也就是一个上手时间的问题，让&lt;code class=&quot;language-text&quot;&gt;有能力的人才&lt;/code&gt;来做，最后还是能做得很好。&lt;/p&gt;
&lt;h1 id=&quot;理解996&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%90%86%E8%A7%A3996&quot; aria-label=&quot;理解996 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;理解996&lt;/h1&gt;
&lt;p&gt;所以回过头来我们再来看996，为什么大厂都喜欢996？因为能满足&lt;code class=&quot;language-text&quot;&gt;人才&lt;/code&gt;需求的从业者实在是太少，而要从那么多自然人当中筛选出合适的人选培养，并组建&lt;code class=&quot;language-text&quot;&gt;团队&lt;/code&gt;，对于一个公司来说成本太高，特别是超大型的软件公司。要提升生产力，老板有两个选择：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;花大量时间大量代价，真正把公司的管理工作做好，把团队压缩下来，把有能力的人留住，做类似&lt;code class=&quot;language-text&quot;&gt;精实创业（Lean Startup）&lt;/code&gt;在做的事情&lt;/li&gt;
&lt;li&gt;野蛮地延长工作时间，即便效率更低，人员流动性更大，生产力总是有提升的&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你看看，所以大公司只能选后者，其来自有。反过来说，当你成为头部的&lt;code class=&quot;language-text&quot;&gt;人才&lt;/code&gt;，想象下，是不是路就宽阔了很多。所以996我从来不担心，当你有能力了，你自然就多了很多选择。&lt;/p&gt;
&lt;h1 id=&quot;你应该做什么&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E4%BD%A0%E5%BA%94%E8%AF%A5%E5%81%9A%E4%BB%80%E4%B9%88&quot; aria-label=&quot;你应该做什么 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;你应该做什么&lt;/h1&gt;
&lt;p&gt;放下奶头乐，放下名为&lt;code class=&quot;language-text&quot;&gt;努力工作&lt;/code&gt;实则&lt;code class=&quot;language-text&quot;&gt;放弃思考&lt;/code&gt;的麻醉剂，睁开闭起来的眼睛，一步一个脚印做好自己的能力提升。以我个人的经验，每天做一个小的笔记，把每天做的事情尽量详细记录下来，晚上都过一遍，找找自己有没有能力的提升，每日自省，如果没有，就要找方法挤出时间来做对提升自己有益的事情。每天一回顾，每周一大回顾，按周期给自己制定目标，并慢慢实现之。所谓逆水行舟，人生在世没有轻松的方法能让你活得更好，你每天轻松，那就长期悲剧，每天痛苦，那就长期顺利，就这么简单。&lt;/p&gt;
&lt;p&gt;共勉。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Debug]]></title><link>https://xenojoshua.com/posts/2019/03/golang-debug</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/03/golang-debug</guid><pubDate>Wed, 27 Mar 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85&quot;&gt;2. 安装&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E4%BD%BF%E7%94%A8&quot;&gt;2. 使用&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-cli&quot;&gt;3. CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#dlv-help-id_app_help&quot;&gt;dlv help {#ID_APP_HELP}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dlv-help-id_app_dlv_help&quot;&gt;(dlv) help {#ID_APP_DLV_HELP}&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;本文是Go语言系列文章&lt;a href=&quot;/2019/02/golang-note/&quot;&gt;Golang Notes&lt;/a&gt;的其中一篇，完整的文章列表请去总章查看。&lt;/p&gt;
&lt;p&gt;Go语言的Debug工具对于一直写高级语言的程序员来说有点陌生，而对于写C常年和GDB打交道的程序员来说，则非常熟悉。&lt;/p&gt;
&lt;h1 id=&quot;2-安装&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%AE%89%E8%A3%85&quot; aria-label=&quot;2 安装 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 安装&lt;/h1&gt;
&lt;p&gt;MAC下的官方安装教程：&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/installation/osx/install.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Installation on OSX&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;环境完备的情况下只要直接使用go的下载命令即可：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go get -u github.com/go-delve/delve/cmd/dlv&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果没有设置过&lt;code class=&quot;language-text&quot;&gt;$GOPATH&lt;/code&gt;的话，软件包会安装在&lt;code class=&quot;language-text&quot;&gt;~/go&lt;/code&gt;下。然后需要把&lt;code class=&quot;language-text&quot;&gt;~/go/bin&lt;/code&gt;加入到&lt;code class=&quot;language-text&quot;&gt;$PATH&lt;/code&gt;里，就可以全局使用这个debug工具了。&lt;/p&gt;
&lt;p&gt;MAC下使用的时候可能遇到如下问题：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ dlv debug goroutine.go
could not launch process: debugserver or lldb-server not found: install XCode&apos;s command line tools or lldb-server&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;需要重新安装xcode的命令行工具：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ xcode-select --install&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完成后即可正常使用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ dlv debug goroutine.go
Type &apos;help&apos; for list of commands.
(dlv)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2-使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;2 使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 使用&lt;/h1&gt;
&lt;p&gt;dlv可以以两种模式进行运行：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;API模式：
&lt;ul&gt;
&lt;li&gt;暴露API接口，提供给其他IDE等工具，提供协同Debug的能力&lt;/li&gt;
&lt;li&gt;此外也可以使用这个模式进行远程debug&lt;/li&gt;
&lt;li&gt;文档入口在：&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/api/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delve/Documentation/api/README.md&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;CLI模式：
&lt;ul&gt;
&lt;li&gt;常规的命令行下直接进入交互界面，进行debug&lt;/li&gt;
&lt;li&gt;文档入口在：&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/cli/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delve/Documentation/cli/README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;通过交互命令界面的help是最直接也最贴合版本的文档获取方式：&lt;a href=&quot;#ID_APP_DLV_HELP&quot;&gt;(dlv) help&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-cli&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-cli&quot; aria-label=&quot;3 cli permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. CLI&lt;/h1&gt;
&lt;p&gt;命令行下使用dlv首先需要了解dlv这个命令本身的使用方法：&lt;a href=&quot;#ID_APP_HELP&quot;&gt;dlv help&lt;/a&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;attach：附到一个正在运行的线程上，这个在生产环境上比较常见&lt;/li&gt;
&lt;li&gt;connect：把自己作为客户端，连接到远程debug进程上&lt;/li&gt;
&lt;li&gt;core：检查一个核心导出文件（core dump）&lt;/li&gt;
&lt;li&gt;debug：从源代码开编译，并debug&lt;/li&gt;
&lt;li&gt;exec：运行并debug一个已经编译完成的二进制文件&lt;/li&gt;
&lt;li&gt;test：编译一个test二进制文件，并进行debug&lt;/li&gt;
&lt;li&gt;trace：编译并对程序进行trace&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在线的文档可以在github上看到：&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/usage/dlv.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delve/Documentation/usage/dlv.md&lt;/a&gt;。类似debug、exec等，在这个主页面里都可以看得到，不过打开也没什么细节，就是一些选项参数的说明，和&lt;code class=&quot;language-text&quot;&gt;$ dlv connect ...&lt;/code&gt;打印出来的没差别。&lt;/p&gt;
&lt;p&gt;经过上面的选择后，就可以进入到dlv的交互界面了，同样的，可以通过&lt;a href=&quot;#ID_APP_DLV_HELP&quot;&gt;(dlv) help&lt;/a&gt;来查看交互命令选项。&lt;/p&gt;
&lt;p&gt;在调试过程中，有些时候你需要做一些细节观察行为，比如说打印出某些变量的值之类的。dlv提供了一些go语法的子集表达式，可以在交互界面直接使用：&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/cli/expr.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Expressions&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;实际的debug范例可以看这篇：&lt;a href=&quot;https://yq.aliyun.com/articles/57578&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用Delve进行Golang代码的调试&lt;/a&gt;，算是讲解得很贴近日常工作使用了。&lt;/p&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/installation/osx/install.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Installation on OSX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/api/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delve/Documentation/api/README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/cli/README.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delve/Documentation/cli/README.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/usage/dlv.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;delve/Documentation/usage/dlv.md&lt;/a&gt;{:target=“_blank”&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/go-delve/delve/blob/master/Documentation/cli/expr.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Expressions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yq.aliyun.com/articles/57578&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用Delve进行Golang代码的调试&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;dlv-help-id_app_help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dlv-help-id_app_help&quot; aria-label=&quot;dlv help id_app_help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;dlv help {#ID_APP_HELP}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ dlv help
Delve is a source level debugger for Go programs.

Delve enables you to interact with your program by controlling the execution of the process,
evaluating variables, and providing information of thread / goroutine state, CPU register state and more.

The goal of this tool is to provide a simple yet powerful interface for debugging Go programs.

Pass flags to the program you are debugging using `--`, for example:

`dlv exec ./hello -- server --config conf/config.toml`

Usage:
  dlv [command]

Available Commands:
  attach      Attach to running process and begin debugging.
  connect     Connect to a headless debug server.
  core        Examine a core dump.
  debug       Compile and begin debugging main package in current directory, or the package specified.
  exec        Execute a precompiled binary, and begin a debug session.
  help        Help about any command
  run         Deprecated command. Use &apos;debug&apos; instead.
  test        Compile test binary and begin debugging program.
  trace       Compile and begin tracing program.
  version     Prints version.

Flags:
      --accept-multiclient   Allows a headless server to accept multiple client connections. Note that the server API is not reentrant and clients will have to coordinate.
      --api-version int      Selects API version when headless. (default 1)
      --backend string       Backend selection:
	default		Uses lldb on macOS, native everywhere else.
	native		Native backend.
	lldb		Uses lldb-server or debugserver.
	rr		Uses mozilla rr (https://github.com/mozilla/rr).
 (default &quot;default&quot;)
      --build-flags string   Build flags, to be passed to the compiler.
      --headless             Run debug server only, in headless mode.
      --init string          Init file, executed by the terminal client.
  -l, --listen string        Debugging server listen address. (default &quot;localhost:0&quot;)
      --log                  Enable debugging server logging.
      --log-output string    Comma separated list of components that should produce debug output, possible values:
	debugger	Log debugger commands
	gdbwire		Log connection to gdbserial backend
	lldbout		Copy output from debugserver/lldb to standard output
	debuglineerr	Log recoverable errors reading .debug_line
	rpc		Log all RPC messages
	fncall		Log function call protocol
	minidump	Log minidump loading
Defaults to &quot;debugger&quot; when logging is enabled with --log.
      --wd string            Working directory for running the program. (default &quot;.&quot;)

Use &quot;dlv [command] --help&quot; for more information about a command.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;dlv-help-id_app_dlv_help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dlv-help-id_app_dlv_help&quot; aria-label=&quot;dlv help id_app_dlv_help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;(dlv) help {#ID_APP_DLV_HELP}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;(dlv) help
The following commands are available:
    args ------------------------ Print function arguments.
    break (alias: b) ------------ Sets a breakpoint.
    breakpoints (alias: bp) ----- Print out info for active breakpoints.
    call ------------------------ Resumes process, injecting a function call (EXPERIMENTAL!!!)
    clear ----------------------- Deletes breakpoint.
    clearall -------------------- Deletes multiple breakpoints.
    condition (alias: cond) ----- Set breakpoint condition.
    config ---------------------- Changes configuration parameters.
    continue (alias: c) --------- Run until breakpoint or program termination.
    deferred -------------------- Executes command in the context of a deferred call.
    disassemble (alias: disass) - Disassembler.
    down ------------------------ Move the current frame down.
    edit (alias: ed) ------------ Open where you are in $DELVE_EDITOR or $EDITOR
    exit (alias: quit | q) ------ Exit the debugger.
    frame ----------------------- Set the current frame, or execute command on a different frame.
    funcs ----------------------- Print list of functions.
    goroutine ------------------- Shows or changes current goroutine
    goroutines ------------------ List program goroutines.
    help (alias: h) ------------- Prints the help message.
    list (alias: ls | l) -------- Show source code.
    locals ---------------------- Print local variables.
    next (alias: n) ------------- Step over to next source line.
    on -------------------------- Executes a command when a breakpoint is hit.
    print (alias: p) ------------ Evaluate an expression.
    regs ------------------------ Print contents of CPU registers.
    restart (alias: r) ---------- Restart process.
    set ------------------------- Changes the value of a variable.
    source ---------------------- Executes a file containing a list of delve commands
    sources --------------------- Print list of source files.
    stack (alias: bt) ----------- Print stack trace.
    step (alias: s) ------------- Single step through program.
    step-instruction (alias: si)  Single step a single cpu instruction.
    stepout --------------------- Step out of the current function.
    thread (alias: tr) ---------- Switch to the specified thread.
    threads --------------------- Print out info for every traced thread.
    trace (alias: t) ------------ Set tracepoint.
    types ----------------------- Print list of types
    up -------------------------- Move the current frame up.
    vars ------------------------ Print package variables.
    whatis ---------------------- Prints type of an expression.
Type help followed by a command for full documentation.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Goroutine]]></title><link>https://xenojoshua.com/posts/2019/03/golang-goroutine</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/03/golang-goroutine</guid><pubDate>Tue, 26 Mar 2019 03:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-gpm--%E5%8E%9F%E7%90%86&quot;&gt;2. GPM &amp;#x26; 原理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-profiling&quot;&gt;3. Profiling&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#pprof-web&quot;&gt;pprof web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#godebugschedtrace1000&quot;&gt;GODEBUG=schedtrace=1000&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-blocking&quot;&gt;4. Blocking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;本文是Go语言系列文章&lt;a href=&quot;/2019/02/golang-note/&quot;&gt;Golang Notes&lt;/a&gt;的其中一篇，完整的文章列表请去总章查看。&lt;/p&gt;
&lt;p&gt;Goroutine或者说Go程是Go语言的高性能关键。常见的高级语言比如说node、php这种，天生就是单进程单线程的，如果需要充分利用CPU，就需要启动多个进程进行集群管理。即便如此，在多个进程之间如何进行数据交换、进行业务协作又是一个基本上无解的头痛问题。而像Java这种，虽然用的是单个进程中的多线程，但因语言本身及线程设计本质的问题，开发体验仍旧说不上好。&lt;/p&gt;
&lt;p&gt;Go为什么能这么快就火起来，第一是因为它本身的性能很好，能满足各种需求，另一个就是Goroutine了，可以说是Go的灵魂。在不增加程序复杂度的情况下，马上就能将所有的物理核心都跑满利用起来的，横向过一遍也就只有Go了。&lt;/p&gt;
&lt;p&gt;但世上无银弹，Goroutine虽然好用消耗小，但使用不当仍旧会出问题，所以这里就需要理解其原理，并知道如何profiling找问题。&lt;/p&gt;
&lt;h1 id=&quot;2-gpm--原理&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-gpm--%E5%8E%9F%E7%90%86&quot; aria-label=&quot;2 gpm  原理 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. GPM &amp;#x26; 原理&lt;/h1&gt;
&lt;p&gt;这部分的文章实在是太多了，基本上看完或者选择性看完（最重要的是3和4）下面几篇，就OK了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果只需要初步的理解，这篇即可：&lt;a href=&quot;https://juejin.im/post/5b7678f451882533110e8948&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang 的 协程调度机制 与 GOMAXPROCS 性能调优&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;如果需要深入源码及实现细节（过于细节，有点偏离了行文的目的）：&lt;a href=&quot;https://studygolang.com/articles/11627&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang源码探索(二) 协程的实现原理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;如果需要完美理解GPM及Goroutine（其实这篇是最好的）：&lt;a href=&quot;https://tonybai.com/2017/06/23/an-intro-about-goroutine-scheduler/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;也谈goroutine调度器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;接上一篇，更多范例的调度细节：&lt;a href=&quot;https://tonybai.com/2017/11/23/the-simple-analysis-of-goroutine-schedule-examples/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Goroutine调度实例简要分析&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;几点记住就好：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;G是任务，全局有一个队列，每个P还有自己的队列&lt;/li&gt;
&lt;li&gt;P是逻辑处理器，由P来处理G&lt;/li&gt;
&lt;li&gt;M是物理处理器（实际上是Go应用程序里的&lt;code class=&quot;language-text&quot;&gt;线程&lt;/code&gt;），P会和M绑定，得到执行的实体&lt;/li&gt;
&lt;li&gt;M最终会通过操作系统调度，在CPU上得到运行&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-profiling&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-profiling&quot; aria-label=&quot;3 profiling permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. Profiling&lt;/h1&gt;
&lt;h2 id=&quot;pprof-web&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#pprof-web&quot; aria-label=&quot;pprof web permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;pprof web&lt;/h2&gt;
&lt;p&gt;继续建议使用基于WEB的入口的方式进行查看：&lt;a href=&quot;/2019/03/golang-memory/#ID_PROF_PPROF_WEB&quot;&gt;Golang Memory#5.3.3 runtime/pprof web&lt;/a&gt;。此外，由于Goroutine一般数量巨大，不像CPU和内存检查的是点，goroutine更多的时候是要把握一个状态（面），因此更建议使用pprof的WEB UI来进行观察。入口在：&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:8080/debug/pprof/goroutine&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool pprof -http=:8899 http://127.0.0.1:8080/debug/pprof/goroutine
Fetching profile over HTTP from http://127.0.0.1:8080/debug/pprof/goroutine
Saved profile in /Users/Jonathan/pprof/pprof.goroutine.001.pb.gz&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在Profile的分析结果里，一般会看到&lt;code class=&quot;language-text&quot;&gt;gopark&lt;/code&gt;这个东西，这个在之前的几篇文章里都没怎么提到过（当然最细节的那篇是有的）。这里可以再看下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/27056944&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go调度详解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/u010853261/article/details/85887948&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang-gopark函数和goready函数原理分析&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在第一篇里还可以顺道看下&lt;code class=&quot;language-text&quot;&gt;自旋（spinning）&lt;/code&gt;的概念。&lt;/p&gt;
&lt;p&gt;测试代码这里就不帖了，写起来实在是太简单，做个循环，起一点goroutine就好。&lt;/p&gt;
&lt;h2 id=&quot;godebugschedtrace1000&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#godebugschedtrace1000&quot; aria-label=&quot;godebugschedtrace1000 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;GODEBUG=schedtrace=1000&lt;/h2&gt;
&lt;p&gt;如果需要查看Go调度器当前状态：使用&lt;code class=&quot;language-text&quot;&gt;GODEBUG=schedtrace=...&lt;/code&gt;，第二个等号后面给时间间隔，单位为毫秒。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ GODEBUG=schedtrace=1000 go run goroutine.go
SCHED 0ms: gomaxprocs=8 idleprocs=6 threads=4 spinningthreads=1 idlethreads=0 runqueue=0 [0 0 0 0 0 0 0 0]
# command-line-arguments
SCHED 0ms: gomaxprocs=8 idleprocs=5 threads=5 spinningthreads=1 idlethreads=0 runqueue=0 [0 0 0 0 0 0 0 0]
# command-line-arguments
SCHED 0ms: gomaxprocs=8 idleprocs=5 threads=5 spinningthreads=1 idlethreads=0 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 0ms: gomaxprocs=8 idleprocs=6 threads=4 spinningthreads=1 idlethreads=0 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 1000ms: gomaxprocs=8 idleprocs=8 threads=22 spinningthreads=0 idlethreads=15 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 1010ms: gomaxprocs=8 idleprocs=0 threads=12 spinningthreads=0 idlethreads=1 runqueue=33 [1 1 0 2 2 1 1 2]
SCHED 2010ms: gomaxprocs=8 idleprocs=8 threads=22 spinningthreads=0 idlethreads=15 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 2022ms: gomaxprocs=8 idleprocs=0 threads=12 spinningthreads=0 idlethreads=1 runqueue=36 [1 1 0 1 0 2 2 0]
SCHED 3019ms: gomaxprocs=8 idleprocs=8 threads=22 spinningthreads=0 idlethreads=15 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 3027ms: gomaxprocs=8 idleprocs=0 threads=12 spinningthreads=0 idlethreads=1 runqueue=36 [1 1 1 1 0 1 1 0]
SCHED 4028ms: gomaxprocs=8 idleprocs=8 threads=22 spinningthreads=0 idlethreads=15 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 4034ms: gomaxprocs=8 idleprocs=0 threads=12 spinningthreads=0 idlethreads=1 runqueue=31 [1 0 4 4 1 0 1 0]
SCHED 5037ms: gomaxprocs=8 idleprocs=8 threads=22 spinningthreads=0 idlethreads=15 runqueue=0 [0 0 0 0 0 0 0 0]
SCHED 5037ms: gomaxprocs=8 idleprocs=0 threads=12 spinningthreads=0 idlethreads=1 runqueue=22 [3 3 3 0 3 2 3 3]
SCHED 6041ms: gomaxprocs=8 idleprocs=8 threads=22 spinningthreads=0 idlethreads=15 runqueue=0 [0 0 0 0 0 0 0 0]
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;字段说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;SCHED&lt;/code&gt;：标识该输出信息为goroutine scheduler的输出&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;5037ms&lt;/code&gt;：从程序启动到输出这行日志的时间&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;gomaxprocs&lt;/code&gt;：P的数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;idleprocs&lt;/code&gt;：idle状态的P的数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;threads&lt;/code&gt;：操作系统threads的数量，包含scheduler使用的m数量，加上runtime自用的类似sysmon这样的thread的数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;spinningthreads&lt;/code&gt;：处于自旋状态的操作系统thread数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;idlethread&lt;/code&gt;：处于idle状态的操作系统thread的数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;runqueue=22&lt;/code&gt;：go scheduler全局队列中G的数量&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;[3 3 3 0 3 2 3 3]&lt;/code&gt;：8个P的local queue中的G的数量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;通过这个输出可以很清晰看到goroutine的整体状态，特别是调度的状态，到底有没有跑满CPU，到底有没有空闲的线程，任务调度整体是不是平滑的，等等。可以说是非常有用。&lt;/p&gt;
&lt;p&gt;如果在GODEBUG中再加上&lt;code class=&quot;language-text&quot;&gt;,scheddetail=1&lt;/code&gt;的话，则会给出更多的细节：每个G、M和P的详细调度信息。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ GODEBUG=schedtrace=1000,scheddetail=1 go run goroutine.go
...
# command-line-arguments
SCHED 0ms: gomaxprocs=8 idleprocs=5 threads=5 spinningthreads=1 idlethreads=0 runqueue=0 gcwaiting=0 nmidlelocked=1 stopwait=0 sysmonwait=0
  P0: status=1 schedtick=0 syscalltick=0 m=3 runqsize=0 gfreecnt=0
  P1: status=1 schedtick=1 syscalltick=0 m=2 runqsize=0 gfreecnt=0
  P2: status=1 schedtick=0 syscalltick=0 m=4 runqsize=0 gfreecnt=0
  P3: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P4: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P5: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P6: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P7: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  M4: p=2 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=true blocked=false lockedg=-1
  M3: p=0 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=false blocked=false lockedg=-1
  M2: p=1 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=true blocked=false lockedg=-1
  M1: p=-1 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=false blocked=false lockedg=-1
  M0: p=-1 curg=-1 mallocing=0 throwing=0 preemptoff= locks=0 dying=0 spinning=false blocked=true lockedg=1
  G1: status=1(chan receive) m=-1 lockedm=0
  G2: status=4(force gc (idle)) m=-1 lockedm=-1
  G3: status=4(GC sweep wait) m=-1 lockedm=-1
SCHED 0ms: gomaxprocs=8 idleprocs=6 threads=4 spinningthreads=1 idlethreads=0 runqueue=0 gcwaiting=0 nmidlelocked=0 stopwait=0 sysmonwait=0
  P0: status=1 schedtick=0 syscalltick=0 m=0 runqsize=0 gfreecnt=0
  P1: status=1 schedtick=0 syscalltick=0 m=3 runqsize=0 gfreecnt=0
  P2: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P3: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P4: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P5: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P6: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  P7: status=0 schedtick=0 syscalltick=0 m=-1 runqsize=0 gfreecnt=0
  M3: p=1 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=false blocked=false lockedg=-1
  M2: p=-1 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=false blocked=false lockedg=-1
  M1: p=-1 curg=17 mallocing=0 throwing=0 preemptoff= locks=0 dying=0 spinning=false blocked=false lockedg=17
  M0: p=0 curg=-1 mallocing=0 throwing=0 preemptoff= locks=1 dying=0 spinning=false blocked=false lockedg=1
  G1: status=1() m=-1 lockedm=0
  G17: status=6() m=1 lockedm=1
  G2: status=1() m=-1 lockedm=-1
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;4-blocking&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-blocking&quot; aria-label=&quot;4 blocking permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. Blocking&lt;/h1&gt;
&lt;p&gt;阻塞的事情在这里顺道提一笔，毕竟阻塞和goroutine还是有很深的关系的，很多时候我们的debug就是要找死循环或死锁的goroutine。如果需要查看程序当中的阻塞情况（主要是竞争锁），一样可以使用pprof，入口在：&lt;code class=&quot;language-text&quot;&gt;go tool pprof http://127.0.0.1:8080/debug/pprof/block&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/5b7678f451882533110e8948&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang 的 协程调度机制 与 GOMAXPROCS 性能调优&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://studygolang.com/articles/11627&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang源码探索(二) 协程的实现原理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2017/06/23/an-intro-about-goroutine-scheduler/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;也谈goroutine调度器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2017/11/23/the-simple-analysis-of-goroutine-schedule-examples/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Goroutine调度实例简要分析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://juejin.im/post/5b7678f451882533110e8948&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang 的 协程调度机制 与 GOMAXPROCS 性能调优&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/28351811&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;剖析使Go语言高效的5个特性(4/5): Goroutines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/28381197&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Goroutine是如何工作的?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/27056944&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go调度详解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/u010853261/article/details/85887948&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang-gopark函数和goready函数原理分析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://software.intel.com/en-us/blogs/2014/05/10/debugging-performance-issues-in-go-programs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Debugging performance issues in Go programs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang CPU]]></title><link>https://xenojoshua.com/posts/2019/03/golang-cpu</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/03/golang-cpu</guid><pubDate>Tue, 26 Mar 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-cpu&quot;&gt;2. CPU&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E6%A0%B8%E5%BF%83%E6%95%B0%E9%87%8F&quot;&gt;2.1 核心数量&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-profiling&quot;&gt;2.2 Profiling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-%E7%81%AB%E7%84%B0%E5%9B%BE&quot;&gt;2.3 火焰图&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E4%BB%A3%E7%A0%81&quot;&gt;3. 代码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E8%B5%84%E6%96%99&quot;&gt;4. 资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#experimentcpucpugo-id_app_cpu_sample&quot;&gt;experiment/cpu/cpu.go {#ID_APP_CPU_SAMPLE}&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;本文是Go语言系列文章&lt;a href=&quot;/2019/02/golang-note/&quot;&gt;Golang Notes&lt;/a&gt;的其中一篇，完整的文章列表请去总章查看。&lt;/p&gt;
&lt;h1 id=&quot;2-cpu&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-cpu&quot; aria-label=&quot;2 cpu permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. CPU&lt;/h1&gt;
&lt;p&gt;CPU这里基本上就没什么太多原理可以说了，只要知道几个知识点就OK。&lt;/p&gt;
&lt;h2 id=&quot;21-核心数量&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E6%A0%B8%E5%BF%83%E6%95%B0%E9%87%8F&quot; aria-label=&quot;21 核心数量 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 核心数量&lt;/h2&gt;
&lt;p&gt;获取可用的核心数量：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;runtime&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NumCPU&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;设置当前Go进程应该使用多少核心：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;runtime&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;GOMAXPROCS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;22-profiling&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-profiling&quot; aria-label=&quot;22 profiling permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 Profiling&lt;/h2&gt;
&lt;p&gt;Profiling方面和内存使用的工具基本上是一致的，直接看内存那篇里的内容即可：&lt;a href=&quot;/2019/03/golang-memory/#ID_PROF_PPROF_WEB&quot;&gt;Golang Memory#5.3.3 runtime/pprof web&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;仍旧推荐使用WEB入口的方式来进行profiling，更容易进行实时追踪。获取采样的地址为：&lt;code class=&quot;language-text&quot;&gt;http://localhost:8080/debug/pprof/profile&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool pprof http://localhost:8080/debug/pprof/profile
Fetching profile over HTTP from http://localhost:8080/debug/pprof/profile
Saved profile in /Users/XXX/pprof/pprof.samples.cpu.001.pb.gz
Type: cpu
Time: Mar 26, 2019 at 1:41pm (CST)
Duration: 30.15s, Total samples = 3.16s (10.48%)
Entering interactive mode (type &quot;help&quot; for commands, &quot;o&quot; for options)
(pprof)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;go tool pprof在进行CPU分析的时候先要进行采样，所以需要等待一段时间，如果在URL上不加任何参数的话，默认是采样30秒。可以通过附加&lt;code class=&quot;language-text&quot;&gt;?seconds=x&lt;/code&gt;来进行调整。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool pprof http://localhost:8080/debug/pprof/profile?seconds=10
Fetching profile over HTTP from http://localhost:8080/debug/pprof/profile?seconds=10
Saved profile in /Users/XXX/pprof/pprof.samples.cpu.002.pb.gz
Type: cpu
Time: Mar 26, 2019 at 1:44pm (CST)
Duration: 10.02s, Total samples = 1.06s (10.57%)
Entering interactive mode (type &quot;help&quot; for commands, &quot;o&quot; for options)
(pprof)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;同样的，其他的工具例如&lt;code class=&quot;language-text&quot;&gt;trace&lt;/code&gt;等也都可以使用。如果要在代码里进行采样，则需要使用接口：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;pprof&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;StartCPUProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Stdout&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; pprof&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;StopCPUProfile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;23-火焰图&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-%E7%81%AB%E7%84%B0%E5%9B%BE&quot; aria-label=&quot;23 火焰图 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 火焰图&lt;/h2&gt;
&lt;p&gt;火焰图是最直观的查看CPU消耗的分析工具，如果要在Go工具链上生成火焰图，可以使用在内存篇里提到过的pprof的UI界面。打开之后&lt;code class=&quot;language-text&quot;&gt;VIEW &gt; Flame Graph&lt;/code&gt;就能看到了。&lt;/p&gt;
&lt;h1 id=&quot;3-代码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E4%BB%A3%E7%A0%81&quot; aria-label=&quot;3 代码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 代码&lt;/h1&gt;
&lt;p&gt;代码放在github：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/experiment/cpu/cpu.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;experiment/cpu/cpu.go&lt;/a&gt;。github上的代码可以看到最新的更新，不过需要打开新的页面稍微麻烦点。&lt;/p&gt;
&lt;p&gt;当前页面会放一份gist，方便直接查看：&lt;a href=&quot;#ID_APP_CPU_SAMPLE&quot;&gt;experiment/cpu/cpu.go&lt;/a&gt;，但可能更新不及时。&lt;/p&gt;
&lt;h1 id=&quot;4-资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E8%B5%84%E6%96%99&quot; aria-label=&quot;4 资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 资料&lt;/h1&gt;
&lt;h2 id=&quot;experimentcpucpugo-id_app_cpu_sample&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#experimentcpucpugo-id_app_cpu_sample&quot; aria-label=&quot;experimentcpucpugo id_app_cpu_sample permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;experiment/cpu/cpu.go {#ID_APP_CPU_SAMPLE}&lt;/h2&gt;
&lt;script src=&quot;https://gist.github.com/agreatfool/24a00ddbdb04c68d6fd2792ba8808ce6.js&quot;&gt; &lt;/script&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Memory]]></title><link>https://xenojoshua.com/posts/2019/03/golang-memory</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/03/golang-memory</guid><pubDate>Mon, 25 Mar 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D&quot;&gt;2. 内存分配&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-why&quot;&gt;2.1 WHY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-tcmalloc&quot;&gt;2.2 Tcmalloc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3&quot;&gt;2.3 源码理解&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#231-%E4%B8%BB%E8%A6%81%E6%BA%90%E7%A0%81&quot;&gt;2.3.1 主要源码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#232-%E6%A6%82%E5%BF%B5&quot;&gt;2.3.2 概念&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A0%86%E5%86%85%E5%AD%98%E4%B8%8A%E9%99%90&quot;&gt;堆内存上限&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#page&quot;&gt;Page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%80%83%E9%80%B8%E5%88%86%E6%9E%90&quot;&gt;逃逸分析&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#233-%E5%86%85%E5%AD%98%E5%88%86%E5%9D%97&quot;&gt;2.3.3 内存分块&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#234-%E5%AF%B9%E8%B1%A1%E5%B0%BA%E5%AF%B8%E5%88%86%E7%BA%A7&quot;&gt;2.3.4 对象尺寸分级&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#235-%E9%98%B2%E7%A2%8E%E7%89%87%E8%AE%BE%E8%AE%A1&quot;&gt;2.3.5 防碎片设计&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#236-%E5%86%85%E5%AD%98%E7%94%B3%E8%AF%B7%E7%AE%A1%E7%BA%BF%E8%AE%BE%E8%AE%A1&quot;&gt;2.3.6 内存申请管线设计&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#237-%E6%8C%89%E5%AF%B9%E8%B1%A1%E5%B0%BA%E5%AF%B8%E4%B8%8D%E5%90%8C%E7%9A%84%E5%88%86%E9%85%8D%E8%A1%8C%E4%B8%BA&quot;&gt;2.3.7 按对象尺寸不同的分配行为&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#2371-tiny&quot;&gt;2.3.7.1 Tiny&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2372-small&quot;&gt;2.3.7.2 Small&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2373-large&quot;&gt;2.3.7.3 Large&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6&quot;&gt;3. 垃圾回收&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-%E7%89%88%E6%9C%AC%E5%8E%86%E5%8F%B2--%E6%BC%94%E8%BF%9B&quot;&gt;3.1 版本历史 &amp;#x26; 演进&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E8%A6%81%E7%82%B9&quot;&gt;3.2 垃圾回收要点&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#321-gc%E8%A7%A6%E5%8F%91%E6%9D%A1%E4%BB%B6&quot;&gt;3.2.1 GC触发条件&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#3211-gctriggerheap&quot;&gt;3.2.1.1 gcTriggerHeap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3212-gctriggertime&quot;&gt;3.2.1.2 gcTriggerTime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3213-gctriggercycle&quot;&gt;3.2.1.3 gcTriggerCycle&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-%E5%85%B6%E4%BB%96%E6%A6%82%E5%BF%B5&quot;&gt;3.3 其他概念&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-profile-id_profile&quot;&gt;5. Profile {#ID_PROFILE}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#51-metrics&quot;&gt;5.1 Metrics&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#memstats-id_memstats_export&quot;&gt;MemStats {#ID_MEMSTATS_EXPORT}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#memstats-id_memstats&quot;&gt;memstats {#ID_MEMSTATS}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#gcstats&quot;&gt;GCStats&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#52-%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B&quot;&gt;5.2 测试用例&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#53-profile%E6%96%B9%E6%B3%95&quot;&gt;5.3 Profile方法&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#531-runtimereadmemstats-id_prof_readmemstats&quot;&gt;5.3.1 runtime.ReadMemStats {#ID_PROF_READMEMSTATS}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#532-runtimepprof-id_prof_pprof&quot;&gt;5.3.2 runtime/pprof {#ID_PROF_PPROF}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#533-runtimepprof-web-id_prof_pprof_web&quot;&gt;5.3.3 runtime/pprof web {#ID_PROF_PPROF_WEB}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#534-runtimetrace-id_prof_trace&quot;&gt;5.3.4 runtime/trace {#ID_PROF_TRACE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#535-godebuggctrace1-id_porf_debug&quot;&gt;5.3.5 GODEBUG=‘gctrace=1’ {#ID_PORF_DEBUG}&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#54-pprof%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8&quot;&gt;5.4 pprof简单使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#541-pprof-help&quot;&gt;5.4.1 pprof help&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#542-%E5%B8%B8%E7%94%A8%E4%BA%A4%E4%BA%92%E5%91%BD%E4%BB%A4&quot;&gt;5.4.2 常用交互命令&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#543-sample_index-id_prof_sample_index&quot;&gt;5.4.3 sample_index {#ID_PROF_SAMPLE_INDEX}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#pprof%E6%97%A0%E8%BE%93%E5%87%BA&quot;&gt;pprof无输出&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#544-%E8%BE%93%E5%87%BA&quot;&gt;5.4.4 输出&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90&quot;&gt;静态资源&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#web-ui&quot;&gt;WEB UI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#545-pprofprotoprofileproto&quot;&gt;5.4.5 pprof/proto/profile.proto&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#55-%E5%A4%8D%E6%9D%82%E8%8C%83%E4%BE%8B%E5%AE%9E%E8%B7%B5&quot;&gt;5.5 复杂范例实践&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5-id_app_links&quot;&gt;参考链接 {#ID_APP_LINKS}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D&quot;&gt;内存分配&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98%E5%9B%9E%E6%94%B6&quot;&gt;内存回收&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98profile&quot;&gt;内存Profile&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%85%B6%E4%BB%96&quot;&gt;其他&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#gosrcruntimemstatsgomemstats112-id_app_memstats&quot;&gt;go/src/runtime/mstats.go#MemStats@1.12 {#ID_APP_MEMSTATS}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#comments-of-gosrcruntimemallocgo112-id_app_malloc&quot;&gt;comments of go/src/runtime/malloc.go@1.12 {#ID_APP_MALLOC}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#go-tool-pprof-usage112-id_app_pprof_usage&quot;&gt;go tool pprof usage@1.12 {#ID_APP_PPROF_USAGE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#pprof-help112-id_app_pprof_help&quot;&gt;(pprof) help@1.12 {#ID_APP_PPROF_HELP}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#go-tool-trace-usage112-id_app_trace_usage&quot;&gt;go tool trace usage@1.12 {#ID_APP_TRACE_USAGE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#godebuggctrace1-sample-id_app_gctrace_sample&quot;&gt;GODEBUG=gctrace=1 sample {#ID_APP_GCTRACE_SAMPLE}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#experimentmemorymemorygo-id_app_memory_sample&quot;&gt;experiment/memory/memory.go {#ID_APP_MEMORY_SAMPLE}&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;本文是Go语言系列文章&lt;a href=&quot;/2019/02/golang-note/&quot;&gt;Golang Notes&lt;/a&gt;的其中一篇，完整的文章列表请去总章查看。&lt;/p&gt;
&lt;p&gt;内存管理是任何编程语言最重要的部分，几乎可以不带之一了。Go语言的机制是和一般高级语言一样的垃圾回收器机制，因此需要用户直接操作的东西比较少，但掌握其知识点仍旧有利于写出性能更好的Go程序，此外也可以监控Go程序的内存使用情况。&lt;/p&gt;
&lt;p&gt;下文按以下思路走，先看下Go语言是如何进行内存分配的，然后看下Go语言是如何对分配的内存进行垃圾回收的，最后看下如何对运行的Go程序进行下针对内存的Profiling。&lt;/p&gt;
&lt;h1 id=&quot;2-内存分配&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D&quot; aria-label=&quot;2 内存分配 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 内存分配&lt;/h1&gt;
&lt;h2 id=&quot;21-why&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-why&quot; aria-label=&quot;21 why permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 WHY&lt;/h2&gt;
&lt;p&gt;理解Go语言是如何分配内存确实是一件收益不高的事情，不了解也不影响Go编码和程序运行与使用。当然，了解了能更好理解Go语言是如何分配内存的，对某些类型的应用编写有指导作用，此外，也能更好理解GC和Profile。（作为学习也是好的，见多识广，就像这次看完Go语言的内存分配之后，发现思路和很早之前学习memcached的内存分配防碎片的机制是一致的）&lt;/p&gt;
&lt;h2 id=&quot;22-tcmalloc&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-tcmalloc&quot; aria-label=&quot;22 tcmalloc permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 Tcmalloc&lt;/h2&gt;
&lt;p&gt;Go语言的内存分配最早是基于Tcmalloc的，但后来分化出来做了点定制。毕竟Go语言有其自身的目标，不可能全盘照搬Tcmalloc。有精力的其实可以好好看看Tcmalloc，一样可以帮助理解Go语言内存分配。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;// This was originally based on tcmalloc, but has diverged quite a bit.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;// &lt;a href=&quot;http://goog-perftools.sourceforge.net/doc/tcmalloc.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;http://goog-perftools.sourceforge.net/doc/tcmalloc.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;相关的分析之类的资料在最下面的&lt;a href=&quot;#ID_APP_LINKS&quot;&gt;资料章节&lt;/a&gt;里有，有兴趣的可以自行查看。&lt;/p&gt;
&lt;h2 id=&quot;23-源码理解&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-%E6%BA%90%E7%A0%81%E7%90%86%E8%A7%A3&quot; aria-label=&quot;23 源码理解 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 源码理解&lt;/h2&gt;
&lt;p&gt;与Node.js开发组不同，Golang的维护者对于信息的整理和公布做的实在是一般，很少有高质量的官方博客对底层及一系列的系统进行对应的说明（不是长篇wiki就是一些简单的slide+视频）。所以要挖Golang的很多底层设计，就有必要深度阅读Golang的官方源代码。内存这块也是一样，因时间成本的原因，我主要是找了一些网上现成的博文进行阅读。主要有以下两篇，讲解得非常到位，正好国内国外各一篇：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://yq.aliyun.com/blog/573819&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang源码探索(三) GC的实现原理&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;基于Go &lt;code class=&quot;language-text&quot;&gt;1.9.2版本&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;完整讲解了Go是如何分配内存的，有自制的图解，附带代码以及注释解释&lt;/li&gt;
&lt;li&gt;更偏向于系统分析和程序性的讲解，对读者相对不太友好&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://povilasv.me/go-memory-management/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Memory Management&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;无版本信息，博客时间为&lt;code class=&quot;language-text&quot;&gt;2018-06-06&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;从基础的示例开始讲起，对读者友好&lt;/li&gt;
&lt;li&gt;会在讲解中穿插基础的概念解释，容易阅读理解&lt;/li&gt;
&lt;li&gt;包含了巨量的操作系统和内存系统相关的基本概念和设计思路&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上述两篇博客建议从英语的开始看起，甚至只看英语那篇也是可以的。此外，因版本关系中文那篇提到的512G最大堆内存容量限制已经在&lt;code class=&quot;language-text&quot;&gt;1.11版本&lt;/code&gt;中被取消了，具体可以查看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/10460&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: 512GB memory limitation #10460&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/commit/2b415549b813ba36caafa34fc34d72e47ee8335c&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: use sparse mappings for the heap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面会将内存分配相关的核心要点做摘录，长篇详细的，上面的博客里都有。&lt;/p&gt;
&lt;h3 id=&quot;231-主要源码&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#231-%E4%B8%BB%E8%A6%81%E6%BA%90%E7%A0%81&quot; aria-label=&quot;231 主要源码 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.1 主要源码&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/malloc.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/malloc.go&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;最重要看下代码头部的&lt;a href=&quot;#ID_APP_MALLOC&quot;&gt;注释&lt;/a&gt;，包含了太多重要的信息&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/sizeclasses.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/sizeclasses.go&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;span大小定义文件&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;232-概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#232-%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;232 概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.2 概念&lt;/h3&gt;
&lt;h4 id=&quot;堆内存上限&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%A0%86%E5%86%85%E5%AD%98%E4%B8%8A%E9%99%90&quot; aria-label=&quot;堆内存上限 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;堆内存上限&lt;/h4&gt;
&lt;p&gt;已取消限制，见上文的链接。在最后有上限的一个版本里，堆内存的极限是&lt;code class=&quot;language-text&quot;&gt;512 GB&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&quot;page&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#page&quot; aria-label=&quot;page permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Page&lt;/h4&gt;
&lt;p&gt;用来实际分配的内存块，一个Page的容量是&lt;code class=&quot;language-text&quot;&gt;8 KB&lt;/code&gt;。&lt;/p&gt;
&lt;h4 id=&quot;逃逸分析&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%80%83%E9%80%B8%E5%88%86%E6%9E%90&quot; aria-label=&quot;逃逸分析 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;逃逸分析&lt;/h4&gt;
&lt;p&gt;对于手动管理内存的语言，比如 C/C++，我们使用 malloc 或者 new 申请的变量会被分配到堆上。但是 Golang 并不是这样，虽然 Golang 语言里面也有 new。Golang 编译器决定变量应该分配到什么地方时会进行逃逸分析。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; x &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;x
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    x &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;x
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ go run &lt;span class=&quot;token parameter variable&quot;&gt;-gcflags&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;-m -l&apos;&lt;/span&gt; escape.go
./escape.go:6: moved to heap: x
./escape.go:7: &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;x escape to heap
./escape.go:11: bar new&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; does not escape&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;foo() 中的 x 最后在堆上分配，而 bar() 中的 x 最后分配在了栈上。&lt;/p&gt;
&lt;p&gt;资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/27807169&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang 内存管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/doc/faq#stack_or_heap&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How do I know whether a variable is allocated on the heap or the stack?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/wiki/CompilerOptimizations#escape-analysis-and-inlining&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Escape analysis and Inlining&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;233-内存分块&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#233-%E5%86%85%E5%AD%98%E5%88%86%E5%9D%97&quot; aria-label=&quot;233 内存分块 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.3 内存分块&lt;/h3&gt;
&lt;p&gt;go在程序启动时会分配一块虚拟内存地址是连续的内存, 结构如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;arena：arena区域就是我们通常说的&lt;code class=&quot;language-text&quot;&gt;heap&lt;/code&gt;，go从heap分配的内存都在这个区域中&lt;/li&gt;
&lt;li&gt;bitmap：bitmap区域用于表示arena区域中&lt;code class=&quot;language-text&quot;&gt;哪些地址保存了对象&lt;/code&gt;, 并且对象中哪些地址包含了指针（&lt;code class=&quot;language-text&quot;&gt;为GC服务&lt;/code&gt;）
&lt;ul&gt;
&lt;li&gt;bitmap区域中一个byte（8 bit）对应了arena区域中的四个指针大小的内存, 也就是2 bit对应一个指针大小的内存&lt;/li&gt;
&lt;li&gt;所以bitmap区域的大小是 n GB / 指针大小（8 byte）/ 4 = x GB&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;spans：spans区域用于表示arena区中的&lt;code class=&quot;language-text&quot;&gt;某一页（Page）属于哪个span&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;spans区域中一个指针（8 byte）对应了arena区域中的某一页（8KB）&lt;/li&gt;
&lt;li&gt;所以spans的大小是 n GB / Page（8 KB）* 指针大小（8 byte）= x MB&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;简单来说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;arena是真正存储数据的，也就是堆内存&lt;/li&gt;
&lt;li&gt;bitmap是用来维护内存地址使用情况的，主要为GC服务，以便快速扫描回收（这是堆的，栈有专门的类似功能的区块）&lt;/li&gt;
&lt;li&gt;spans是管理实际用来分配的内存块（span）的管理空间&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;234-对象尺寸分级&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#234-%E5%AF%B9%E8%B1%A1%E5%B0%BA%E5%AF%B8%E5%88%86%E7%BA%A7&quot; aria-label=&quot;234 对象尺寸分级 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.4 对象尺寸分级&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Tiny级别：对象大小小于16 byte；这句解释其实有点问题，这里的tiny其实应该是非常小的对象，比如说2 byte之类的，会聚合成为16 byte放到class 2的span中&lt;/li&gt;
&lt;li&gt;Small级别：对象大小小于等于32 KB&lt;/li&gt;
&lt;li&gt;Large级别：剩余的其他对象大小&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于Tiny的设计目的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;// The main targets of tiny allocator are small strings and&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;// standalone escaping variables. On a json benchmark&lt;br&gt;
// the allocator reduces number of allocations by ~12% and&lt;br&gt;
// reduces heap size by ~20%.&lt;/p&gt;
&lt;h3 id=&quot;235-防碎片设计&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#235-%E9%98%B2%E7%A2%8E%E7%89%87%E8%AE%BE%E8%AE%A1&quot; aria-label=&quot;235 防碎片设计 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.5 防碎片设计&lt;/h3&gt;
&lt;p&gt;如果内存分配器按需求随意从内存中进行对象的创建（占用）和销毁（释放），最后就会产生大量的内存碎片。因此常见的（也是Go使用的）防碎片方法是一开始就按对象的尺寸划分好一个个的内存单元，然后按实际的对象大小，放到对应的内存单元里。可以想象是银行的一整排保险柜，把东西放到保险柜的抽屉里。这样做的好处是可以防止内存碎片的大量发生，坏处是必然会产生内存浪费（想象下刚才举的例子，放进去的东西必然不可能完全占满一个抽屉，整个保险柜里的空间并不是100%被占满）。&lt;/p&gt;
&lt;p&gt;这里有一点需要注意，防碎片设计&lt;code class=&quot;language-text&quot;&gt;只&lt;/code&gt;针对&lt;code class=&quot;language-text&quot;&gt;Small级别&lt;/code&gt;的对象：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tiny对象是聚合在一起，然后固定分配在16 byte的class 2 span中&lt;/li&gt;
&lt;li&gt;Large对象则是一个对象一个span，span大小占多少个Page则取决于这个Large对象的大小&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go的内存分配器对&lt;code class=&quot;language-text&quot;&gt;span&lt;/code&gt;按大小做了分级，可以查看&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/sizeclasses.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;源代码&lt;/a&gt;来获得一个直观的认识。&lt;/p&gt;
&lt;p&gt;这里有几个字段：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;class：span的分级id&lt;/li&gt;
&lt;li&gt;bytes/obj：这个class的span里可以存放的对象的大小的上限
&lt;ul&gt;
&lt;li&gt;即，这个class的span可以存放的对象为：上一级span大小上限 + 1 &amp;#x3C;= 对象大小 &amp;#x3C;= 当前span大小上限&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;bytes/span：最低占用一个Page，即8 KB（8192 bytes），上涨都是按Page倍数来&lt;/li&gt;
&lt;li&gt;objects：这个class的span一个可存放的对象数量上限
&lt;ul&gt;
&lt;li&gt;公式：bytes/span / bytes/obj&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;tail waste：在span中对象满载的情况下，因对象数量无法被整除而浪费的内存
&lt;ul&gt;
&lt;li&gt;公式：(bytes/span / bytes/obj - objects) * bytes/obj&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;max waste：最大内存浪费情况，每一个放进该span的对象大小都是最小值的情况，浪费的内存量
&lt;ul&gt;
&lt;li&gt;公式：1 -（上一级span的bytes/obj + 1）* objects / bytes/span&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;举个例子：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;class  bytes/obj  bytes/span  objects  tail waste  max waste
  ...
    3         32        8192      256           0     46.88%
    4         48        8192      170          32     31.52%
  ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;class：4，4号span分级&lt;/li&gt;
&lt;li&gt;bytes/obj：48，该span内的对象大小为，33 byte -&gt; 48 byte&lt;/li&gt;
&lt;li&gt;bytes/span：8192，一个Page&lt;/li&gt;
&lt;li&gt;objects：8192 / 48&lt;/li&gt;
&lt;li&gt;tail waste：(8192 / 48 - 170) * 48 = 32 byte&lt;/li&gt;
&lt;li&gt;max waste：1 - 33 * 170 / 8192 = 0.31518&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;P.S&lt;/p&gt;
&lt;p&gt;源码中的class id从1到66，但还有一个0号span，这个class的span代表里面存放的是Large级别的对象，也就是超过32 KB尺寸的对象。所有span的class分类一共是67种。&lt;/p&gt;
&lt;h3 id=&quot;236-内存申请管线设计&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#236-%E5%86%85%E5%AD%98%E7%94%B3%E8%AF%B7%E7%AE%A1%E7%BA%BF%E8%AE%BE%E8%AE%A1&quot; aria-label=&quot;236 内存申请管线设计 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.6 内存申请管线设计&lt;/h3&gt;
&lt;p&gt;这个title是我自己起的，感觉还算贴切。&lt;/p&gt;
&lt;p&gt;Go语言的内存分配，并不是由单一的一个中央分配器进行控制的，而是由多个层级进行管理。最关键的是根据&lt;a href=&quot;https://studygolang.com/articles/11627&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;GMP&lt;/a&gt;的设计，在P这一层有单独的内存分配及缓存管理器。这么做的好处就是在P这一级，如果有缓存着的spans可以分配，那么这个内存申请行为就是完全无锁的，对性能的损耗就非常小了。关于这个分级缓存的概念，可以查看&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/malloc.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;malloc.go&lt;/a&gt;代码头部的注释。&lt;/p&gt;
&lt;p&gt;仍旧需要注意，这一套机制只服务于Tiny（其实就是Small）、Small级别的对象：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Large对象则会跳过下面的所有层级，直接到mheap这一层分配&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;//	mheap: the malloc heap, managed at page (8192-byte) granularity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;//	mspan: a run of pages managed by the mheap.&lt;br&gt;
//	mcentral: collects all spans of a given size class.&lt;br&gt;
//	mcache: a per-P cache of mspans with free space.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mheap：顶层的分配器，下面所有的申请都OOM之后就会走到这里，然后它检查自身的内存空间，如果还是没有足以满足这次分配需求的量，则向操作系统申请&lt;/li&gt;
&lt;li&gt;mcentral：会根据之前提到过的Small对象分级，对其内部管理的spans进行同样的分级，申请过来的时候按对应的分级进行检索。本质上来说，它和mheap其实是同一层，只是处理的工作不同，mcentral处理的是Tiny、Small对象的申请（分级span），而mheap则是处理mcentral内存不足的时候过来的申请以及所有Large对象的申请&lt;/li&gt;
&lt;li&gt;mcache：P层的spans分配管理，如果能在这一层直接解决申请和分配，则不需要加锁&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;237-按对象尺寸不同的分配行为&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#237-%E6%8C%89%E5%AF%B9%E8%B1%A1%E5%B0%BA%E5%AF%B8%E4%B8%8D%E5%90%8C%E7%9A%84%E5%88%86%E9%85%8D%E8%A1%8C%E4%B8%BA&quot; aria-label=&quot;237 按对象尺寸不同的分配行为 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.7 按对象尺寸不同的分配行为&lt;/h3&gt;
&lt;p&gt;根据之前提到过的Tiny、Small、Large三种对象大小分类，在对其申请内存空间的时候的行为也是不一样的。&lt;/p&gt;
&lt;h4 id=&quot;2371-tiny&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2371-tiny&quot; aria-label=&quot;2371 tiny permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.7.1 Tiny&lt;/h4&gt;
&lt;p&gt;Tiny对象的分配有其特殊性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Small对象：一个span内会包含多个Small对象，根据span的class分级不同，其内部可容纳的Small对象数量上限也不同&lt;/li&gt;
&lt;li&gt;Large对象：一个span内只会包含一个Large对象&lt;/li&gt;
&lt;li&gt;Tiny对象：多个Tiny对象会被&lt;code class=&quot;language-text&quot;&gt;合并&lt;/code&gt;起来，作为&lt;code class=&quot;language-text&quot;&gt;一个&lt;/code&gt;单独的对象（可以理解为组合成Small对象），放到class 2分级span中（和Small对象一样的处理）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根据官方的注释，存放Tiny对象的span现在默认是class为2的span分级，也就是16 byte一个对象的内存空间。这样做可以让尽量多的Tiny对象组合起来存放到一起，当然会造一定量的内存浪费（有可能）。如果使用8 byte的span，就不会浪费任何内存，但Tiny对象的合并机会就会少。而如果使用32 byte的span，可以有更多的Tiny对象合并机会，但最差情况下的内存浪费也会大很多。&lt;/p&gt;
&lt;p&gt;这部分的内容，可以查看malloc.go代码关于Tiny allocator部分的注释：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/malloc.go#L864&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;malloc.go&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;分配行为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在当前P的mcache里寻找可用的Tiny对象存储插槽（slot）对象&lt;/li&gt;
&lt;li&gt;根据这个存储位里已经存在的（如果有的话）其他Tiny对象，将当前对象尺寸取整为8、4、2 byte（为合并做准备）&lt;/li&gt;
&lt;li&gt;如果尺寸合适（能合并进去），则进行合并，并放到存储位里&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果合并不进去：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查找当前P的mcache里有没有其他mspan&lt;/li&gt;
&lt;li&gt;从mcache获取一个新的mspan&lt;/li&gt;
&lt;li&gt;扫描mspan的空闲bitmap来找到一个空闲的插槽（slot）&lt;/li&gt;
&lt;li&gt;如果有空闲的插槽（slot），申请这个位置，并将其作为一个新的Tiny对象插槽（slot）&lt;/li&gt;
&lt;li&gt;以上行为皆无锁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果mspan没有空闲的插槽（slot）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从mcentral申请一个新的mspan，mspan分级必须符合当前放置Tiny对象的mspan，并且有空闲的空间&lt;/li&gt;
&lt;li&gt;这个操作需要对mcentral加锁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果没有mspan：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从mheap申请mspan&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果mheap没有足够的空间：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从OS申请一组Page（至少1 MB）&lt;/li&gt;
&lt;li&gt;这个操作需要付出系统操作的代价&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2372-small&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2372-small&quot; aria-label=&quot;2372 small permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.7.2 Small&lt;/h4&gt;
&lt;p&gt;分配行为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;根据对象大小确定span的分级&lt;/li&gt;
&lt;li&gt;在P的mcache里寻找可用的mspan&lt;/li&gt;
&lt;li&gt;扫描mspan的空闲bitmap来查找是否有空闲的插槽（slot）&lt;/li&gt;
&lt;li&gt;如果有的话，就分配这个内存&lt;/li&gt;
&lt;li&gt;以上行为皆无锁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果mspan没有空闲的插槽（slot）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从mcentral申请一个新的mspan，mspan分级必须符合当前放置Tiny对象的mspan，并且有空闲的空间&lt;/li&gt;
&lt;li&gt;这个操作需要对mcentral加锁&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果没有mspan：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从mheap申请mspan&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果mheap没有足够的空间：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从OS申请一组Page（至少1 MB）&lt;/li&gt;
&lt;li&gt;这个操作需要付出系统操作的代价&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;2373-large&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2373-large&quot; aria-label=&quot;2373 large permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3.7.3 Large&lt;/h4&gt;
&lt;p&gt;Large对象的分配会直接使用mheap，跳过mcentral和mcache。如果没有足够的空间，则直接向OS申请。&lt;/p&gt;
&lt;h1 id=&quot;3-垃圾回收&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6&quot; aria-label=&quot;3 垃圾回收 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 垃圾回收&lt;/h1&gt;
&lt;p&gt;垃圾回收的知识点其实非常简单，软件工程业界在垃圾回收这个话题上其实是有几篇非常重要的算法的，一般的垃圾回收都是按照这些论文和算法进行实施，当然具体的细节处理上，各语言都有各自的应对方法。因此只要理解过一两个语言的垃圾回收机制，基本上问题就不大了，其他都是大同小异。&lt;/p&gt;
&lt;p&gt;Node.js这块我曾经写过：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/2018/01/node-memory/&quot;&gt;Node.JS Profile 1.1 V8内存机制&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;/2018/01/node-v8-gc/&quot;&gt;Node.JS Profile 1.2 V8 GC详解&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;基本上也算是很清晰了。&lt;/p&gt;
&lt;p&gt;Go语言GC比较好的分析文章可以阅读：&lt;a href=&quot;https://making.pusher.com/golangs-real-time-gc-in-theory-and-practice/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang’s Real-time GC in Theory and Practice&lt;/a&gt;。需要了解更多GC细节的，推荐继续阅读：&lt;a href=&quot;https://yq.aliyun.com/blog/573819&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang源码探索(三) GC的实现原理#回收对象的处理&lt;/a&gt;从&lt;code class=&quot;language-text&quot;&gt;回收对象的处理&lt;/code&gt;标题开始的后续内容（这篇文章没有标题锚链接，给不出链接，只能打开页面后搜索标题）。&lt;/p&gt;
&lt;p&gt;Go语言的GC发展到最近的版本，GC也已经是并行GC实现了，Go的GC相当的目标明确：&lt;code class=&quot;language-text&quot;&gt;减少停顿时间&lt;/code&gt;。STW越短，runtime对于应用程序的响应就响应越长，就可以显著缩短程序的延迟，并增加程序的吞吐量。&lt;/p&gt;
&lt;h2 id=&quot;31-版本历史--演进&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-%E7%89%88%E6%9C%AC%E5%8E%86%E5%8F%B2--%E6%BC%94%E8%BF%9B&quot; aria-label=&quot;31 版本历史  演进 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 版本历史 &amp;#x26; 演进&lt;/h2&gt;
&lt;p&gt;Go语言的GC在早期的几个版本里做的也并不是非常好，回顾整个发展历史可以让读者对于GC的功能及核心瓶颈要点有一个认识。相关内容可以通过阅读以下几篇来得到认识，这方面基本上看看就好，不用太较真。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/ismmkeynote&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Getting to Go: The Journey of Go’s Garbage Collector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://talks.golang.org/2015/go-gc.pdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go GC: Latency Problem Solved&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://making.pusher.com/golangs-real-time-gc-in-theory-and-practice/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang’s Real-time GC in Theory and Practice&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;32-垃圾回收要点&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E8%A6%81%E7%82%B9&quot; aria-label=&quot;32 垃圾回收要点 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 垃圾回收要点&lt;/h2&gt;
&lt;p&gt;理论的东西之后就是比较关键的实践和影响实践的一些关键要点了，接下来可以慢慢过一下。&lt;/p&gt;
&lt;h3 id=&quot;321-gc触发条件&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#321-gc%E8%A7%A6%E5%8F%91%E6%9D%A1%E4%BB%B6&quot; aria-label=&quot;321 gc触发条件 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2.1 GC触发条件&lt;/h3&gt;
&lt;p&gt;触发条件有以下几种:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;gcTriggerHeap: 当前分配的内存达到一定值就触发GC&lt;/li&gt;
&lt;li&gt;gcTriggerTime: 当一定时间没有执行过GC就触发GC&lt;/li&gt;
&lt;li&gt;gcTriggerCycle: 要求启动新一轮的GC, 已启动则跳过, 手动触发GC的runtime.GC()会使用这个条件&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3211-gctriggerheap&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3211-gctriggerheap&quot; aria-label=&quot;3211 gctriggerheap permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2.1.1 gcTriggerHeap&lt;/h4&gt;
&lt;p&gt;定义可见：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mgc.go#L1147&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mgc.go#gcTriggerHeap&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// gcTriggerHeap indicates that a cycle should be started when&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// the heap size reaches the trigger heap size computed by the&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// controller.&lt;/span&gt;
gcTriggerHeap&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该触发条件为：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mgc.go#L1174&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mgc.go#test()&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Non-atomic access to heap_live for performance. If&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// we are going to trigger on this, this thread just&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// atomically wrote heap_live anyway and we&apos;ll see our&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// own write.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;heap_live &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gc_trigger&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;memstats&lt;/code&gt;在下文Profile里会&lt;a href=&quot;#ID_MEMSTATS&quot;&gt;提到&lt;/a&gt;，这里先不展开。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go#L126&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mstats.go#heap_live&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// heap_live is the number of bytes considered live by the GC.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
heap_live &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;附带提一个&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go#L139&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mstats.go#heap_marked&lt;/a&gt;，后面会用到：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// heap_marked is the number of bytes marked by the previous&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// GC. After mark termination, heap_live == heap_marked, but&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
heap_marked &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go#L100&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mstats.go#gc_trigger&lt;/a&gt;：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// gc_trigger is the heap size that triggers marking.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
gc_trigger &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;gc_trigger&lt;/code&gt;是一个浮动值，根据runtime的状态时时变化的，其计算如下：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mgc.go#L563&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mgc.go#endCycle()&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// 常量，用来调整后续的触发偏移值&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; triggerGain &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 目标增长率，gcpercent来自于环境变量GOGC&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// GOGC是一个1-100的数字，如果没有这个环境变量的话，默认是100，即目标增长率为1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 如果GOGC是off，则值为-1&lt;/span&gt;
goalGrowthRatio &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gcpercent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 实际增长率，（当前存活的量 / 上一次GC标记存活的量）- 1&lt;/span&gt;
actualGrowthRatio &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;heap_live&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;heap_marked&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// GC标记阶段的耗时（因为endCycle是在Mark Termination阶段调用的）&lt;/span&gt;
assistDuration &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;nanotime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;markStartTime

&lt;span class=&quot;token comment&quot;&gt;// GC标记阶段的CPU占用率, 目标值gcBackgroundUtilization是一个常量0.25&lt;/span&gt;
utilization &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; gcBackgroundUtilization
&lt;span class=&quot;token comment&quot;&gt;// assistTime是G辅助GC标记对象所使用的时间合计 (nanosecnds spent in mutator assists during this cycle)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; assistDuration &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// 额外的CPU占用率 = 辅助GC标记对象的总时间 / (GC标记使用时间 * P的数量)&lt;/span&gt;
    utilization &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;assistTime&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;float64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;assistDuration&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gomaxprocs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 触发系数偏移值 = 目标增长率 - 原触发系数 - CPU占用率 / 目标CPU占用率 * (实际增长率 - 原触发系数)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// 参数的分析:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//     实际增长率越大, 触发系数偏移值越小, 小于0时下次触发GC会提早&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//     CPU占用率越大, 触发系数偏移值越小, 小于0时下次触发GC会提早&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//     原触发系数越大, 触发系数偏移值越小, 小于0时下次触发GC会提早&lt;/span&gt;
triggerError &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; goalGrowthRatio &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;triggerRatio &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; utilization&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;gcGoalUtilization&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;actualGrowthRatio&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;triggerRatio&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// 根据偏移值调整触发系数, 每次只调整偏移值的一半（渐进式调整）&lt;/span&gt;
triggerRatio &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;triggerRatio &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; triggerGain&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;triggerError&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;GOGC&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;公式中的&lt;code class=&quot;language-text&quot;&gt;目标增长率&lt;/code&gt;源于环境变量&lt;code class=&quot;language-text&quot;&gt;GOGC&lt;/code&gt;，取值范围1-100，如果没有设置的话默认为100，增加它的值可以减少GC的触发。设置&lt;code class=&quot;language-text&quot;&gt;GOGC=off&lt;/code&gt;可以关闭GC。&lt;/p&gt;
&lt;p&gt;见：&lt;a href=&quot;https://golang.org/pkg/runtime/#hdr-Environment_Variables&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables#GOGC&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The GOGC variable sets the initial garbage collection target percentage. A collection is triggered when the ratio of freshly allocated data to live data remaining after the previous collection reaches this percentage. The default is GOGC=100. Setting GOGC=off disables the garbage collector entirely. The runtime/debug package’s SetGCPercent function allows changing this percentage at run time. See &lt;a href=&quot;https://golang.org/pkg/runtime/debug/#SetGCPercent&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;https://golang.org/pkg/runtime/debug/#SetGCPercent&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id=&quot;3212-gctriggertime&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3212-gctriggertime&quot; aria-label=&quot;3212 gctriggertime permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2.1.2 gcTriggerTime&lt;/h4&gt;
&lt;p&gt;定义可见：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mgc.go#L1152&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mgc.go#gcTriggerTime&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// gcTriggerTime indicates that a cycle should be started when&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// it&apos;s been more than forcegcperiod nanoseconds since the&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// previous GC cycle.&lt;/span&gt;
gcTriggerTime&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该触发条件为：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mgc.go#L1180&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mgc.go#test()&lt;/a&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;lastgc &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;atomic&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Load64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;memstats&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;last_gc_nanotime&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// var forcegcperiod int64 = 2 * 60 * 1e9，即两分钟&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; lastgc &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;now&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;lastgc &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; forcegcperiod&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果2分钟内没有执行过GC就会强制触发。&lt;/p&gt;
&lt;h4 id=&quot;3213-gctriggercycle&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3213-gctriggercycle&quot; aria-label=&quot;3213 gctriggercycle permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2.1.3 gcTriggerCycle&lt;/h4&gt;
&lt;p&gt;定义可见：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mgc.go#L1157&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mgc.go#gcTriggerCycle&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;手动调用&lt;code class=&quot;language-text&quot;&gt;runtime.GC()&lt;/code&gt;进行触发：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mgc.go#L1022&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;mgc.go#GC()&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;33-其他概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-%E5%85%B6%E4%BB%96%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;33 其他概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 其他概念&lt;/h2&gt;
&lt;p&gt;其他GC相关的细节及概念可以参见之前提到的中文博客，这里就不展开了。基本上GC的逻辑和里面的概念都大同小异。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;三色的定义（黑、灰、白）&lt;/li&gt;
&lt;li&gt;写屏障（Write Barrier）&lt;/li&gt;
&lt;li&gt;辅助GC（mutator assist）&lt;/li&gt;
&lt;li&gt;根对象&lt;/li&gt;
&lt;li&gt;标记队列&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;5-profile-id_profile&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-profile-id_profile&quot; aria-label=&quot;5 profile id_profile permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. Profile {#ID_PROFILE}&lt;/h1&gt;
&lt;p&gt;Go语言官方提供的Profile相关工具相当的丰富，能从各种角度和层面满足开发者的需求，因此在我们整理这块知识点的时候，也需要横向全部了解下，方便后续根据不同的应用场景选用对应的技术。&lt;/p&gt;
&lt;p&gt;可选用的Profile技术/工具有：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align=&quot;left&quot;&gt;工具&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;是否实时&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;应用场景&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;是否侵入&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;时效&lt;/th&gt;
&lt;th align=&quot;left&quot;&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID_PROF_READMEMSTATS&quot;&gt;ReadMemStats&lt;/a&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;实时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;指标监控&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;是&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间点&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;调用接口，将内存相关统计信息读入到一个对象内，可自由使用该对象内的统计数据&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID_PROF_PPROF&quot;&gt;pprof&lt;/a&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;离线&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;事后分析&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;是&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间点&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;- 在代码中调用接口输出内存profile&lt;br/&gt;- 输出的数据可以通过专门的工具事后分析&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID_PROF_PPROF_WEB&quot;&gt;pprof web&lt;/a&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;实时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;在线调试&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;是&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间点&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;在代码中嵌入pprof的HTTP相关代码，然后可以：&lt;br/&gt;- 在浏览器中的对应endpoint获得到对应的profile信息&lt;br/&gt;- 在专门的工具中指向HTTP的endpoint，获得实时的分析结果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID_PROF_TRACE&quot;&gt;trace&lt;/a&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;离线&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;事后分析&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;是&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间段&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;- 在代码中开启trace以及关闭trace，输出数据&lt;br/&gt;- 输出的数据可以通过专门工具事后分析查看&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align=&quot;left&quot;&gt;&lt;a href=&quot;#ID_PORF_DEBUG&quot;&gt;GODEBUG&lt;/a&gt;&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;实时&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;在线调试&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;否&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;时间点&lt;/td&gt;
&lt;td align=&quot;left&quot;&gt;- 对应用程序无侵入，在启动时带上全局变量即可&lt;br/&gt;- 信息会实时输出在stderr&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;br/&gt;
&lt;p&gt;备注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否实时：
&lt;ul&gt;
&lt;li&gt;实时：可在应用程序活动的同时，对应用程序进行观测&lt;/li&gt;
&lt;li&gt;离线：在应用程序活动时收集数据，产生对应的数据文件，事后（和应用程序不同步）对数据进行解析并观测&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;是否侵入：对应用程序是否有侵入，是否需要修改源代码&lt;/li&gt;
&lt;li&gt;时效：该工具获得到的数据是一个时间点上的数据，还是一个时间段内的数据，对于不同的应用场景来说，这点很重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;P.S&lt;/p&gt;
&lt;p&gt;几篇推荐：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;综合Profiling经验博文：&lt;a href=&quot;https://artem.krylysov.com/blog/2017/03/13/profiling-and-optimizing-go-web-applications/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Profiling and optimizing Go web applications&lt;/a&gt;。写得很好，基本上该覆盖的面都有涉及，通读一遍对于如何检验性能问题，以及一般性的优化经验很有帮助。&lt;/li&gt;
&lt;li&gt;阿里的一篇内存profiling &amp;#x26; debugging文章，也很有帮助：&lt;a href=&quot;https://yq.aliyun.com/articles/573743&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;记一次Golang内存分析——基于go pprof&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;对于交互命令中的一些细节解释得比较清楚：&lt;a href=&quot;http://wudaijun.com/2018/04/go-pprof/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go pprof 性能分析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;火焰图可以看下这篇：&lt;a href=&quot;http://cizixs.com/2017/09/11/profiling-golang-program/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用 pprof 和火焰图调试 golang 应用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;51-metrics&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#51-metrics&quot; aria-label=&quot;51 metrics permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.1 Metrics&lt;/h2&gt;
&lt;p&gt;在使用接口&lt;code class=&quot;language-text&quot;&gt;runtime.ReadMemStats&lt;/code&gt;获得对应的内存统计状态的时候，我们会拿到对应的数据对象&lt;code class=&quot;language-text&quot;&gt;MemStats&lt;/code&gt;，对于这个数据对象的理解是必要的。&lt;/p&gt;
&lt;p&gt;在源码中，对于内存相关的数据统计有两个struct。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Statistics.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// If you edit this structure, also edit type MemStats below.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Their layouts must match exactly.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// For detailed descriptions see the documentation for MemStats.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Fields that differ from MemStats are further documented here.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Many of these fields are updated on the fly, while others are only&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// updated when updatememstats is called.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; mstats &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// A MemStats records statistics about the memory allocator.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; MemStats &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;关于&lt;code class=&quot;language-text&quot;&gt;memstats&lt;/code&gt;与&lt;code class=&quot;language-text&quot;&gt;MemStats&lt;/code&gt;的区别，第一次读代码的人肯定会有困惑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它们都是定义在同一个源码文件中&lt;/li&gt;
&lt;li&gt;字段基本一致（命名有点不同，以及memstats稍微多了几个字段，例如&lt;code class=&quot;language-text&quot;&gt;heap_live&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;heap_marked&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要理解了Go语言的命名规范就不会迷惑了，大写的是对外暴露的，小写的是不对外暴露的，而且获取统计数据的接口&lt;code class=&quot;language-text&quot;&gt;runtime.ReadMemStats&lt;/code&gt;给出的数据类型是&lt;code class=&quot;language-text&quot;&gt;MemStats&lt;/code&gt;。因此，&lt;code class=&quot;language-text&quot;&gt;MemStats&lt;/code&gt;是提供外部使用者观测统计数据的类型，而&lt;code class=&quot;language-text&quot;&gt;memstats&lt;/code&gt;则是在Go内部运行使用的类型。一般来说，作为开发者，只需要阅读&lt;code class=&quot;language-text&quot;&gt;MemStats&lt;/code&gt;的注释，理解这个对象即可。&lt;/p&gt;
&lt;h3 id=&quot;memstats-id_memstats_export&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#memstats-id_memstats_export&quot; aria-label=&quot;memstats id_memstats_export permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;MemStats {#ID_MEMSTATS_EXPORT}&lt;/h3&gt;
&lt;p&gt;这个结构体会在下面做一个简单翻译，需要完整注释及理解的，请查阅源码：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go#L145&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/mstats.go#MemStats@1.12&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;翻译内容因为过长，放在下面的&lt;a href=&quot;#ID_APP_MEMSTATS&quot;&gt;资料&lt;/a&gt;部分里。&lt;/p&gt;
&lt;p&gt;行文中就列出比较常用的Metrics，方便阅览：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Alloc
&lt;ul&gt;
&lt;li&gt;堆内存大小（bytes）&lt;/li&gt;
&lt;li&gt;注意该值和HeapAlloc一致，因此HeapAlloc就不需要了&lt;/li&gt;
&lt;li&gt;需要观察平滑度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(TotalAlloc.now - TotalAlloc.prev) / CollectInterval
&lt;ul&gt;
&lt;li&gt;采样间隔期间内存增长量（bytes）&lt;/li&gt;
&lt;li&gt;该数值需要采样后自行计算，稍微麻烦点&lt;/li&gt;
&lt;li&gt;需要观察平滑度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mallocs - Frees
&lt;ul&gt;
&lt;li&gt;存活的堆内存对象数量&lt;/li&gt;
&lt;li&gt;需要观察平滑度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NextGC
&lt;ul&gt;
&lt;li&gt;下一次GC的触发堆内存容量&lt;/li&gt;
&lt;li&gt;需要观察平滑度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(PauseTotalNs.now - PauseTotalNs.prev) / CollectInterval
&lt;ul&gt;
&lt;li&gt;采样间隔期间GC暂停时长&lt;/li&gt;
&lt;li&gt;该数值需要采样后自行计算，稍微麻烦点&lt;/li&gt;
&lt;li&gt;需要观察平滑度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;(NumGC.now - NumGC.prev) / CollectInterval
&lt;ul&gt;
&lt;li&gt;采样间隔期间GC次数&lt;/li&gt;
&lt;li&gt;该数值需要采样后自行计算，稍微麻烦点&lt;/li&gt;
&lt;li&gt;需要观察平滑度&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;BySize
&lt;ul&gt;
&lt;li&gt;这项可选，如果对应用程序中小于32K的对象的分布敏感的话，可以做一下监控&lt;/li&gt;
&lt;li&gt;Size标识span的大小&lt;/li&gt;
&lt;li&gt;Mallocs - Frees计算span中存活的对象个数&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;memstats-id_memstats&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#memstats-id_memstats&quot; aria-label=&quot;memstats id_memstats permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;memstats {#ID_MEMSTATS}&lt;/h3&gt;
&lt;p&gt;大部分的数据同：&lt;a href=&quot;#ID_MEMSTATS_EXPORT&quot;&gt;MemStats&lt;/a&gt;，不同的是&lt;code class=&quot;language-text&quot;&gt;// Statistics below here are not exported to MemStats directly.&lt;/code&gt;以下的部分没有暴露出来：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Statistics below here are not exported to MemStats directly.&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;有需要可以直接阅读&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go#L78&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/mstats.go#memstats@1.12&lt;/a&gt;中的字段和注释。&lt;/p&gt;
&lt;h3 id=&quot;gcstats&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#gcstats&quot; aria-label=&quot;gcstats permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;GCStats&lt;/h3&gt;
&lt;p&gt;如果仅只需要获取GC相关的Metrics，则可以调用接口：&lt;code class=&quot;language-text&quot;&gt;debug.ReadGCStats&lt;/code&gt;（&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/debug/garbage.go#L31&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;源码&lt;/a&gt;），获得到的结构是：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/debug/garbage.go#L14&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/debug/garbage.go#GCStats@1.12&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;其相关Metrics在&lt;code class=&quot;language-text&quot;&gt;MemStats&lt;/code&gt;里都有，这里就不啰嗦了，直接看上面就好。&lt;/p&gt;
&lt;h2 id=&quot;52-测试用例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#52-%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B&quot; aria-label=&quot;52 测试用例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.2 测试用例&lt;/h2&gt;
&lt;p&gt;测试相关的用例和输出分析都来自：&lt;a href=&quot;https://www.integralist.co.uk/posts/profiling-go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Profiling Go&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;测试用例：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;log&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;os&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// bigBytes allocates 10 sets of 100 megabytes&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bigBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;byte&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	s &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100000000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;s
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		s &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bigBytes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;oh noes&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;53-profile方法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#53-profile%E6%96%B9%E6%B3%95&quot; aria-label=&quot;53 profile方法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3 Profile方法&lt;/h2&gt;
&lt;h3 id=&quot;531-runtimereadmemstats-id_prof_readmemstats&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#531-runtimereadmemstats-id_prof_readmemstats&quot; aria-label=&quot;531 runtimereadmemstats id_prof_readmemstats permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3.1 runtime.ReadMemStats {#ID_PROF_READMEMSTATS}&lt;/h3&gt;
&lt;p&gt;**注意：**在1.9之前的版本中调用&lt;code class=&quot;language-text&quot;&gt;runtime.ReadMemStats&lt;/code&gt;读取内存分析会导致比较长的STW，使用代价会比较高，在1.9及之后的版本中使用就非常安全了，STW的耗时仅&lt;code class=&quot;language-text&quot;&gt;&amp;lt; 25µs&lt;/code&gt;。见：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/13613&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: cheaper alternative to runtime.ReadMemStats #13613&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/commit/4a7cf960c38d72e9f0c6f00e46e013be2a35d56e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: make ReadMemStats STW for &amp;#x3C; 25µs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否实时：是，实时&lt;/li&gt;
&lt;li&gt;应用场景：定时指标监控&lt;/li&gt;
&lt;li&gt;是否侵入：是，需要修改代码&lt;/li&gt;
&lt;li&gt;时效：时间点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用方法直接调用接口就好，非常简单&lt;/li&gt;
&lt;li&gt;获得的数据如何理解和使用可以参见：&lt;a href=&quot;#ID_MEMSTATS_EXPORT&quot;&gt;MemStats&lt;/a&gt;。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;532-runtimepprof-id_prof_pprof&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#532-runtimepprof-id_prof_pprof&quot; aria-label=&quot;532 runtimepprof id_prof_pprof permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3.2 runtime/pprof {#ID_PROF_PPROF}&lt;/h3&gt;
&lt;p&gt;特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否实时：否，离线&lt;/li&gt;
&lt;li&gt;应用场景：事后分析&lt;/li&gt;
&lt;li&gt;是否侵入：是，需要修改代码&lt;/li&gt;
&lt;li&gt;时效：时间点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用：&lt;/p&gt;
&lt;p&gt;调用接口&lt;code class=&quot;language-text&quot;&gt;pprof.WriteHeapProfile(os.Stdout)&lt;/code&gt;获取一个时间点上的内存状态。&lt;/p&gt;
&lt;p&gt;编译执行：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go build -o app &amp;amp;&amp;amp; time ./app &gt; memory.profile&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;分析结果：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool pprof memory.profile&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;分析结果总览：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ (pprof) top
Showing nodes accounting for 95.38MB, 100% of 95.38MB total
      flat  flat%   sum%        cum   cum%
   95.38MB   100%   100%    95.38MB   100%  main.bigBytes /...ain.go (inline)
         0     0%   100%    95.38MB   100%  main.main /.../profiling/main.go
         0     0%   100%    95.38MB   100%  runtime.main /.../runtime/proc.go&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;观察函数细节：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ (pprof) list main.
Total: 95.38MB
ROUTINE ======================== main.bigBytes in /.../go/profiling/main.go
   95.38MB    95.38MB (flat, cum)   100% of Total
         .          .      6:   &quot;runtime/pprof&quot;
         .          .      7:)
         .          .      8:
         .          .      9:// bigBytes allocates 10 sets of 100 megabytes
         .          .     10:func bigBytes() *[]byte {
   95.38MB    95.38MB     11:   s := make([]byte, 100000000)
         .          .     12:   return &amp;amp;s
         .          .     13:}
         .          .     14:
         .          .     15:func main() {
         .          .     16:   for i := 0; i &amp;lt; 10; i++ {
ROUTINE ======================== main.main in /.../code/go/profiling/main.go
         0    95.38MB (flat, cum)   100% of Total
         .          .     12:   return &amp;amp;s
         .          .     13:}
         .          .     14:
         .          .     15:func main() {
         .          .     16:   for i := 0; i &amp;lt; 10; i++ {
         .    95.38MB     17:           s := bigBytes()
         .          .     18:           if s == nil {
         .          .     19:                   log.Println(&quot;oh noes&quot;)
         .          .     20:           }
         .          .     21:   }
         .          .     22:&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;533-runtimepprof-web-id_prof_pprof_web&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#533-runtimepprof-web-id_prof_pprof_web&quot; aria-label=&quot;533 runtimepprof web id_prof_pprof_web permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3.3 runtime/pprof web {#ID_PROF_PPROF_WEB}&lt;/h3&gt;
&lt;p&gt;特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否实时：是，实时&lt;/li&gt;
&lt;li&gt;应用场景：在线调试&lt;/li&gt;
&lt;li&gt;是否侵入：是，需要修改代码&lt;/li&gt;
&lt;li&gt;时效：时间点&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用：&lt;/p&gt;
&lt;p&gt;引入pprof的http包，并启动web服务器：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;net/http/pprof&quot;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
	err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ListenAndServe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0.0.0.0:6060&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;编译运行之后，可以到&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:6060/debug/pprof/&lt;/code&gt;查看输出情况。内存相关在：&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:8080/debug/pprof/heap?debug=1&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果有已经在使用的URL router，需要自定义输出endpoint：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;net/http&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;net/http/pprof&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ResponseWriter&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	w&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Write&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	r &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewServeMux&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HandleFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; message&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HandleFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/debug/pprof/&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pprof&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HandleFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/debug/pprof/cmdline&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pprof&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Cmdline&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HandleFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/debug/pprof/profile&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pprof&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Profile&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HandleFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/debug/pprof/symbol&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pprof&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Symbol&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;HandleFunc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/debug/pprof/trace&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pprof&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Trace&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

	http&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ListenAndServe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;:8080&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;细节分析仍旧使用pprof的命令行工具，输入部分改为URL：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool pprof http://localhost:6060/debug/pprof/heap
Fetching profile over HTTP from http://localhost:6060/debug/pprof/heap
Saved profile in /Users/XXX/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.009.pb.gz
Type: inuse_space
Time: Mar 23, 2019 at 3:13pm (CST)
Entering interactive mode (type &quot;help&quot; for commands, &quot;o&quot; for options)
(pprof)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;本质上，pprof工具其实是从指定的URL下载一份当时的heap信息，然后开始交互分析：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Saved profile in /Users/XXX/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.009.pb.gz&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;进入pprof的交互命令行之后就是常规操作了，这里不再赘述。&lt;/p&gt;
&lt;h3 id=&quot;534-runtimetrace-id_prof_trace&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#534-runtimetrace-id_prof_trace&quot; aria-label=&quot;534 runtimetrace id_prof_trace permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3.4 runtime/trace {#ID_PROF_TRACE}&lt;/h3&gt;
&lt;p&gt;Trace的使用和前几者有显著不同，trace追踪的是一个时间段内程序的行为，且其API并没有对内存等进行区分，也就是说trace函数执行期间，其对Go应用程序进行了全方面的信息采集，包括了CPU、内存、Gorountine等等。&lt;/p&gt;
&lt;p&gt;一般来说Trace的应用场景是&lt;code class=&quot;language-text&quot;&gt;打开思路&lt;/code&gt;：“我感觉应用程序有点问题，但具体问题在哪里暂时还不知道，要不就先trace一下，把所有数据都导出来，然后工具里看看随着时间的应用程序指标变化，然后找找问题”。大致上是这么一个方向。&lt;/p&gt;
&lt;p&gt;实际上这种需求的可能性会很小，一般来说，应用程序的监控会使用API或者聚合工具将Metrics输出并采集，随着时间会进行对应的指标检查。所以一般出问题了，肯定知道问题在哪个领域内，后面如果真的要追细节，那肯定也是用&lt;code class=&quot;language-text&quot;&gt;go tool pprof&lt;/code&gt;而不是trace。所以其实trace的存在意义并不大。&lt;/p&gt;
&lt;p&gt;特性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;是否实时：否，离线&lt;/li&gt;
&lt;li&gt;应用场景：事后分析&lt;/li&gt;
&lt;li&gt;是否侵入：是，需要修改代码&lt;/li&gt;
&lt;li&gt;时效：时间段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;trace&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;os&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Stdout&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; trace&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;编译、运行、输出trace文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go build -o app
$ time ./app &gt; app.trace
$ go tool trace app.trace&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果你想输出一份pprof也能使用的兼容文件，你可以使用 -pprof 选项。使用手册仍旧是命令行help：&lt;a href=&quot;#ID_APP_TRACE_USAGE&quot;&gt;go tool trace usage@1.12&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;解析trace文件：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool trace app.trace
2017/10/29 09:30:40 Parsing trace...
2017/10/29 09:30:40 Serializing trace...
2017/10/29 09:30:40 Splitting trace...
2017/10/29 09:30:40 Opening browser&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;浏览器会自动打开：&lt;code class=&quot;language-text&quot;&gt;http://127.0.0.1:60331&lt;/code&gt;。后续的查看细节这里就不展开了，有兴趣的可以阅读：&lt;a href=&quot;https://www.integralist.co.uk/posts/profiling-go/#7&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Profiling Go &gt; Trace&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;此外，官方的trace包也可以稍微看下：&lt;a href=&quot;https://golang.org/pkg/runtime/trace/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Package trace&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;535-godebuggctrace1-id_porf_debug&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#535-godebuggctrace1-id_porf_debug&quot; aria-label=&quot;535 godebuggctrace1 id_porf_debug permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.3.5 GODEBUG=‘gctrace=1’ {#ID_PORF_DEBUG}&lt;/h3&gt;
&lt;p&gt;在Go程序运行的时候设置全局变量&lt;code class=&quot;language-text&quot;&gt;GODEBUG=gctrace=1&lt;/code&gt;，则可以开始gc状态输出，每次gc之后都会向stderr输出信息。比较常用在初步定位GC问题的时候，或怀疑程序的GC是否消耗了过多的CPU资源等情况。&lt;/p&gt;
&lt;p&gt;文档在官方runtime包：&lt;a href=&quot;https://golang.org/pkg/runtime/#hdr-Environment_Variables&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables#gctrace&lt;/a&gt;。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gctrace: setting gctrace=1 causes the garbage collector to emit a single line to standard
error at each collection, summarizing the amount of memory collected and the
length of the pause. The format of this line is subject to change.
Currently, it is:
	gc # @#s #%: #+#+# ms clock, #+#/#/#+# ms cpu, #-&gt;#-&gt;# MB, # MB goal, # P
where the fields are as follows:
	gc #        the GC number, incremented at each GC
	@#s         time in seconds since program start
	#%          percentage of time spent in GC since program start
	#+...+#     wall-clock/CPU times for the phases of the GC
	#-&gt;#-&gt;# MB  heap size at GC start, at GC end, and live heap
	# MB goal   goal heap size
	# P         number of processors used
The phases are stop-the-world (STW) sweep termination, concurrent
mark and scan, and STW mark termination. The CPU times
for mark/scan are broken down in to assist time (GC performed in
line with allocation), background GC time, and idle GC time.
If the line ends with &quot;(forced)&quot;, this GC was forced by a
runtime.GC() call.

Setting gctrace to any value &gt; 0 also causes the garbage collector
to emit a summary when memory is released back to the system.
This process of returning memory to the system is called scavenging.
The format of this summary is subject to change.
Currently it is:
	scvg#: # MB released  printed only if non-zero
	scvg#: inuse: # idle: # sys: # released: # consumed: # (MB)
where the fields are as follows:
	scvg#        the scavenge cycle number, incremented at each scavenge
	inuse: #     MB used or partially used spans
	idle: #      MB spans pending scavenging
	sys: #       MB mapped from the system
	released: #  MB released to the system
	consumed: #  MB allocated from the system&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;举个例子来说：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gc 31 @1656.509s 0%: 0.010+0.26+0.006 ms clock, 0.085+0/0.33/0.64+0.048 ms cpu, 49-&gt;49-&gt;18 MB, 50 MB goal, 8 P&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;gc 31&lt;/code&gt;：第31次GC&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;@1656.509s&lt;/code&gt;：程序启动至今1656.509秒&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;0%:&lt;/code&gt;：消耗在GC上的CPU为0%&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;0.010+0.26+0.006 ms clock,&lt;/code&gt;：STW清扫、并发标记扫描、STW标记耗时，单位为毫秒（ms）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;0.085+0/0.33/0.64+0.048 ms cpu,&lt;/code&gt;：辅助GC、后台GC、闲置GC耗时，单位为毫秒（ms）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;49-&gt;49-&gt;18 MB,&lt;/code&gt;：GC启动前，完成后，以及存活的堆内存大小&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;50 MB goal,&lt;/code&gt;：下一次GC启动的目标堆内存大小&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;8 P&lt;/code&gt;：该应用程序使用的处理器数量&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;scvg52: inuse: 19, idle: 43, sys: 63, released: 4, consumed: 59 (MB)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;scvg52:&lt;/code&gt;：第52次scavenge循环&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;inuse: 19,&lt;/code&gt;：使用中或部分使用中的spans占用的内存（MB）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;idle: 43,&lt;/code&gt;：处于空闲状态，等待回收的spans占用的内存（MB）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;sys: 63,&lt;/code&gt;：从操作系统申请的内存（MB）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;released: 4&lt;/code&gt;：返还给操作系统的内存（MB）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;consumed: 59 (MB)&lt;/code&gt;：从操作系统申请且已经分配被占用的内存（MB）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;完整的输出例子可以查看：&lt;a href=&quot;#ID_APP_GCTRACE_SAMPLE&quot;&gt;GODEBUG=gctrace=1 sample&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;54-pprof简单使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#54-pprof%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;54 pprof简单使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.4 pprof简单使用&lt;/h2&gt;
&lt;h3 id=&quot;541-pprof-help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#541-pprof-help&quot; aria-label=&quot;541 pprof help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.4.1 pprof help&lt;/h3&gt;
&lt;p&gt;pprof使用分两部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在命令行中，以&lt;code class=&quot;language-text&quot;&gt;go tool pprof ...&lt;/code&gt;的方式直接将分析结果输出&lt;/li&gt;
&lt;li&gt;或在命令行中以上面的命令进入到一个pprof内部的交互命令行&lt;code class=&quot;language-text&quot;&gt;(pprof) ...&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一般来说，如果只是对一个比较小的程序做简单的分析，可以选择第一种，直接将所有的关系都输出成图、PDF之类，直接阅读。但对于比较复杂的程序，就更推荐第二种方式，进入交互界面，根据自己的需求，进行细致的分析。&lt;/p&gt;
&lt;p&gt;这里要提下两者的帮助信息如何取得，众所周知，Go的文档实在是不怎么样。所以这两者的使用，基本上都靠命令+help打印出来的内容进行指导。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;go tool pprof&lt;/code&gt;可以不带任何参数进行直接执行，就会打印出使用手册：&lt;a href=&quot;#ID_APP_PPROF_USAGE&quot;&gt;go tool pprof usage@1.12&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;(pprof) help&lt;/code&gt;可以打印出交互命令的使用手册：&lt;a href=&quot;#ID_APP_PPROF_HELP&quot;&gt;(pprof) help@1.12&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;542-常用交互命令&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#542-%E5%B8%B8%E7%94%A8%E4%BA%A4%E4%BA%92%E5%91%BD%E4%BB%A4&quot; aria-label=&quot;542 常用交互命令 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.4.2 常用交互命令&lt;/h3&gt;
&lt;p&gt;所谓的交互命令，是指在命令行中执行&lt;code class=&quot;language-text&quot;&gt;go tool pprof ...&lt;/code&gt;之后，进入了一个以&lt;code class=&quot;language-text&quot;&gt;(pprof) ...&lt;/code&gt;开头的命令行。在这里可以执行一系列pprof的子命令，进行对应的内存和CPU分析。&lt;/p&gt;
&lt;p&gt;常用的有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;top：列出以降序排列的所有高消耗入口&lt;/li&gt;
&lt;li&gt;topN：基本同上，但只列出最高的N个入口&lt;/li&gt;
&lt;li&gt;list &amp;#x3C;function_regex&gt;：按照函数名对消耗入口进行过滤，找到精确的定位信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;list的help信息如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;(pprof) help list
Output annotated source for functions matching regexp
  Usage:
    list&amp;lt;func_regex|address&gt; [-focus_regex]* [-ignore_regex]*
    Include functions matching func_regex, or including the address specified.
    Include samples matching focus_regex, and exclude ignore_regex.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完整的命令可以查看：&lt;a href=&quot;#ID_APP_PPROF_HELP&quot;&gt;(pprof) help@1.12&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&quot;543-sample_index-id_prof_sample_index&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#543-sample_index-id_prof_sample_index&quot; aria-label=&quot;543 sample_index id_prof_sample_index permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.4.3 sample_index {#ID_PROF_SAMPLE_INDEX}&lt;/h3&gt;
&lt;p&gt;在使用&lt;code class=&quot;language-text&quot;&gt;go tool pprof ...&lt;/code&gt;进行对应的分析交互的时候，默认的内存观察视角是：&lt;code class=&quot;language-text&quot;&gt;inuse_space&lt;/code&gt;，也就是在使用中（当前占用）的内存空间的视角。但某些时候也需要以其他视角进行观察分析，就需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在命令行执行命令的时候（进入交互之前）就进行指定：&lt;code class=&quot;language-text&quot;&gt;go tool pprof -alloc_space ...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;或者在进入pprof的交互命令行之后，进行切换：&lt;code class=&quot;language-text&quot;&gt;(pprof) sample_index = alloc_space&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可用的视角选项如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;  Legacy convenience options:
   -inuse_space           Same as -sample_index=inuse_space
   -inuse_objects         Same as -sample_index=inuse_objects
   -alloc_space           Same as -sample_index=alloc_space
   -alloc_objects         Same as -sample_index=alloc_objects
   -total_delay           Same as -sample_index=delay
   -contentions           Same as -sample_index=contentions
   -mean_delay            Same as -mean -sample_index=delay&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;sample_index命令帮助：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;(pprof) help sample_index
Sample value to report (0-based index or name)
Profiles contain multiple values per sample.
Use sample_index=i to select the ith value (starting at 0).
Or use sample_index=name, with name in [alloc_objects alloc_space inuse_objects inuse_space].&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;完整的列表，及其他的选项，可以查看：&lt;a href=&quot;#ID_APP_PPROF_USAGE&quot;&gt;go tool pprof usage@1.12&lt;/a&gt;以及&lt;a href=&quot;#ID_APP_PPROF_HELP&quot;&gt;(pprof) help@1.12&lt;/a&gt;。&lt;/p&gt;
&lt;h4 id=&quot;pprof无输出&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#pprof%E6%97%A0%E8%BE%93%E5%87%BA&quot; aria-label=&quot;pprof无输出 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;pprof无输出&lt;/h4&gt;
&lt;p&gt;根据上面所述，如果你指定的视角当前没有任何可分析的东西，pprof会对此进行提示：&lt;code class=&quot;language-text&quot;&gt;No samples were found with the default sample value type.&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool pprof http://127.0.0.1:8080/debug/pprof/heap
Fetching profile over HTTP from http://127.0.0.1:8080/debug/pprof/heap
Saved profile in /Users/XXX/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.005.pb.gz
Type: inuse_space
Time: Mar 22, 2019 at 4:43pm (CST)
No samples were found with the default sample value type.
Try &quot;sample_index&quot; command to analyze different sample values.
Entering interactive mode (type &quot;help&quot; for commands, &quot;o&quot; for options)
(pprof) sample_index = alloc_space
(pprof) top5
Showing nodes accounting for 6.35GB, 100% of 6.35GB total
      flat  flat%   sum%        cum   cum%
    6.35GB   100%   100%     6.35GB   100%  main.channelFactory.func1&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/24443#issuecomment-374141183&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;cmd/go: tool pprof gives no samples #24443&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/pprof/issues/182&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;-help output does not mention all flags #182&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/pprof/pull/202/files/b27144b31b62977102786aa81d8786f8af5709ca&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Add legacy options to command-line help #202&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;544-输出&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#544-%E8%BE%93%E5%87%BA&quot; aria-label=&quot;544 输出 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.4.4 输出&lt;/h3&gt;
&lt;h4 id=&quot;静态资源&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90&quot; aria-label=&quot;静态资源 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;静态资源&lt;/h4&gt;
&lt;p&gt;使用如下命令将一个profile文件或URL的分析结果导出成一个可打开的静态资源：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;go tool pprof -png http://localhost:6060/debug/pprof/heap &gt; data.png&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可选的类型有：&lt;code class=&quot;language-text&quot;&gt;-png&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;-gif&lt;/code&gt;、&lt;code class=&quot;language-text&quot;&gt;-svg&lt;/code&gt;，等等，甚至是&lt;code class=&quot;language-text&quot;&gt;-pdf&lt;/code&gt;。所有的可选项可以查看：&lt;a href=&quot;#ID_APP_PPROF_USAGE&quot;&gt;go tool pprof usage@1.12&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;默认输出的是&lt;code class=&quot;language-text&quot;&gt;inuse_space&lt;/code&gt;的分析，可以进行调整，参见：&lt;a href=&quot;#ID_PROF_SAMPLE_INDEX&quot;&gt;sample_index&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;图中的格子越大，表示其消耗的内存越多。&lt;/p&gt;
&lt;h4 id=&quot;web-ui&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#web-ui&quot; aria-label=&quot;web ui permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;WEB UI&lt;/h4&gt;
&lt;p&gt;从&lt;code class=&quot;language-text&quot;&gt;Go 1.10&lt;/code&gt;开始，pprof也提供了方法将分析结果展示到WEB UI中，方便交互和查看。&lt;code class=&quot;language-text&quot;&gt;(pprof) ...&lt;/code&gt;的交互命令行需要熟悉命令，&lt;code class=&quot;language-text&quot;&gt;静态资源&lt;/code&gt;则比较难以处理复杂的程序。WEB UI在交互这方面应该是最佳选项了。&lt;/p&gt;
&lt;p&gt;使用：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;pprof -http=:8899 http://localhost:8080/debug/pprof/heap
Fetching profile over HTTP from http://localhost:8080/debug/pprof/heap
Saved profile in /Users/XXX/pprof/pprof.alloc_objects.alloc_space.inuse_objects.inuse_space.008.pb.gz&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这样就开启并保持了一个WEB进程，只需要在浏览器中打开：&lt;code class=&quot;language-text&quot;&gt;http://localhost:8899/ui/&lt;/code&gt;，就可以进行交互和观察了。&lt;/p&gt;
&lt;p&gt;资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://rakyll.org/pprof-ui/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pprof user interface&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;545-pprofprotoprofileproto&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#545-pprofprotoprofileproto&quot; aria-label=&quot;545 pprofprotoprofileproto permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.4.5 pprof/proto/profile.proto&lt;/h3&gt;
&lt;p&gt;pprof输出、保存下来的profile文件是一个protobuf二进制文件，其结构描述在：&lt;a href=&quot;https://github.com/google/pprof/blob/master/proto/profile.proto&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pprof/proto/profile.proto&lt;/a&gt;。有兴趣的可以查阅下，可以更深入理解profile里保存了什么。&lt;/p&gt;
&lt;h2 id=&quot;55-复杂范例实践&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#55-%E5%A4%8D%E6%9D%82%E8%8C%83%E4%BE%8B%E5%AE%9E%E8%B7%B5&quot; aria-label=&quot;55 复杂范例实践 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5.5 复杂范例实践&lt;/h2&gt;
&lt;p&gt;代码放在github：&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice/blob/master/golang/src/experiment/memory/memory.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;experiment/memory/memory.go&lt;/a&gt;。github上的代码可以看到最新的更新，不过需要打开新的页面稍微麻烦点。&lt;/p&gt;
&lt;p&gt;当前页面会放一份gist，方便直接查看：&lt;a href=&quot;#ID_APP_MEMORY_SAMPLE&quot;&gt;experiment/memory/memory.go&lt;/a&gt;，但可能更新不及时。&lt;/p&gt;
&lt;p&gt;使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;go run memory.go 参数…：运行内存泄露脚本，不带任何命令行输出&lt;/li&gt;
&lt;li&gt;go run memory.go 参数… &lt;code class=&quot;language-text&quot;&gt;-stats=true&lt;/code&gt;：运行内存泄露脚本，在命令行输出&lt;code class=&quot;language-text&quot;&gt;runtime.MemStats&lt;/code&gt;的信息&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;GODEBUG=gctrace=1&lt;/code&gt; go run memory.go 参数…：运行内存泄露脚本，在命令行输出gc统计信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;参数说明：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;mode：三种模式
&lt;ul&gt;
&lt;li&gt;FIXED_SPAN：泄露内存为固定长度的span&lt;/li&gt;
&lt;li&gt;RANDOM_SPAN：泄露内存为随机浮动长度的span，但不会是大对象&lt;/li&gt;
&lt;li&gt;LARGE_OBJ：泄露内存为1MB到2MB之间的大对象&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;class：指定span的class id，具体的class id对应的内存大小可以查看：&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/sizeclasses.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/sizeclasses.go&lt;/a&gt;。注意，这个参数只在&lt;code class=&quot;language-text&quot;&gt;FIXED_SPAN&lt;/code&gt;下生效&lt;/li&gt;
&lt;li&gt;interval：每个goroutine每隔多久进行一次内存泄露，实际运行的时候会上下进行一些浮动，防止大量goroutine在同一时间点进行操作&lt;/li&gt;
&lt;li&gt;goroutine：同时运行的gorountine数量，越多内存泄露越快&lt;/li&gt;
&lt;li&gt;size：每个goroutine每次tick泄露的内存量，虽然每次泄露的对象大小是一个span大小，但泄露的内存量是固定的 = span大小 * span数量&lt;/li&gt;
&lt;li&gt;edge：Go进程允许的泄露内存总量，超过这个量之后，脚本会释放对之前泄露对象的指针，内存就会被回收&lt;/li&gt;
&lt;li&gt;stats：布尔值，附上true之后会在命令行里打印&lt;code class=&quot;language-text&quot;&gt;runtime.MemStats&lt;/code&gt;的信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;h2 id=&quot;参考链接-id_app_links&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%8F%82%E8%80%83%E9%93%BE%E6%8E%A5-id_app_links&quot; aria-label=&quot;参考链接 id_app_links permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;参考链接 {#ID_APP_LINKS}&lt;/h2&gt;
&lt;h3 id=&quot;内存分配&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D&quot; aria-label=&quot;内存分配 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;内存分配&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/malloc.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/malloc.go@1.12&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/sizeclasses.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/sizeclasses.go@1.12&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/wiki/CompilerOptimizations#escape-analysis-and-inlining&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Escape analysis and Inlining&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/10460&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: 512GB memory limitation #10460&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/commit/2b415549b813ba36caafa34fc34d72e47ee8335c&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: use sparse mappings for the heap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yq.aliyun.com/blog/573819&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang源码探索(三) GC的实现原理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://povilasv.me/go-memory-management/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Memory Management&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/27807169&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang 内存管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.learngoprogramming.com/a-visual-guide-to-golang-memory-allocator-from-ground-up-e132258453ed&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;A visual guide to Go Memory Allocator from scratch (Golang)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/29216091&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;图解 TCMalloc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/29415507&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TCMalloc分析 - 如何减少内存碎片&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://goog-perftools.sourceforge.net/doc/tcmalloc.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;TCMalloc : Thread-Caching Malloc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/28484133&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go语言的栈空间管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/28348712&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;剖析使Go语言高效的5个特性(3/5): 垃圾回收机制&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/28357162&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;剖析使Go语言高效的5个特性(5/5): Goroutine的栈管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.infoq.cn/article/IEhRLwmmIM7-11RYaLHR&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;图解 Go 内存分配器&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;内存回收&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98%E5%9B%9E%E6%94%B6&quot; aria-label=&quot;内存回收 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;内存回收&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go#L145&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/mstats.go#MemStats@1.12&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/pkg/runtime/#hdr-Environment_Variables&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables#GOGC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://talks.golang.org/2015/go-gc.pdf&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go GC: Latency Problem Solved&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://making.pusher.com/golangs-real-time-gc-in-theory-and-practice/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang’s Real-time GC in Theory and Practice&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/ismmkeynote&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Getting to Go: The Journey of Go’s Garbage Collector&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/23044&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;proposal: runtime: add a mechanism for specifying a minimum target heap size #23044&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/18155&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: latency in sweep assists when there’s no garbage #18155&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://legendtkl.com/2017/04/28/golang-gc/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang 垃圾回收剖析&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhuanlan.zhihu.com/p/54236970&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go的内存管理缺陷?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;内存profile&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98profile&quot; aria-label=&quot;内存profile permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;内存Profile&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/mstats.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/13613&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: cheaper alternative to runtime.ReadMemStats #13613&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/commit/4a7cf960c38d72e9f0c6f00e46e013be2a35d56e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;runtime: make ReadMemStats STW for &amp;#x3C; 25µs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/profiling-go-programs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Profiling Go Programs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/doc/diagnostics.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The Go Programming Language &gt; Diagnostics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://golang.org/pkg/runtime/#hdr-Environment_Variables&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Environment Variables#GODEBUG&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/pprof&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;google/pprof&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/pprof/blob/master/proto/profile.proto&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pprof/proto/profile.proto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.integralist.co.uk/posts/profiling-go/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Profiling Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://jvns.ca/blog/2017/09/24/profiling-go-with-pprof/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Profiling Go programs with pprof&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yq.aliyun.com/articles/573743&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;记一次Golang内存分析——基于go pprof&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lrita.github.io/2017/05/26/golang-memory-pprof/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;golang 内存分析/动态追踪&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.to/davidsbond/golang-debugging-memory-leaks-using-pprof-5di8&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang: Debugging memory leaks using pprof&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://artem.krylysov.com/blog/2017/03/13/profiling-and-optimizing-go-web-applications/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Profiling and optimizing Go web applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://povilasv.me/prometheus-go-metrics/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Exploring Prometheus Go client metrics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sheepbao.github.io/post/golang_debug_gctrace/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;golang开启GODEBUG=gctrace=1 显示信息的含义&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/issues/24443#issuecomment-374141183&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;cmd/go: tool pprof gives no samples #24443&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/pprof/issues/182&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;-help output does not mention all flags #182&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/google/pprof/pull/202/files/b27144b31b62977102786aa81d8786f8af5709ca&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Add legacy options to command-line help #202&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rakyll.org/pprof-ui/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;pprof user interface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://cizixs.com/2017/09/11/profiling-golang-program/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用 pprof 和火焰图调试 golang 应用&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;其他&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%85%B6%E4%BB%96&quot; aria-label=&quot;其他 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;其他&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/9bf36aa82f90&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Linux 内存管理中的 RSS 和 VSZ 是什么意思？&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://studygolang.com/articles/11627&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Golang源码探索(二) 协程的实现原理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/wiki/Performance&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;golang/go wiki &gt; Debugging performance issues in Go programs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;gosrcruntimemstatsgomemstats112-id_app_memstats&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#gosrcruntimemstatsgomemstats112-id_app_memstats&quot; aria-label=&quot;gosrcruntimemstatsgomemstats112 id_app_memstats permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/mstats.go#L145&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/mstats.go#MemStats@1.12&lt;/a&gt; {#ID_APP_MEMSTATS}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// A MemStats records statistics about the memory allocator.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; MemStats &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 常规统计。&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Alloc 是已分配的堆内存对象占用的内存量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这个值和 HeapAlloc 一致（看下面）。&lt;/span&gt;
	Alloc &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// TotalAlloc 是累积的堆内存对象分配的内存量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// TotalAlloc 会随着堆内存对象分配慢慢增长，但不像 Alloc 和 HeapAlloc，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这个值不会随着对象被释放而缩小。&lt;/span&gt;
	TotalAlloc &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Sys 是从 OS 获得的内存总量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// Sys 是下面列出的 XSys 字段的综合。Sys 维护着为 Go 运行时预留的虚拟内存空间地址，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 里面包含了：堆、栈，以及其他内部数据结构。&lt;/span&gt;
	Sys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Lookups 是 runtime 执行的指针查询的数量。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这主要在针对 runtime 内部进行 debugging 的时候比较有用。&lt;/span&gt;
	Lookups &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Mallocs 是累积被分配的堆内存对象数量。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 存活堆内存对象数量是 Mallocs - Frees。&lt;/span&gt;
	Mallocs &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Frees 是累积被释放掉的堆内存对象数量。&lt;/span&gt;
	Frees &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// 堆内存统计。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 理解堆内存统计需要一些 Go 是如何管理内存的知识。Go 将堆内存虚拟内存空间以 &quot;spans&quot; 为单位进行分割。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// spans 是 8K（或更大）的连续内存空间。一个 span 可能会在以下三种状态之一：&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 一个 &quot;空闲 idle&quot; 的 span 内部不含任何对象或其他数据。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 占用物理内存空间的空闲状态 span 可以被释放回 OS（但虚拟内存空间不会），&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 或者也可以被转化成为 &quot;使用中 in use&quot; 或 &quot;堆栈 stack&quot; 状态。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 一个 &quot;使用中 in use&quot; span 包含了至少一个堆内存对象且可能还有富余的空间可以分配更多的堆内存对象。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 一个 &quot;堆栈 stack&quot; span 是被用作 goroutine stack 的 内存空间。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 堆栈状态的 span 不被视作是堆内存的一部分。一个 span 可以在堆内存和栈内存之间切换；&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 但不可能同时作为两者。&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// HeapAlloc 是已分配的堆内存对象占用的内存量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// &quot;已分配&quot;的堆内存对象包含了所有可达的对象，以及所有垃圾回收器已知但仍未回收的不可达对象。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 确切的说，HeapAlloc 随着堆内存对象分配而增长，并随着内存清理、不可达对象的释放而缩小。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 清理会随着 GC 循环渐进发生，所有增长和缩小这两个情况是同时存在的，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 作为结果 HeapAlloc 的变动趋势是平滑的（与传统的 stop-the-world 型垃圾回收器的锯齿状趋势成对比）。&lt;/span&gt;
	HeapAlloc &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// HeapSys 是堆内存从 OS 获得的内存总量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// HeapSys 维护着为堆内存而保留的虚拟内存空间。这包括被保留但尚未使用的虚拟内存空间，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这部分是不占用实际物理内存的，但趋向于缩小，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 和那些占用物理内存但后续因不再使用而释放回 OS 的虚拟内存空间一样。（查看 HeapReleased 作为校对）&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// HeapSys 用来评估堆内存曾经到过的最大尺寸。&lt;/span&gt;
	HeapSys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// HeapIdle 是处于&quot;空闲状态（未使用）&quot;的 spans 占用的内存总量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 空闲状态的 spans 内部不含对象。这些 spans 可以（并可能已经被）释放回 OS，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 或者它们可以在堆内存分配中重新被利用起来，或者也可以被重新作为栈内存利用起来。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// HeapIdle 减去 HeapReleased 用来评估可以被释放回 OS 的内存总量，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 但因为这些内存已经被 runtime 占用了（已经从 OS 申请下来了）所以堆内存可以重新使用这些内存，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 就不用再向 OS 申请更多内存了。如果这个差值显著大于堆内存尺寸，这意味着近期堆内存存活对象数量存在一个短时峰值。&lt;/span&gt;
	HeapIdle &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// HeapInuse 是处于&quot;使用中&quot;状态的 spans 占用的内存总量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 使用中的 spans 内部存在至少一个对象。这些 spans 仅可以被用来存储其他尺寸接近的对象。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// HeapInuse 减去 HeapAlloc 用来评估被用来存储特定尺寸对象的内存空间的总量，&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 但目前并没有被使用。这是内存碎片的上界，但通常来说这些内存会被高效重用。&lt;/span&gt;
	HeapInuse &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// HeapReleased 是被释放回 OS 的物理内存总量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这个值计算为已经被释放回 OS 的空闲状态的 spans 堆内存空间，且尚未重新被堆内存分配。&lt;/span&gt;
	HeapReleased &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// HeapObjects 是堆内存中的对象总量。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 和 HeapAlloc 一样，这个值随着对象分配而上涨，随着堆内存清理不可达对象而缩小。&lt;/span&gt;
	HeapObjects &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// 栈内存统计。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 栈内存不被认为是堆内存的一部分，但 runtime 会将一个堆内存中的 span 用作为栈内存，反之亦然。&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// StackInuse 是栈内存使用的 spans 占用的内存总量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 使用中状态的栈内存 spans 其中至少有一个栈内存。这些 spans 只能被用来存储其他尺寸接近的栈内存。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 并不存在 StackIdle，因为未使用的栈内存 spans 会被释放回堆内存（因此被计入 HeapIdle）。&lt;/span&gt;
	StackInuse &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// StackSys 是栈内存从 OS 获得的内存总量（bytes）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// StackSys 是 StackInuse 加上一些为了 OS 线程栈而直接从 OS 获取的内存（应该很小）。&lt;/span&gt;
	StackSys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// 堆外（off-heap）内存统计。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 下列的统计信息描述了并不会从堆内存进行分配的运行时内部（runtime-internal）结构体（通常因为它们是堆内存实现的一部分）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 不像堆内存或栈内存，任何这些结构体的内存分配仅只是为这些结构服务。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这些统计信息对 debugging runtime 内存额外开销非常有用。&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// MSpanInuse 是 mspan 结构体分配的内存量（bytes）。&lt;/span&gt;
	MSpanInuse &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// MSpanSys 是为 mspan 结构体从 OS 申请过来的内存量（bytes）。&lt;/span&gt;
	MSpanSys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// MCacheInuse 是 mcache 结构体分配的内存量（bytes）。&lt;/span&gt;
	MCacheInuse &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// MCacheSys 是为 mcache 结构体从 OS 申请过来的内存量（bytes）。&lt;/span&gt;
	MCacheSys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// BuckHashSys 是用来 profiling bucket hash tables 的内存量（bytes）。&lt;/span&gt;
	BuckHashSys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// GCSys 是在垃圾回收中使用的 metadata 的内存量（bytes）。 &lt;/span&gt;
	GCSys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// OtherSys 是各种各样的 runtime 分配的堆外内存量（bytes）。&lt;/span&gt;
	OtherSys &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// 垃圾回收统计。&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// NextGC 是下一次 GC 循环的目标堆内存尺寸。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 垃圾回收器的目标是保持 HeapAlloc ≤ NextGC。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 在每一轮 GC 循环末尾，下一次循环的目标值会基于当前可达对象数据量以及 GOGC 的值来进行计算。&lt;/span&gt;
	NextGC &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// LastGC 是上一次垃圾回收完成的时间，其值为自 1970 年纸巾的 nanoseconds（UNIX epoch）。&lt;/span&gt;
	LastGC &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// PauseTotalNs 是自程序启动开始，在 GC stop-the-world 中暂停的累积时长，以 nanoseconds 计数。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 在一次 stop-the-world 暂停期间，所有的 goroutines 都会被暂停，仅垃圾回收器在运行。&lt;/span&gt;
	PauseTotalNs &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// PauseNs 是最近的 GC stop-the-world 暂停耗时的环形缓冲区（以 nanoseconds 计数）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 最近一次的暂停耗时在 PauseNs[(NumGC+255)%256] 这个位置。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 通常来说，PauseNs[N%256] 记录着最近第 N%256th 次 GC 循环的暂停耗时。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 在每次 GC 循环中可能会有多次暂停；这是在一次循环中的所有暂停时长的总合。&lt;/span&gt;
	PauseNs &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// PauseEnd 是最近的 GC 暂停结束时间的环形缓冲区，其值为自 1970 年纸巾的 nanoseconds（UNIX epoch）。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这个缓冲区的填充方式和 PauseNs 是一致的。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 每次 GC 循环可能有多次暂停；这个缓冲区记录的是每个循环的最后一次暂停的结束时间。&lt;/span&gt;
	PauseEnd &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// NumGC 是完成过的 GC 循环的数量。&lt;/span&gt;
	NumGC &lt;span class=&quot;token builtin&quot;&gt;uint32&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// NumForcedGC 是应用程序经由调用 GC 函数来强制发起的 GC 循环的数量。&lt;/span&gt;
	NumForcedGC &lt;span class=&quot;token builtin&quot;&gt;uint32&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// GCCPUFraction 是自程序启动以来，应用程序的可用 CPU 时间被 GC 消耗的时长部分。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// GCCPUFraction 是一个 0 和 1 之间的数字，0 代表 GC 并没有消耗该应用程序的任何 CPU。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 一个应用程序的可用 CPU 时间定义为：自应用程序启动以来 GOMAXPROCS 的积分。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 举例来说，如果 GOMAXPROCS 是 2 且应用程序已经运行了 10 秒，那么&quot;可用 CPU 时长&quot;就是 20 秒。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// GCCPUFraction 并未包含写屏障行为消耗的 CPU 时长。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 该值和经由 GODEBUG=gctrace=1 报告出来的 CPU 时长是一致的。 &lt;/span&gt;
	GCCPUFraction &lt;span class=&quot;token builtin&quot;&gt;float64&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// EnableGC 显示 GC 是否被启用了。该值永远为真，即便 GOGC=off 被启用。&lt;/span&gt;
	EnableGC &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// DebugGC 目前并未被使用。&lt;/span&gt;
	DebugGC &lt;span class=&quot;token builtin&quot;&gt;bool&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// BySize 汇报了按大小划分的 span 级别内存分配统计信息。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// BySize[N] 给出了尺寸 S 对象的内存分配统计信息，尺寸大小是：&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// BySize[N-1].Size &amp;lt; S ≤ BySize[N].Size。&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// 这个结构里的数据并未汇报尺寸大于 BySize[60].Size 的内存分配数据。&lt;/span&gt;
	BySize &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;61&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// Size 是当前尺寸级别可容纳的最大对象的 byte 大小。&lt;/span&gt;
		Size &lt;span class=&quot;token builtin&quot;&gt;uint32&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// Mallocs 是分配到这个尺寸级别的堆内存对象的累积数量。&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// 累积分配的内存容量（bytes）可用：Size*Mallocs 进行计算。&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// 当前尺寸级别内存活的对象数量可以用 Mallocs - Frees 进行计算。&lt;/span&gt;
		Mallocs &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// Frees 是当前尺寸级别累积释放的堆内存对象的数量。&lt;/span&gt;
		Frees &lt;span class=&quot;token builtin&quot;&gt;uint64&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;comments-of-gosrcruntimemallocgo112-id_app_malloc&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#comments-of-gosrcruntimemallocgo112-id_app_malloc&quot; aria-label=&quot;comments of gosrcruntimemallocgo112 id_app_malloc permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;comments of &lt;a href=&quot;https://github.com/golang/go/blob/go1.12/src/runtime/malloc.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go/src/runtime/malloc.go@1.12&lt;/a&gt; {#ID_APP_MALLOC}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Memory allocator.
//
// This was originally based on tcmalloc, but has diverged quite a bit.
// http://goog-perftools.sourceforge.net/doc/tcmalloc.html

// The main allocator works in runs of pages.
// Small allocation sizes (up to and including 32 kB) are
// rounded to one of about 70 size classes, each of which
// has its own free set of objects of exactly that size.
// Any free page of memory can be split into a set of objects
// of one size class, which are then managed using a free bitmap.
//
// The allocator&apos;s data structures are:
//
//	fixalloc: a free-list allocator for fixed-size off-heap objects,
//		used to manage storage used by the allocator.
//	mheap: the malloc heap, managed at page (8192-byte) granularity.
//	mspan: a run of pages managed by the mheap.
//	mcentral: collects all spans of a given size class.
//	mcache: a per-P cache of mspans with free space.
//	mstats: allocation statistics.
//
// Allocating a small object proceeds up a hierarchy of caches:
//
//	1. Round the size up to one of the small size classes
//	   and look in the corresponding mspan in this P&apos;s mcache.
//	   Scan the mspan&apos;s free bitmap to find a free slot.
//	   If there is a free slot, allocate it.
//	   This can all be done without acquiring a lock.
//
//	2. If the mspan has no free slots, obtain a new mspan
//	   from the mcentral&apos;s list of mspans of the required size
//	   class that have free space.
//	   Obtaining a whole span amortizes the cost of locking
//	   the mcentral.
//
//	3. If the mcentral&apos;s mspan list is empty, obtain a run
//	   of pages from the mheap to use for the mspan.
//
//	4. If the mheap is empty or has no page runs large enough,
//	   allocate a new group of pages (at least 1MB) from the
//	   operating system. Allocating a large run of pages
//	   amortizes the cost of talking to the operating system.
//
// Sweeping an mspan and freeing objects on it proceeds up a similar
// hierarchy:
//
//	1. If the mspan is being swept in response to allocation, it
//	   is returned to the mcache to satisfy the allocation.
//
//	2. Otherwise, if the mspan still has allocated objects in it,
//	   it is placed on the mcentral free list for the mspan&apos;s size
//	   class.
//
//	3. Otherwise, if all objects in the mspan are free, the mspan
//	   is now &quot;idle&quot;, so it is returned to the mheap and no longer
//	   has a size class.
//	   This may coalesce it with adjacent idle mspans.
//
//	4. If an mspan remains idle for long enough, return its pages
//	   to the operating system.
//
// Allocating and freeing a large object uses the mheap
// directly, bypassing the mcache and mcentral.
//
// Free object slots in an mspan are zeroed only if mspan.needzero is
// false. If needzero is true, objects are zeroed as they are
// allocated. There are various benefits to delaying zeroing this way:
//
//	1. Stack frame allocation can avoid zeroing altogether.
//
//	2. It exhibits better temporal locality, since the program is
//	   probably about to write to the memory.
//
//	3. We don&apos;t zero pages that never get reused.

// Virtual memory layout
//
// The heap consists of a set of arenas, which are 64MB on 64-bit and
// 4MB on 32-bit (heapArenaBytes). Each arena&apos;s start address is also
// aligned to the arena size.
//
// Each arena has an associated heapArena object that stores the
// metadata for that arena: the heap bitmap for all words in the arena
// and the span map for all pages in the arena. heapArena objects are
// themselves allocated off-heap.
//
// Since arenas are aligned, the address space can be viewed as a
// series of arena frames. The arena map (mheap_.arenas) maps from
// arena frame number to *heapArena, or nil for parts of the address
// space not backed by the Go heap. The arena map is structured as a
// two-level array consisting of a &quot;L1&quot; arena map and many &quot;L2&quot; arena
// maps; however, since arenas are large, on many architectures, the
// arena map consists of a single, large L2 map.
//
// The arena map covers the entire possible address space, allowing
// the Go heap to use any part of the address space. The allocator
// attempts to keep arenas contiguous so that large spans (and hence
// large objects) can cross arenas.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;go-tool-pprof-usage112-id_app_pprof_usage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go-tool-pprof-usage112-id_app_pprof_usage&quot; aria-label=&quot;go tool pprof usage112 id_app_pprof_usage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;go tool pprof &lt;a href=&quot;mailto:usage@1.12&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;usage@1.12&lt;/a&gt; {#ID_APP_PPROF_USAGE}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool pprof
usage:

Produce output in the specified format.

   pprof &amp;lt;format&gt; [options] [binary] &amp;lt;source&gt; ...

Omit the format to get an interactive shell whose commands can be used
to generate various views of a profile

   pprof [options] [binary] &amp;lt;source&gt; ...

Omit the format and provide the &quot;-http&quot; flag to get an interactive web
interface at the specified host:port that can be used to navigate through
various views of a profile.

   pprof -http [host]:[port] [options] [binary] &amp;lt;source&gt; ...

Details:
  Output formats (select at most one):
    -callgrind       Outputs a graph in callgrind format
    -comments        Output all profile comments
    -disasm          Output assembly listings annotated with samples
    -dot             Outputs a graph in DOT format
    -eog             Visualize graph through eog
    -evince          Visualize graph through evince
    -gif             Outputs a graph image in GIF format
    -gv              Visualize graph through gv
    -kcachegrind     Visualize report in KCachegrind
    -list            Output annotated source for functions matching regexp
    -pdf             Outputs a graph in PDF format
    -peek            Output callers/callees of functions matching regexp
    -png             Outputs a graph image in PNG format
    -proto           Outputs the profile in compressed protobuf format
    -ps              Outputs a graph in PS format
    -raw             Outputs a text representation of the raw profile
    -svg             Outputs a graph in SVG format
    -tags            Outputs all tags in the profile
    -text            Outputs top entries in text form
    -top             Outputs top entries in text form
    -topproto        Outputs top entries in compressed protobuf format
    -traces          Outputs all profile samples in text form
    -tree            Outputs a text rendering of call graph
    -web             Visualize graph through web browser
    -weblist         Display annotated source in a web browser

  Options:
    -call_tree       Create a context-sensitive call tree
    -compact_labels  Show minimal headers
    -divide_by       Ratio to divide all samples before visualization
    -drop_negative   Ignore negative differences
    -edgefraction    Hide edges below &amp;lt;f&gt;*total
    -focus           Restricts to samples going through a node matching regexp
    -hide            Skips nodes matching regexp
    -ignore          Skips paths going through any nodes matching regexp
    -mean            Average sample value over first value (count)
    -nodecount       Max number of nodes to show
    -nodefraction    Hide nodes below &amp;lt;f&gt;*total
    -noinlines       Ignore inlines.
    -normalize       Scales profile based on the base profile.
    -output          Output filename for file-based outputs
    -prune_from      Drops any functions below the matched frame.
    -relative_percentages Show percentages relative to focused subgraph
    -sample_index    Sample value to report (0-based index or name)
    -show            Only show nodes matching regexp
    -show_from       Drops functions above the highest matched frame.
    -source_path     Search path for source files
    -tagfocus        Restricts to samples with tags in range or matched by regexp
    -taghide         Skip tags matching this regexp
    -tagignore       Discard samples with tags in range or matched by regexp
    -tagshow         Only consider tags matching this regexp
    -trim            Honor nodefraction/edgefraction/nodecount defaults
    -trim_path       Path to trim from source paths before search
    -unit            Measurement units to display

  Option groups (only set one per group):
    cumulative
      -cum             Sort entries based on cumulative weight
      -flat            Sort entries based on own weight
    granularity
      -addresses       Aggregate at the address level.
      -filefunctions   Aggregate at the function level.
      -files           Aggregate at the file level.
      -functions       Aggregate at the function level.
      -lines           Aggregate at the source code line level.

  Source options:
    -seconds              Duration for time-based profile collection
    -timeout              Timeout in seconds for profile collection
    -buildid              Override build id for main binary
    -add_comment          Free-form annotation to add to the profile
                          Displayed on some reports or with pprof -comments
    -diff_base source     Source of base profile for comparison
    -base source          Source of base profile for profile subtraction
    profile.pb.gz         Profile in compressed protobuf format
    legacy_profile        Profile in legacy pprof format
    http://host/profile   URL for profile handler to retrieve
    -symbolize=           Controls source of symbol information
      none                  Do not attempt symbolization
      local                 Examine only local binaries
      fastlocal             Only get function names from local binaries
      remote                Do not examine local binaries
      force                 Force re-symbolization
    Binary                  Local path or build id of binary for symbolization
    -tls_cert             TLS client certificate file for fetching profile and symbols
    -tls_key              TLS private key file for fetching profile and symbols
    -tls_ca               TLS CA certs file for fetching profile and symbols

  Misc options:
   -http              Provide web based interface at host:port.
                      Host is optional and &apos;localhost&apos; by default.
                      Port is optional and a randomly available port by default.
   -tools             Search path for object tools

  Legacy convenience options:
   -inuse_space           Same as -sample_index=inuse_space
   -inuse_objects         Same as -sample_index=inuse_objects
   -alloc_space           Same as -sample_index=alloc_space
   -alloc_objects         Same as -sample_index=alloc_objects
   -total_delay           Same as -sample_index=delay
   -contentions           Same as -sample_index=contentions
   -mean_delay            Same as -mean -sample_index=delay

  Environment Variables:
   PPROF_TMPDIR       Location for saved profiles (default $HOME/pprof)
   PPROF_TOOLS        Search path for object-level tools
   PPROF_BINARY_PATH  Search path for local binary files
                      default: $HOME/pprof/binaries
                      searches $name, $path, $buildid/$name, $path/$buildid
   * On Windows, %USERPROFILE% is used instead of $HOME&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;pprof-help112-id_app_pprof_help&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#pprof-help112-id_app_pprof_help&quot; aria-label=&quot;pprof help112 id_app_pprof_help permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;(pprof) &lt;a href=&quot;mailto:help@1.12&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;help@1.12&lt;/a&gt; {#ID_APP_PPROF_HELP}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;(pprof) help
  Commands:
    callgrind        Outputs a graph in callgrind format
    comments         Output all profile comments
    disasm           Output assembly listings annotated with samples
    dot              Outputs a graph in DOT format
    eog              Visualize graph through eog
    evince           Visualize graph through evince
    gif              Outputs a graph image in GIF format
    gv               Visualize graph through gv
    kcachegrind      Visualize report in KCachegrind
    list             Output annotated source for functions matching regexp
    pdf              Outputs a graph in PDF format
    peek             Output callers/callees of functions matching regexp
    png              Outputs a graph image in PNG format
    proto            Outputs the profile in compressed protobuf format
    ps               Outputs a graph in PS format
    raw              Outputs a text representation of the raw profile
    svg              Outputs a graph in SVG format
    tags             Outputs all tags in the profile
    text             Outputs top entries in text form
    top              Outputs top entries in text form
    topproto         Outputs top entries in compressed protobuf format
    traces           Outputs all profile samples in text form
    tree             Outputs a text rendering of call graph
    web              Visualize graph through web browser
    weblist          Display annotated source in a web browser
    o/options        List options and their current values
    quit/exit/^D     Exit pprof

  Options:
    call_tree        Create a context-sensitive call tree
    compact_labels   Show minimal headers
    divide_by        Ratio to divide all samples before visualization
    drop_negative    Ignore negative differences
    edgefraction     Hide edges below &amp;lt;f&gt;*total
    focus            Restricts to samples going through a node matching regexp
    hide             Skips nodes matching regexp
    ignore           Skips paths going through any nodes matching regexp
    mean             Average sample value over first value (count)
    nodecount        Max number of nodes to show
    nodefraction     Hide nodes below &amp;lt;f&gt;*total
    noinlines        Ignore inlines.
    normalize        Scales profile based on the base profile.
    output           Output filename for file-based outputs
    prune_from       Drops any functions below the matched frame.
    relative_percentages Show percentages relative to focused subgraph
    sample_index     Sample value to report (0-based index or name)
    show             Only show nodes matching regexp
    show_from        Drops functions above the highest matched frame.
    source_path      Search path for source files
    tagfocus         Restricts to samples with tags in range or matched by regexp
    taghide          Skip tags matching this regexp
    tagignore        Discard samples with tags in range or matched by regexp
    tagshow          Only consider tags matching this regexp
    trim             Honor nodefraction/edgefraction/nodecount defaults
    trim_path        Path to trim from source paths before search
    unit             Measurement units to display

  Option groups (only set one per group):
    cumulative
      cum              Sort entries based on cumulative weight
      flat             Sort entries based on own weight
    granularity
      addresses        Aggregate at the address level.
      filefunctions    Aggregate at the function level.
      files            Aggregate at the file level.
      functions        Aggregate at the function level.
      lines            Aggregate at the source code line level.
  :   Clear focus/ignore/hide/tagfocus/tagignore

  type &quot;help &amp;lt;cmd|option&gt;&quot; for more information&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;go-tool-trace-usage112-id_app_trace_usage&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go-tool-trace-usage112-id_app_trace_usage&quot; aria-label=&quot;go tool trace usage112 id_app_trace_usage permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;go tool trace &lt;a href=&quot;mailto:usage@1.12&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;usage@1.12&lt;/a&gt; {#ID_APP_TRACE_USAGE}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ go tool trace
Usage of &apos;go tool trace&apos;:
Given a trace file produced by &apos;go test&apos;:
	go test -trace=trace.out pkg

Open a web browser displaying trace:
	go tool trace [flags] [pkg.test] trace.out

Generate a pprof-like profile from the trace:
    go tool trace -pprof=TYPE [pkg.test] trace.out

[pkg.test] argument is required for traces produced by Go 1.6 and below.
Go 1.7 does not require the binary argument.

Supported profile types are:
    - net: network blocking profile
    - sync: synchronization blocking profile
    - syscall: syscall blocking profile
    - sched: scheduler latency profile

Flags:
	-http=addr: HTTP service address (e.g., &apos;:6060&apos;)
	-pprof=type: print a pprof-like profile instead
	-d: print debug info such as parsed events

Note that while the various profiles available when launching
&apos;go tool trace&apos; work on every browser, the trace viewer itself
(the &apos;view trace&apos; page) comes from the Chrome/Chromium project
and is only actively tested on that browser.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;godebuggctrace1-sample-id_app_gctrace_sample&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#godebuggctrace1-sample-id_app_gctrace_sample&quot; aria-label=&quot;godebuggctrace1 sample id_app_gctrace_sample permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;GODEBUG=gctrace=1 sample {#ID_APP_GCTRACE_SAMPLE}&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ GODEBUG=gctrace=1 ./memory
gc 1 @11.703s 0%: 0.009+0.21+0.004 ms clock, 0.072+0/0.21/0.27+0.033 ms cpu, 4-&gt;4-&gt;3 MB, 5 MB goal, 8 P
gc 2 @23.103s 0%: 0.008+0.19+0.005 ms clock, 0.069+0/0.22/0.35+0.043 ms cpu, 7-&gt;7-&gt;7 MB, 8 MB goal, 8 P
gc 3 @45.707s 0%: 0.022+0.35+0.005 ms clock, 0.18+0/0.46/0.35+0.047 ms cpu, 14-&gt;14-&gt;14 MB, 15 MB goal, 8 P
gc 4 @89.806s 0%: 0.010+0.42+0.006 ms clock, 0.086+0/0.47/0.68+0.051 ms cpu, 28-&gt;28-&gt;28 MB, 29 MB goal, 8 P
scvg0: inuse: 47, idle: 15, sys: 63, released: 0, consumed: 63 (MB)
gc 5 @175.704s 0%: 0.010+0.34+0.005 ms clock, 0.087+0/0.44/0.85+0.047 ms cpu, 55-&gt;55-&gt;23 MB, 56 MB goal, 8 P
gc 6 @248.402s 0%: 0.010+0.41+0.008 ms clock, 0.086+0/0.44/0.99+0.065 ms cpu, 46-&gt;46-&gt;15 MB, 47 MB goal, 8 P
gc 7 @295.302s 0%: 0.010+0.20+0.004 ms clock, 0.080+0/0.25/0.55+0.035 ms cpu, 30-&gt;30-&gt;30 MB, 31 MB goal, 8 P
scvg1: inuse: 32, idle: 31, sys: 63, released: 0, consumed: 63 (MB)
gc 8 @386.702s 0%: 0.011+0.33+0.007 ms clock, 0.088+0/0.46/0.70+0.059 ms cpu, 58-&gt;58-&gt;27 MB, 60 MB goal, 8 P
scvg2: inuse: 47, idle: 15, sys: 63, released: 0, consumed: 63 (MB)
gc 9 @470.005s 0%: 0.011+0.27+0.006 ms clock, 0.093+0/0.25/0.75+0.050 ms cpu, 53-&gt;53-&gt;22 MB, 54 MB goal, 8 P
gc 10 @537.503s 0%: 0.010+0.28+0.009 ms clock, 0.087+0/0.27/0.58+0.076 ms cpu, 43-&gt;43-&gt;12 MB, 44 MB goal, 8 P
gc 11 @574.301s 0%: 0.011+0.27+0.006 ms clock, 0.089+0/0.31/0.74+0.049 ms cpu, 23-&gt;23-&gt;23 MB, 24 MB goal, 8 P
scvg3: inuse: 32, idle: 31, sys: 63, released: 0, consumed: 63 (MB)
gc 12 @646.001s 0%: 0.006+0.11+0.003 ms clock, 0.052+0/0.14/0.39+0.030 ms cpu, 46-&gt;46-&gt;14 MB, 47 MB goal, 8 P
gc 13 @691.005s 0%: 0.016+0.26+0.006 ms clock, 0.13+0/0.33/0.36+0.050 ms cpu, 28-&gt;28-&gt;28 MB, 29 MB goal, 8 P
scvg4: inuse: 48, idle: 15, sys: 63, released: 0, consumed: 63 (MB)
gc 14 @778.602s 0%: 0.021+0.26+0.008 ms clock, 0.17+0/0.34/0.80+0.067 ms cpu, 56-&gt;56-&gt;25 MB, 57 MB goal, 8 P
gc 15 @854.601s 0%: 0.013+0.29+0.008 ms clock, 0.11+0/0.34/0.77+0.064 ms cpu, 48-&gt;48-&gt;17 MB, 50 MB goal, 8 P
scvg5: inuse: 32, idle: 31, sys: 63, released: 0, consumed: 63 (MB)
gc 16 @907.902s 0%: 0.011+0.22+0.006 ms clock, 0.093+0/0.23/0.48+0.049 ms cpu, 34-&gt;34-&gt;2 MB, 35 MB goal, 8 P
gc 17 @916.902s 0%: 0.016+0.24+0.005 ms clock, 0.12+0/0.25/0.48+0.046 ms cpu, 5-&gt;5-&gt;5 MB, 6 MB goal, 8 P
gc 18 @934.507s 0%: 0.034+0.33+0.005 ms clock, 0.27+0/0.41/0.75+0.047 ms cpu, 11-&gt;11-&gt;11 MB, 12 MB goal, 8 P
gc 19 @968.802s 0%: 0.017+0.24+0.007 ms clock, 0.14+0/0.30/0.60+0.063 ms cpu, 22-&gt;22-&gt;22 MB, 23 MB goal, 8 P
gc 20 @1035.706s 0%: 0.071+0.25+0.006 ms clock, 0.57+0/0.33/0.61+0.049 ms cpu, 42-&gt;42-&gt;11 MB, 44 MB goal, 8 P
scvg6: inuse: 16, idle: 46, sys: 63, released: 0, consumed: 63 (MB)
gc 21 @1071.302s 0%: 0.011+0.24+0.006 ms clock, 0.089+0/0.28/0.72+0.048 ms cpu, 22-&gt;22-&gt;22 MB, 23 MB goal, 8 P
gc 22 @1140.611s 0%: 0.045+0.25+0.006 ms clock, 0.36+0/0.25/0.70+0.052 ms cpu, 44-&gt;44-&gt;13 MB, 45 MB goal, 8 P
gc 23 @1180.905s 0%: 0.034+0.34+0.006 ms clock, 0.27+0/0.32/0.72+0.051 ms cpu, 25-&gt;25-&gt;25 MB, 26 MB goal, 8 P
scvg7: inuse: 32, idle: 30, sys: 63, released: 0, consumed: 63 (MB)
gc 24 @1259.503s 0%: 0.018+0.24+0.008 ms clock, 0.14+0/0.32/0.51+0.067 ms cpu, 50-&gt;50-&gt;19 MB, 51 MB goal, 8 P
gc 25 @1317.902s 0%: 0.011+0.24+0.006 ms clock, 0.091+0/0.26/0.48+0.053 ms cpu, 37-&gt;37-&gt;6 MB, 38 MB goal, 8 P
gc 26 @1336.809s 0%: 0.034+0.22+0.006 ms clock, 0.27+0/0.27/0.53+0.053 ms cpu, 12-&gt;12-&gt;12 MB, 13 MB goal, 8 P
scvg8: inuse: 17, idle: 46, sys: 63, released: 0, consumed: 63 (MB)
gc 27 @1373.707s 0%: 0.037+0.29+0.006 ms clock, 0.29+0/0.33/0.78+0.051 ms cpu, 23-&gt;23-&gt;23 MB, 24 MB goal, 8 P
gc 28 @1445.610s 0%: 0.022+0.29+0.006 ms clock, 0.17+0/0.37/0.64+0.048 ms cpu, 46-&gt;46-&gt;14 MB, 47 MB goal, 8 P
gc 29 @1490.911s 0%: 0.008+0.19+0.004 ms clock, 0.067+0/0.25/0.66+0.036 ms cpu, 29-&gt;29-&gt;29 MB, 30 MB goal, 8 P
scvg9: inuse: 32, idle: 30, sys: 63, released: 0, consumed: 63 (MB)
gc 30 @1579.201s 0%: 0.010+0.25+0.006 ms clock, 0.083+0/0.30/0.72+0.048 ms cpu, 56-&gt;56-&gt;25 MB, 58 MB goal, 8 P
scvg10: inuse: 48, idle: 15, sys: 63, released: 0, consumed: 63 (MB)
gc 31 @1656.509s 0%: 0.010+0.26+0.006 ms clock, 0.085+0/0.33/0.64+0.048 ms cpu, 49-&gt;49-&gt;18 MB, 50 MB goal, 8 P
gc 32 @1712.403s 0%: 0.014+0.27+0.006 ms clock, 0.11+0/0.37/0.46+0.049 ms cpu, 35-&gt;35-&gt;4 MB, 36 MB goal, 8 P
gc 33 @1726.509s 0%: 0.011+0.22+0.006 ms clock, 0.091+0/0.27/0.51+0.050 ms cpu, 9-&gt;9-&gt;9 MB, 10 MB goal, 8 P
gc 34 @1754.002s 0%: 0.016+0.26+0.006 ms clock, 0.13+0/0.34/0.56+0.050 ms cpu, 17-&gt;17-&gt;17 MB, 18 MB goal, 8 P
scvg11: inuse: 32, idle: 30, sys: 63, released: 0, consumed: 63 (MB)
gc 35 @1807.606s 0%: 0.033+0.27+0.006 ms clock, 0.26+0/0.26/0.53+0.052 ms cpu, 34-&gt;34-&gt;3 MB, 35 MB goal, 8 P
gc 36 @1817.204s 0%: 0.024+0.23+0.006 ms clock, 0.19+0/0.28/0.50+0.051 ms cpu, 6-&gt;6-&gt;6 MB, 7 MB goal, 8 P
gc 37 @1835.905s 0%: 0.085+0.31+0.007 ms clock, 0.68+0/0.32/0.54+0.056 ms cpu, 12-&gt;12-&gt;12 MB, 13 MB goal, 8 P
gc 38 @1872.402s 0%: 0.011+0.25+0.009 ms clock, 0.090+0/0.30/0.63+0.074 ms cpu, 23-&gt;23-&gt;23 MB, 24 MB goal, 8 P
gc 39 @1943.602s 0%: 0.011+0.24+0.006 ms clock, 0.090+0/0.27/0.46+0.049 ms cpu, 45-&gt;45-&gt;14 MB, 46 MB goal, 8 P
scvg12: inuse: 17, idle: 46, sys: 63, released: 0, consumed: 63 (MB)
gc 40 @1987.501s 0%: 0.007+0.20+0.004 ms clock, 0.063+0/0.25/0.65+0.033 ms cpu, 28-&gt;28-&gt;28 MB, 29 MB goal, 8 P
gc 41 @2073.102s 0%: 0.050+0.29+0.006 ms clock, 0.40+0/0.32/0.72+0.050 ms cpu, 54-&gt;54-&gt;23 MB, 56 MB goal, 8 P
scvg13: inuse: 33, idle: 30, sys: 63, released: 0, consumed: 63 (MB)
gc 42 @2145.107s 0%: 0.041+0.27+0.006 ms clock, 0.33+0/0.46/0.63+0.049 ms cpu, 46-&gt;46-&gt;14 MB, 47 MB goal, 8 P
gc 43 @2190.606s 0%: 0.11+0.25+0.008 ms clock, 0.91+0/0.36/0.77+0.065 ms cpu, 29-&gt;29-&gt;29 MB, 30 MB goal, 8 P
scvg14: inuse: 48, idle: 14, sys: 63, released: 0, consumed: 63 (MB)
gc 44 @2279.311s 0%: 0.010+0.26+0.006 ms clock, 0.084+0/0.31/0.83+0.052 ms cpu, 56-&gt;56-&gt;25 MB, 58 MB goal, 8 P
gc 45 @2357.406s 0%: 0.061+0.27+0.006 ms clock, 0.48+0/0.31/0.68+0.050 ms cpu, 50-&gt;50-&gt;18 MB, 51 MB goal, 8 P
scvg15: inuse: 33, idle: 30, sys: 63, released: 0, consumed: 63 (MB)
gc 46 @2414.805s 0%: 0.010+0.16+0.014 ms clock, 0.087+0/0.19/0.33+0.11 ms cpu, 36-&gt;36-&gt;5 MB, 37 MB goal, 8 P
gc 47 @2431.810s 0%: 0.023+0.33+0.007 ms clock, 0.18+0/0.32/0.51+0.057 ms cpu, 10-&gt;10-&gt;10 MB, 11 MB goal, 8 P
gc 48 @2465.009s 0%: 0.048+0.29+0.005 ms clock, 0.38+0/0.35/0.72+0.046 ms cpu, 21-&gt;21-&gt;21 MB, 22 MB goal, 8 P
gc 49 @2529.707s 0%: 0.10+0.24+0.006 ms clock, 0.86+0/0.32/0.61+0.048 ms cpu, 41-&gt;41-&gt;10 MB, 42 MB goal, 8 P
scvg16: inuse: 17, idle: 45, sys: 63, released: 0, consumed: 63 (MB)
gc 50 @2561.012s 0%: 0.024+0.31+0.006 ms clock, 0.19+0/0.33/0.70+0.050 ms cpu, 20-&gt;20-&gt;20 MB, 21 MB goal, 8 P
gc 51 @2622.011s 0%: 0.010+0.30+0.007 ms clock, 0.086+0/0.35/0.56+0.056 ms cpu, 39-&gt;39-&gt;7 MB, 40 MB goal, 8 P
gc 52 @2646.003s 0%: 0.009+0.22+0.005 ms clock, 0.076+0/0.25/0.47+0.045 ms cpu, 15-&gt;15-&gt;15 MB, 16 MB goal, 8 P
gc 53 @2692.902s 0%: 0.011+0.24+0.006 ms clock, 0.093+0/0.32/0.74+0.049 ms cpu, 30-&gt;30-&gt;30 MB, 31 MB goal, 8 P
scvg17: 0 MB released
scvg17: inuse: 33, idle: 30, sys: 63, released: 0, consumed: 63 (MB)
gc 54 @2784.303s 0%: 0.011+0.28+0.006 ms clock, 0.093+0/0.34/0.83+0.050 ms cpu, 58-&gt;58-&gt;27 MB, 60 MB goal, 8 P
scvg18: inuse: 48, idle: 14, sys: 63, released: 14, consumed: 48 (MB)
gc 55 @2867.607s 0%: 0.011+0.24+0.006 ms clock, 0.088+0/0.30/0.52+0.050 ms cpu, 53-&gt;53-&gt;22 MB, 54 MB goal, 8 P
gc 56 @2935.203s 0%: 0.019+0.23+0.023 ms clock, 0.15+0/0.30/0.65+0.19 ms cpu, 43-&gt;43-&gt;12 MB, 44 MB goal, 8 P
gc 57 @2972.103s 0%: 0.034+0.32+0.006 ms clock, 0.27+0/0.40/0.45+0.050 ms cpu, 23-&gt;23-&gt;23 MB, 24 MB goal, 8 P
scvg19: inuse: 33, idle: 30, sys: 63, released: 16, consumed: 46 (MB)
gc 58 @3044.011s 0%: 0.025+0.29+0.005 ms clock, 0.20+0/0.28/0.72+0.047 ms cpu, 46-&gt;46-&gt;14 MB, 47 MB goal, 8 P
gc 59 @3089.308s 0%: 0.060+0.31+0.007 ms clock, 0.48+0/0.33/0.75+0.056 ms cpu, 29-&gt;29-&gt;29 MB, 30 MB goal, 8 P
scvg20: inuse: 49, idle: 14, sys: 63, released: 14, consumed: 49 (MB)
gc 60 @3177.703s 0%: 0.041+0.41+0.008 ms clock, 0.33+0/0.48/0.69+0.071 ms cpu, 56-&gt;56-&gt;25 MB, 58 MB goal, 8 P
gc 61 @3255.110s 0%: 0.020+0.24+0.006 ms clock, 0.16+0/0.30/0.72+0.049 ms cpu, 49-&gt;49-&gt;18 MB, 50 MB goal, 8 P
scvg21: inuse: 33, idle: 29, sys: 63, released: 14, consumed: 48 (MB)
gc 62 @3311.110s 0%: 0.12+0.23+0.007 ms clock, 0.97+0/0.24/0.49+0.059 ms cpu, 35-&gt;35-&gt;4 MB, 36 MB goal, 8 P
gc 63 @3325.511s 0%: 0.012+0.15+0.004 ms clock, 0.098+0/0.20/0.39+0.036 ms cpu, 9-&gt;9-&gt;9 MB, 10 MB goal, 8 P
gc 64 @3353.608s 0%: 0.043+0.24+0.006 ms clock, 0.34+0/0.36/0.50+0.049 ms cpu, 18-&gt;18-&gt;18 MB, 19 MB goal, 8 P
gc 65 @3408.311s 0%: 0.012+0.26+0.006 ms clock, 0.098+0/0.27/0.52+0.049 ms cpu, 35-&gt;35-&gt;3 MB, 36 MB goal, 8 P
gc 66 @3420.110s 0%: 0.010+0.25+0.005 ms clock, 0.087+0/0.25/0.58+0.046 ms cpu, 7-&gt;7-&gt;7 MB, 8 MB goal, 8 P
gc 67 @3443.110s 0%: 0.012+0.23+0.006 ms clock, 0.097+0/0.28/0.63+0.048 ms cpu, 14-&gt;14-&gt;14 MB, 15 MB goal, 8 P
scvg22: inuse: 17, idle: 45, sys: 63, released: 0, consumed: 63 (MB)
gc 68 @3487.903s 0%: 0.011+0.26+0.004 ms clock, 0.092+0/0.29/0.67+0.037 ms cpu, 28-&gt;28-&gt;28 MB, 29 MB goal, 8 P
gc 69 @3575.304s 0%: 0.011+0.24+0.006 ms clock, 0.093+0/0.33/0.87+0.050 ms cpu, 56-&gt;56-&gt;24 MB, 57 MB goal, 8 P
scvg23: inuse: 33, idle: 29, sys: 63, released: 20, consumed: 42 (MB)
gc 70 @3650.811s 0%: 0.036+0.30+0.006 ms clock, 0.29+0/0.30/0.62+0.048 ms cpu, 48-&gt;48-&gt;17 MB, 49 MB goal, 8 P
gc 71 @3703.207s 0%: 0.011+0.24+0.006 ms clock, 0.088+0/0.23/0.50+0.048 ms cpu, 33-&gt;33-&gt;2 MB, 34 MB goal, 8 P
gc 72 @3710.409s 0%: 0.040+0.27+0.006 ms clock, 0.32+0/0.24/0.58+0.050 ms cpu, 4-&gt;4-&gt;4 MB, 5 MB goal, 8 P
gc 73 @3724.511s 0%: 0.020+0.37+0.006 ms clock, 0.16+0/0.44/0.46+0.052 ms cpu, 9-&gt;9-&gt;9 MB, 10 MB goal, 8 P
scvg24: inuse: 18, idle: 45, sys: 63, released: 29, consumed: 34 (MB)
gc 74 @3752.012s 0%: 0.022+0.29+0.006 ms clock, 0.17+0/0.38/0.67+0.052 ms cpu, 17-&gt;17-&gt;17 MB, 18 MB goal, 8 P
gc 75 @3805.608s 0%: 0.080+0.24+0.006 ms clock, 0.64+0/0.24/0.55+0.051 ms cpu, 34-&gt;34-&gt;3 MB, 35 MB goal, 8 P
gc 76 @3815.202s 0%: 0.011+0.23+0.005 ms clock, 0.091+0/0.23/0.47+0.047 ms cpu, 6-&gt;6-&gt;6 MB, 7 MB goal, 8 P
gc 77 @3833.902s 0%: 0.010+0.22+0.008 ms clock, 0.085+0/0.28/0.51+0.065 ms cpu, 12-&gt;12-&gt;12 MB, 13 MB goal, 8 P
gc 78 @3870.403s 0%: 0.041+0.23+0.007 ms clock, 0.32+0/0.31/0.77+0.062 ms cpu, 23-&gt;23-&gt;23 MB, 24 MB goal, 8 P
scvg25: inuse: 33, idle: 29, sys: 63, released: 28, consumed: 35 (MB)
gc 79 @3941.505s 0%: 0.094+0.31+0.063 ms clock, 0.75+0/0.37/0.73+0.50 ms cpu, 45-&gt;45-&gt;14 MB, 46 MB goal, 8 P
gc 80 @3985.311s 0%: 0.080+0.22+0.006 ms clock, 0.64+0/0.31/0.47+0.049 ms cpu, 28-&gt;28-&gt;28 MB, 29 MB goal, 8 P
scvg26: inuse: 49, idle: 14, sys: 63, released: 14, consumed: 49 (MB)
gc 81 @4070.701s 0%: 0.009+0.18+0.004 ms clock, 0.079+0/0.23/0.53+0.036 ms cpu, 54-&gt;54-&gt;23 MB, 56 MB goal, 8 P
gc 82 @4142.306s 0%: 0.064+0.27+0.006 ms clock, 0.51+0/0.29/0.61+0.051 ms cpu, 46-&gt;46-&gt;14 MB, 47 MB goal, 8 P
gc 83 @4187.104s 0%: 0.010+0.29+0.006 ms clock, 0.080+0/0.36/0.59+0.050 ms cpu, 28-&gt;28-&gt;28 MB, 29 MB goal, 8 P
scvg27: inuse: 33, idle: 29, sys: 63, released: 16, consumed: 47 (MB)
gc 84 @4274.406s 0%: 0.082+0.27+0.005 ms clock, 0.65+0/0.37/0.67+0.044 ms cpu, 56-&gt;56-&gt;24 MB, 57 MB goal, 8 P
gc 85 @4349.811s 0%: 0.074+0.30+0.006 ms clock, 0.59+0/0.38/0.74+0.053 ms cpu, 48-&gt;48-&gt;17 MB, 49 MB goal, 8 P
scvg28: inuse: 18, idle: 45, sys: 63, released: 8, consumed: 54 (MB)
gc 86 @4401.808s 0%: 0.012+0.23+0.006 ms clock, 0.096+0/0.24/0.58+0.054 ms cpu, 33-&gt;33-&gt;2 MB, 34 MB goal, 8 P
gc 87 @4408.310s 0%: 0.012+0.23+0.006 ms clock, 0.098+0/0.28/0.52+0.052 ms cpu, 4-&gt;4-&gt;4 MB, 5 MB goal, 8 P
gc 88 @4421.008s 0%: 0.022+0.25+0.006 ms clock, 0.17+0/0.30/0.66+0.049 ms cpu, 8-&gt;8-&gt;8 MB, 9 MB goal, 8 P
gc 89 @4445.808s 0%: 0.009+0.19+0.005 ms clock, 0.076+0/0.20/0.40+0.043 ms cpu, 15-&gt;15-&gt;15 MB, 16 MB goal, 8 P
gc 90 @4494.207s 0%: 0.014+0.33+0.008 ms clock, 0.11+0/0.44/0.70+0.067 ms cpu, 31-&gt;31-&gt;31 MB, 32 MB goal, 8 P
scvg29: inuse: 34, idle: 29, sys: 63, released: 26, consumed: 36 (MB)
gc 91 @4588.509s 0%: 0.011+0.27+0.006 ms clock, 0.092+0/0.34/0.83+0.049 ms cpu, 60-&gt;60-&gt;29 MB, 62 MB goal, 8 P
scvg30: inuse: 49, idle: 13, sys: 63, released: 13, consumed: 49 (MB)
gc 92 @4677.504s 0%: 0.033+0.34+0.006 ms clock, 0.26+0/0.44/0.88+0.053 ms cpu, 57-&gt;57-&gt;25 MB, 58 MB goal, 8 P
gc 93 @4756.211s 0%: 0.011+0.33+0.006 ms clock, 0.091+0/0.34/0.64+0.048 ms cpu, 50-&gt;50-&gt;19 MB, 51 MB goal, 8 P
scvg31: inuse: 34, idle: 29, sys: 63, released: 16, consumed: 47 (MB)
gc 94 @4814.709s 0%: 0.035+0.29+0.007 ms clock, 0.28+0/0.30/0.53+0.058 ms cpu, 37-&gt;37-&gt;6 MB, 38 MB goal, 8 P
gc 95 @4833.910s 0%: 0.046+0.25+0.006 ms clock, 0.36+0/0.33/0.64+0.051 ms cpu, 12-&gt;12-&gt;12 MB, 13 MB goal, 8 P
gc 96 @4871.405s 0%: 0.071+0.29+0.007 ms clock, 0.57+0/0.41/0.69+0.060 ms cpu, 24-&gt;24-&gt;24 MB, 25 MB goal, 8 P
gc 97 @4944.505s 0%: 0.066+0.27+0.006 ms clock, 0.53+0/0.29/0.63+0.054 ms cpu, 46-&gt;46-&gt;15 MB, 48 MB goal, 8 P
scvg32: inuse: 18, idle: 44, sys: 63, released: 15, consumed: 47 (MB)
gc 98 @4992.106s 0%: 0.024+0.30+0.006 ms clock, 0.19+0/0.35/0.78+0.048 ms cpu, 30-&gt;30-&gt;30 MB, 31 MB goal, 8 P
gc 99 @5084.906s 0%: 0.013+0.26+0.006 ms clock, 0.10+0/0.33/0.82+0.051 ms cpu, 59-&gt;59-&gt;28 MB, 61 MB goal, 8 P
scvg33: inuse: 34, idle: 29, sys: 63, released: 14, consumed: 49 (MB)
gc 100 @5171.006s 0%: 0.012+0.30+0.007 ms clock, 0.10+0/0.36/0.90+0.057 ms cpu, 55-&gt;55-&gt;24 MB, 56 MB goal, 8 P
gc 101 @5244.002s 0%: 0.010+0.24+0.006 ms clock, 0.086+0/0.25/0.43+0.055 ms cpu, 46-&gt;46-&gt;15 MB, 48 MB goal, 8 P
scvg34: inuse: 18, idle: 44, sys: 63, released: 12, consumed: 50 (MB)
gc 102 @5291.403s 0%: 0.011+0.25+0.008 ms clock, 0.090+0/0.33/0.80+0.066 ms cpu, 30-&gt;30-&gt;30 MB, 31 MB goal, 8 P
gc 103 @5383.803s 0%: 0.011+0.29+0.006 ms clock, 0.092+0/0.35/0.94+0.053 ms cpu, 59-&gt;59-&gt;28 MB, 60 MB goal, 8 P
scvg35: inuse: 34, idle: 29, sys: 63, released: 0, consumed: 62 (MB)
gc 104 @5469.107s 0%: 0.011+0.37+0.008 ms clock, 0.090+0/0.40/0.77+0.064 ms cpu, 54-&gt;54-&gt;23 MB, 56 MB goal, 8 P
gc 105 @5540.506s 0%: 0.031+0.30+0.006 ms clock, 0.25+0/0.31/0.71+0.050 ms cpu, 45-&gt;45-&gt;14 MB, 47 MB goal, 8 P
scvg36: inuse: 18, idle: 44, sys: 63, released: 12, consumed: 50 (MB)
gc 106 @5584.907s 0%: 0.099+0.33+0.008 ms clock, 0.79+0/0.43/0.72+0.068 ms cpu, 28-&gt;28-&gt;28 MB, 29 MB goal, 8 P
gc 107 @5671.406s 0%: 0.031+0.18+0.005 ms clock, 0.25+0/0.21/0.61+0.040 ms cpu, 55-&gt;55-&gt;24 MB, 56 MB goal, 8 P
scvg37: inuse: 34, idle: 28, sys: 63, released: 17, consumed: 46 (MB)
gc 108 @5745.210s 0%: 0.012+0.27+0.006 ms clock, 0.10+0/0.31/0.67+0.049 ms cpu, 47-&gt;47-&gt;16 MB, 48 MB goal, 8 P
gc 109 @5794.303s 0%: 0.008+0.23+0.006 ms clock, 0.067+0.061/0.25/0.71+0.049 ms cpu, 31-&gt;31-&gt;31 MB, 32 MB goal, 8 P
scvg38: inuse: 50, idle: 13, sys: 63, released: 13, consumed: 50 (MB)
gc 110 @5890.006s 0%: 0.033+0.23+0.006 ms clock, 0.26+0/0.27/0.53+0.051 ms cpu, 61-&gt;61-&gt;30 MB, 63 MB goal, 8 P
gc 111 @5981.705s 0%: 0.016+0.22+0.005 ms clock, 0.13+0/0.30/0.50+0.042 ms cpu, 58-&gt;58-&gt;27 MB, 60 MB goal, 8 P
scvg39: inuse: 34, idle: 28, sys: 63, released: 13, consumed: 49 (MB)
gc 112 @6065.606s 0%: 0.020+0.29+0.004 ms clock, 0.16+0/0.37/0.71+0.036 ms cpu, 53-&gt;53-&gt;22 MB, 55 MB goal, 8 P
gc 113 @6134.304s 0%: 0.010+0.17+0.004 ms clock, 0.085+0/0.22/0.44+0.033 ms cpu, 44-&gt;44-&gt;12 MB, 45 MB goal, 8 P
scvg40: inuse: 19, idle: 44, sys: 63, released: 2, consumed: 60 (MB)
gc 114 @6173.404s 0%: 0.018+0.25+0.011 ms clock, 0.14+0/0.32/0.78+0.092 ms cpu, 25-&gt;25-&gt;25 MB, 26 MB goal, 8 P
gc 115 @6249.602s 0%: 0.010+0.26+0.006 ms clock, 0.085+0/0.31/0.68+0.051 ms cpu, 48-&gt;48-&gt;17 MB, 50 MB goal, 8 P
scvg41: inuse: 34, idle: 28, sys: 63, released: 13, consumed: 49 (MB)
gc 116 @6303.302s 0%: 0.011+0.20+0.006 ms clock, 0.092+0/0.26/0.49+0.048 ms cpu, 34-&gt;34-&gt;3 MB, 35 MB goal, 8 P
gc 117 @6313.105s 0%: 0.006+0.12+0.003 ms clock, 0.049+0/0.15/0.41+0.029 ms cpu, 6-&gt;6-&gt;6 MB, 7 MB goal, 8 P
gc 118 @6332.206s 0%: 0.011+0.33+0.006 ms clock, 0.091+0/0.33/0.72+0.052 ms cpu, 12-&gt;12-&gt;12 MB, 13 MB goal, 8 P
gc 119 @6369.503s 0%: 0.010+0.37+0.015 ms clock, 0.085+0/0.38/0.59+0.12 ms cpu, 23-&gt;23-&gt;23 MB, 24 MB goal, 8 P
gc 120 @6442.206s 0%: 0.006+0.19+0.004 ms clock, 0.051+0/0.23/0.31+0.032 ms cpu, 46-&gt;46-&gt;15 MB, 47 MB goal, 8 P
scvg42: 0 MB released
scvg42: inuse: 19, idle: 44, sys: 63, released: 13, consumed: 50 (MB)
gc 121 @6489.106s 0%: 0.011+0.28+0.005 ms clock, 0.093+0/0.34/0.77+0.047 ms cpu, 30-&gt;30-&gt;30 MB, 31 MB goal, 8 P
gc 122 @6580.502s 0%: 0.009+0.18+0.004 ms clock, 0.079+0/0.26/0.46+0.038 ms cpu, 58-&gt;58-&gt;27 MB, 60 MB goal, 8 P
scvg43: inuse: 34, idle: 28, sys: 63, released: 15, consumed: 48 (MB)
gc 123 @6663.801s 0%: 0.007+0.24+0.004 ms clock, 0.063+0/0.20/0.60+0.035 ms cpu, 53-&gt;53-&gt;22 MB, 54 MB goal, 8 P
gc 124 @6731.406s 0%: 0.015+0.26+0.007 ms clock, 0.12+0/0.32/0.56+0.063 ms cpu, 43-&gt;43-&gt;12 MB, 44 MB goal, 8 P
scvg44: inuse: 19, idle: 44, sys: 63, released: 34, consumed: 28 (MB)
gc 125 @6768.305s 0%: 0.013+0.26+0.007 ms clock, 0.10+0/0.42/0.64+0.062 ms cpu, 23-&gt;23-&gt;23 MB, 24 MB goal, 8 P
gc 126 @6840.205s 0%: 0.006+0.20+0.005 ms clock, 0.055+0/0.23/0.49+0.046 ms cpu, 46-&gt;46-&gt;14 MB, 47 MB goal, 8 P
gc 127 @6885.603s 0%: 0.056+0.27+0.007 ms clock, 0.45+0/0.35/0.79+0.063 ms cpu, 29-&gt;29-&gt;29 MB, 30 MB goal, 8 P
scvg45: inuse: 35, idle: 28, sys: 63, released: 20, consumed: 42 (MB)
gc 128 @6974.002s 0%: 0.011+0.35+0.006 ms clock, 0.091+0/0.43/0.67+0.048 ms cpu, 56-&gt;56-&gt;25 MB, 58 MB goal, 8 P
gc 129 @7051.503s 0%: 0.011+0.29+0.006 ms clock, 0.091+0/0.35/0.84+0.048 ms cpu, 49-&gt;49-&gt;18 MB, 51 MB goal, 8 P
scvg46: inuse: 19, idle: 43, sys: 63, released: 12, consumed: 50 (MB)
gc 130 @7107.703s 0%: 0.016+0.21+0.004 ms clock, 0.13+0/0.29/0.57+0.036 ms cpu, 36-&gt;36-&gt;4 MB, 37 MB goal, 8 P
gc 131 @7122.402s 0%: 0.011+0.26+0.006 ms clock, 0.095+0/0.25/0.53+0.052 ms cpu, 9-&gt;9-&gt;9 MB, 10 MB goal, 8 P
gc 132 @7151.102s 0%: 0.008+0.17+0.004 ms clock, 0.071+0/0.21/0.50+0.036 ms cpu, 18-&gt;18-&gt;18 MB, 19 MB goal, 8 P
scvg47: inuse: 35, idle: 28, sys: 63, released: 28, consumed: 35 (MB)
gc 133 @7207.005s 0%: 0.006+0.14+0.004 ms clock, 0.053+0/0.15/0.33+0.039 ms cpu, 35-&gt;35-&gt;4 MB, 36 MB goal, 8 P
gc 134 @7221.202s 0%: 0.008+0.18+0.004 ms clock, 0.066+0/0.24/0.44+0.034 ms cpu, 9-&gt;9-&gt;9 MB, 10 MB goal, 8 P
gc 135 @7248.901s 0%: 0.011+0.24+0.007 ms clock, 0.091+0/0.28/0.60+0.062 ms cpu, 17-&gt;17-&gt;17 MB, 18 MB goal, 8 P
gc 136 @7302.906s 0%: 0.007+0.13+0.005 ms clock, 0.060+0/0.15/0.34+0.041 ms cpu, 34-&gt;34-&gt;3 MB, 35 MB goal, 8 P
gc 137 @7313.306s 0%: 0.011+0.23+0.008 ms clock, 0.089+0/0.29/0.57+0.070 ms cpu, 6-&gt;6-&gt;6 MB, 7 MB goal, 8 P
gc 138 @7333.603s 0%: 0.012+0.31+0.005 ms clock, 0.096+0/0.46/0.36+0.046 ms cpu, 13-&gt;13-&gt;13 MB, 14 MB goal, 8 P
scvg48: 0 MB released
scvg48: inuse: 19, idle: 43, sys: 63, released: 26, consumed: 36 (MB)
gc 139 @7373.204s 0%: 0.019+0.30+0.006 ms clock, 0.15+0/0.36/0.62+0.049 ms cpu, 25-&gt;25-&gt;25 MB, 26 MB goal, 8 P
gc 140 @7450.306s 0%: 0.053+1.4+0.005 ms clock, 0.42+0/0.24/0.56+0.041 ms cpu, 49-&gt;49-&gt;18 MB, 50 MB goal, 8 P
scvg49: inuse: 35, idle: 28, sys: 63, released: 13, consumed: 50 (MB)
gc 141 @7505.801s 0%: 0.008+0.43+0.005 ms clock, 0.068+0/0.57/0.75+0.045 ms cpu, 35-&gt;35-&gt;4 MB, 36 MB goal, 8 P
gc 142 @7519.105s 0%: 0.008+0.20+0.004 ms clock, 0.066+0/0.25/0.37+0.035 ms cpu, 8-&gt;8-&gt;8 MB, 9 MB goal, 8 P
gc 143 @7545.105s 0%: 0.008+0.16+0.004 ms clock, 0.071+0/0.21/0.51+0.036 ms cpu, 16-&gt;16-&gt;16 MB, 17 MB goal, 8 P
gc 144 @7595.706s 0%: 0.029+0.27+0.006 ms clock, 0.23+0/0.30/0.40+0.050 ms cpu, 32-&gt;32-&gt;1 MB, 33 MB goal, 8 P
gc 145 @7604.502s 0%: 0.008+0.19+0.009 ms clock, 0.064+0/0.20/0.50+0.078 ms cpu, 4-&gt;4-&gt;4 MB, 5 MB goal, 8 P
gc 146 @7616.706s 0%: 0.008+0.19+0.005 ms clock, 0.071+0/0.25/0.19+0.041 ms cpu, 7-&gt;7-&gt;7 MB, 8 MB goal, 8 P
gc 147 @7640.505s 0%: 0.006+0.16+0.004 ms clock, 0.055+0/0.22/0.26+0.033 ms cpu, 15-&gt;15-&gt;15 MB, 16 MB goal, 8 P
scvg50: inuse: 19, idle: 43, sys: 63, released: 18, consumed: 44 (MB)
gc 148 @7686.903s 0%: 0.010+0.26+0.005 ms clock, 0.085+0/0.34/0.91+0.047 ms cpu, 29-&gt;29-&gt;29 MB, 30 MB goal, 8 P
gc 149 @7777.303s 0%: 0.027+0.32+0.004 ms clock, 0.21+0/0.36/0.55+0.038 ms cpu, 58-&gt;58-&gt;26 MB, 59 MB goal, 8 P
scvg51: inuse: 35, idle: 27, sys: 63, released: 17, consumed: 46 (MB)
gc 150 @7858.705s 0%: 0.017+0.26+0.007 ms clock, 0.13+0/0.35/0.59+0.063 ms cpu, 52-&gt;52-&gt;21 MB, 53 MB goal, 8 P
gc 151 @7922.606s 0%: 0.016+0.22+0.006 ms clock, 0.12+0/0.30/0.51+0.055 ms cpu, 41-&gt;41-&gt;9 MB, 42 MB goal, 8 P
gc 152 @7952.301s 0%: 0.011+0.18+0.004 ms clock, 0.091+0/0.20/0.46+0.033 ms cpu, 19-&gt;19-&gt;19 MB, 20 MB goal, 8 P
scvg52: inuse: 19, idle: 43, sys: 63, released: 4, consumed: 59 (MB)
gc 153 @8010.203s 0%: 0.043+0.32+0.006 ms clock, 0.34+0/0.34/0.67+0.053 ms cpu, 37-&gt;37-&gt;5 MB, 38 MB goal, 8 P&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;experimentmemorymemorygo-id_app_memory_sample&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#experimentmemorymemorygo-id_app_memory_sample&quot; aria-label=&quot;experimentmemorymemorygo id_app_memory_sample permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;experiment/memory/memory.go {#ID_APP_MEMORY_SAMPLE}&lt;/h2&gt;
&lt;script src=&quot;https://gist.github.com/agreatfool/83764ceff16a8b512da22a9d3a337fea.js&quot;&gt; &lt;/script&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Modules]]></title><link>https://xenojoshua.com/posts/2019/03/golang-modules</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/03/golang-modules</guid><pubDate>Fri, 08 Mar 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%8E%86%E5%8F%B2--%E5%B1%95%E6%9C%9B&quot;&gt;2. 历史 &amp;#x26; 展望&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3&quot;&gt;3. 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8--%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4-go_mod_use&quot;&gt;4. 使用 &amp;#x26; 常用命令 {#GO_MOD_USE}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#go111module&quot;&gt;GO111MODULE&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#go-mod-init&quot;&gt;go mod init&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#go-get--u&quot;&gt;go get (-u)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#go-mod-graph&quot;&gt;go mod graph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#go-mod-download&quot;&gt;go mod download&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#go-mod-tidy&quot;&gt;go mod tidy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E6%A8%A1%E5%9D%97%E5%AE%9A%E4%B9%89--%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84&quot;&gt;5. 模块定义 &amp;#x26; 文件结构&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E4%BB%A3%E7%A0%81%E6%A0%B9%E7%9B%AE%E5%BD%95%E7%9A%84%E7%BA%A6%E5%AE%9A&quot;&gt;代码根目录的约定&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%A8%A1%E5%9D%97%E5%AE%9A%E4%B9%89%E5%AE%98%E6%96%B9%E8%8C%83%E4%BE%8B&quot;&gt;模块定义官方范例&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-%E7%89%88%E6%9C%AC%E5%AE%9A%E4%B9%89--%E6%9B%B4%E6%96%B0&quot;&gt;6. 版本定义 &amp;#x26; 更新&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#tag%E7%9A%84%E5%91%BD%E5%90%8D%E8%A7%84%E8%8C%83&quot;&gt;tag的命名规范&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%89%88%E6%9C%AC%E9%80%89%E6%8B%A9&quot;&gt;版本选择&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%89%88%E6%9C%AC%E5%BC%95%E5%85%A5&quot;&gt;版本引入&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%A6%82%E4%BD%95%E6%9B%B4%E6%96%B0%E4%BE%9D%E8%B5%96%E7%9A%84%E7%89%88%E6%9C%AC&quot;&gt;如何更新依赖的版本&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-%E8%A1%A5%E5%85%85gomod--replace%E6%8C%87%E4%BB%A4-go_mod_file&quot;&gt;7. 补充：go.mod &amp;#x26; replace指令 {#GO_MOD_FILE}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#replace%E6%8C%87%E4%BB%A4&quot;&gt;replace指令&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-%E5%AE%9E%E9%99%85%E7%BB%8F%E9%AA%8C&quot;&gt;8. 实际经验&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot;&gt;资料&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;本文是Go语言系列文章&lt;a href=&quot;/2019/02/golang-note/&quot;&gt;Golang Notes&lt;/a&gt;的其中一篇，完整的文章列表请去总章查看。&lt;/p&gt;
&lt;p&gt;后续&lt;code class=&quot;language-text&quot;&gt;模块&lt;/code&gt;相关技术文字内容主要参考自官方wiki说明：&lt;a href=&quot;https://github.com/golang/go/wiki/Modules&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.11 Modules&lt;/a&gt;。强烈建议有时间的可以自己通读一遍，任何第三方的讲解都不可能比这篇原文更详细、更细节。这是我见过的最&lt;code class=&quot;language-text&quot;&gt;啰嗦&lt;/code&gt;的技术说明文章之一。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE 2019-03-21&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;官方博客3.19姗姗来迟了一篇模块博文，算是补足了正规渠道的引导：&lt;a href=&quot;https://blog.golang.org/using-go-modules&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;The Go Blog &gt; Using Go Modules&lt;/a&gt;。比起之前的wiki，这篇博客算是做了点总结，不像wiki那么啰嗦了。&lt;/p&gt;
&lt;h1 id=&quot;2-历史--展望&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%8E%86%E5%8F%B2--%E5%B1%95%E6%9C%9B&quot; aria-label=&quot;2 历史  展望 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 历史 &amp;#x26; 展望&lt;/h1&gt;
&lt;p&gt;Go语言的包管理可以说是黑历史了，1.5之前基本上没有解决方案，1.5开始出了个vendor&lt;code class=&quot;language-text&quot;&gt;文件夹&lt;/code&gt;，后面几个版本大部分的工具都围绕着这个文件夹做文章。最后终于到了1.11版本才出了个官方的modules解决方案（vgo），算是尘埃落定。估计一开始做语言设计的时候，大佬觉得包管理根本没必要，怎么随意怎么来。结果后面大厂们都开始用go语言构建大型系统和生态了，才慢慢暴露出问题，文件下载随便一扔的解决方案太过随意，有太多太多的不安定要素。&lt;/p&gt;
&lt;p&gt;我之前一直对go语言持观望态度（即便是这两年最火的时候），就是因为这个包管理的原因。于是到了1.11，我终于开始觉得可以入手了。&lt;/p&gt;
&lt;p&gt;1.11正式release的module这个功能应该说是稳定了，后面理论上不会再有很大的改动。这从官方给的modules wiki就可以看得出来，洋洋洒洒长篇累牍写了那么长一篇文章。&lt;/p&gt;
&lt;p&gt;当然以目前的现状来说，仍旧远不能称完善，这里可以简单展望一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;包搜索过于困难：没有一个服务能根据需求功能进行包搜索（类似&lt;a href=&quot;https://www.npmjs.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;www.npmjs.org&lt;/a&gt;）&lt;/li&gt;
&lt;li&gt;包有可能不存在：这问题之前npm遇到过，发布者将库删了，结果依赖它的一堆库都挂了。npm的解决方案比较野蛮，所有上了npm的包不允许删除，永远会留在里面，就杜绝了库消失的问题。go在这方面更弱，很多东西都是一个地址，要是github库被作者删了，或者转private了，马上就出问题，而且还没人管得着&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题官方应该都是有意识到的，具体可以看这篇官方的博客：&lt;a href=&quot;https://blog.golang.org/modules2019&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Modules in 2019&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;3-官方文档&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3&quot; aria-label=&quot;3 官方文档 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 官方文档&lt;/h1&gt;
&lt;p&gt;除了github那篇wiki，go语言的官网上并没有针对modules的详细文档（当然从内容上来说那篇也够了）。倒是命令行工具的help里有点内容（因内容过长，这里就不贴了，有兴趣的可以直接用命令查看，建议用&lt;code class=&quot;language-text&quot;&gt;&gt; ~/Downloads/xxx.txt&lt;/code&gt;方式输出查看）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;go help go.mod&lt;/li&gt;
&lt;li&gt;go help modules&lt;/li&gt;
&lt;li&gt;go help module-get&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;4-使用--常用命令-go_mod_use&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8--%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4-go_mod_use&quot; aria-label=&quot;4 使用  常用命令 go_mod_use permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 使用 &amp;#x26; 常用命令 {#GO_MOD_USE}&lt;/h1&gt;
&lt;p&gt;正常使用modules的情况下，其实你并不需要特别做什么，一般就：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用go mod init创建模块定义文件&lt;/li&gt;
&lt;li&gt;使用go get命令下载对应的依赖（或是更新对应的依赖）&lt;/li&gt;
&lt;li&gt;使用go build / go install命令来进行编译&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;和modules功能出来之前没有任何不同，所有的模块管理工作在go的一系列命令中已经默认完成了。比如说&lt;code class=&quot;language-text&quot;&gt;go build&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;go test&lt;/code&gt;，等等，在执行这些命令的时候会自动对代码进行分析，找到缺失的依赖下载并将信息写入到对应的go.mod文件中。&lt;/p&gt;
&lt;h2 id=&quot;go111module&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go111module&quot; aria-label=&quot;go111module permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;GO111MODULE&lt;/h2&gt;
&lt;p&gt;这个环境变量用来控制是否启用modules功能，还是按之前的套路来处理go的包管理。一般来说都用这个版本了，没什么理由不把这个打开（&lt;code class=&quot;language-text&quot;&gt;export GO111MODULE=on&lt;/code&gt;）。如果你的代码是放在GOPATH之外的，那么默认就是打开的，放在GOPATH里的，默认是关闭的（我试下来是如此）。&lt;/p&gt;
&lt;h2 id=&quot;go-mod-init&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go-mod-init&quot; aria-label=&quot;go mod init permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;go mod init&lt;/h2&gt;
&lt;p&gt;初始化代码模块，本质上就是创建一个go.mod文件。关于go.mod，可以看&lt;a href=&quot;#GO_MOD_FILE&quot;&gt;这里&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;go-get--u&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go-get--u&quot; aria-label=&quot;go get  u permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;go get (-u)&lt;/h2&gt;
&lt;p&gt;获取或更新代码，同时会更新对应的go.mod文件。对modules来说，这个命令更多用在更新依赖的版本。&lt;/p&gt;
&lt;h2 id=&quot;go-mod-graph&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go-mod-graph&quot; aria-label=&quot;go mod graph permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;go mod graph&lt;/h2&gt;
&lt;p&gt;打印模块依赖图，也就是打印出模块之间的依赖关系。&lt;/p&gt;
&lt;h2 id=&quot;go-mod-download&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go-mod-download&quot; aria-label=&quot;go mod download permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;go mod download&lt;/h2&gt;
&lt;p&gt;将依赖下载到本地cache。这个命令的应用场景一般是一个成熟项目，go.mod文件已经编辑好了，协同工作的成员可以在拉下代码之后直接用这个命令进行下载，然后就可以开始工作了。&lt;/p&gt;
&lt;h2 id=&quot;go-mod-tidy&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#go-mod-tidy&quot; aria-label=&quot;go mod tidy permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;go mod tidy&lt;/h2&gt;
&lt;p&gt;添加缺失的依赖，并移除没有使用的依赖。算是一个清理工具，一般在做版本的时候比较常用。&lt;/p&gt;
&lt;p&gt;如果你在使用&lt;code class=&quot;language-text&quot;&gt;go mod init&lt;/code&gt;命令创建好一个干净空的go.mod文件之后，使用的是&lt;code class=&quot;language-text&quot;&gt;go build&lt;/code&gt;命令来进行对应的包解析和下载的话（同时go.mod文件的内容也生成了），之后你再使用&lt;code class=&quot;language-text&quot;&gt;go mod tidy&lt;/code&gt;来进行清理会发现：多出来很多之前&lt;code class=&quot;language-text&quot;&gt;go build&lt;/code&gt;命令没有放进go.mod文件的包。&lt;/p&gt;
&lt;p&gt;这里官方有一个解释：&lt;a href=&quot;https://github.com/golang/go/wiki/Modules#why-does-go-mod-tidy-record-indirect-and-test-dependencies-in-my-gomod&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Why does ‘go mod tidy’ record indirect and test dependencies in my ‘go.mod’?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;另，其他命令，例如’go build’和’go test’不会从go.mod移除依赖，即便是那些不再被需要的依赖。实质上会在go.mod里进行删除操作的，就只有&lt;code class=&quot;language-text&quot;&gt;go mod tidy&lt;/code&gt;这个命令。&lt;/p&gt;
&lt;h1 id=&quot;5-模块定义--文件结构&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E6%A8%A1%E5%9D%97%E5%AE%9A%E4%B9%89--%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84&quot; aria-label=&quot;5 模块定义  文件结构 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 模块定义 &amp;#x26; 文件结构&lt;/h1&gt;
&lt;h2 id=&quot;代码根目录的约定&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E4%BB%A3%E7%A0%81%E6%A0%B9%E7%9B%AE%E5%BD%95%E7%9A%84%E7%BA%A6%E5%AE%9A&quot; aria-label=&quot;代码根目录的约定 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;代码根目录的约定&lt;/h2&gt;
&lt;p&gt;一般来说，一个go项目就是一个github代码仓库。go语言的最佳实践是一个包一个文件夹，包名和文件夹名重合。所以这里其实就有一个约定，定死的，github仓库的根目录&lt;code class=&quot;language-text&quot;&gt;必须&lt;/code&gt;是代码的根目录。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;github.com/my/repo/package_name/code.go&lt;br&gt;
=&gt;&lt;br&gt;
/Users/xxx/Codes/Golang/repo/package_name/code.go&lt;/p&gt;
&lt;p&gt;import “github.com/my/repo/package_name”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果不是这么放，下载下来的代码文件和代码中的import路径就不一致了，会导致找不到代码。&lt;/p&gt;
&lt;p&gt;你不可以自己映射一个文件夹作为代码的根节点，比如说：/Users/xxx/Codes/Golang/repo/&lt;code class=&quot;language-text&quot;&gt;src&lt;/code&gt;/package_name/code.go。对于有强迫症的人来说，这还蛮恶心的。&lt;/p&gt;
&lt;p&gt;几个例子可以看下（gin特别极端，所有源码就散落在根目录下，只有一个包，叫gin）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gin-gonic/gin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gin-gonic/gin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/prometheus/prometheus&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus/prometheus&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;模块定义官方范例&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%A8%A1%E5%9D%97%E5%AE%9A%E4%B9%89%E5%AE%98%E6%96%B9%E8%8C%83%E4%BE%8B&quot; aria-label=&quot;模块定义官方范例 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;模块定义官方范例&lt;/h2&gt;
&lt;p&gt;如果你要在代码仓库 github.com/my/repo 创建一个包含两个包（如下列举）的模块：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;github.com/my/repo/foo&lt;/li&gt;
&lt;li&gt;github.com/my/repo/bar&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么你的go.mod文件的第一行将会定义一个模块，命名为：github.com/my/repo，而磁盘上的文件结构如下：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;repo/
├── go.mod
├── bar
│   └── bar.go
└── foo
    └── foo.go&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;6-版本定义--更新&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-%E7%89%88%E6%9C%AC%E5%AE%9A%E4%B9%89--%E6%9B%B4%E6%96%B0&quot; aria-label=&quot;6 版本定义  更新 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. 版本定义 &amp;#x26; 更新&lt;/h1&gt;
&lt;p&gt;在&lt;a href=&quot;#GO_MOD_USE&quot;&gt;之前&lt;/a&gt;我们已经说到，modules的出现并没有天翻地覆改变我们日常工作使用的命令和流程，但我们仍旧需要了解modules的很多细节，才能保证不犯错。这一节关于版本号相关的知识非常细节，也相当重要。&lt;/p&gt;
&lt;h2 id=&quot;tag的命名规范&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#tag%E7%9A%84%E5%91%BD%E5%90%8D%E8%A7%84%E8%8C%83&quot; aria-label=&quot;tag的命名规范 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;tag的命名规范&lt;/h2&gt;
&lt;p&gt;对于tag的命名，Go官方有明确的要求，不可以按自己的想法随便写。值得注意的点只有一点就是三位的版本号之前，必须添加一个&lt;code class=&quot;language-text&quot;&gt;v&lt;/code&gt;，也就是说，所有的版本号都应该是：&lt;code class=&quot;language-text&quot;&gt;v1.2.3&lt;/code&gt;这样的，而&lt;code class=&quot;language-text&quot;&gt;不是&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;1.2.3&lt;/code&gt;这样。&lt;/p&gt;
&lt;p&gt;看两个例子，打开链接之后观察下他们的版本号列表：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node.js的web服务器：&lt;a href=&quot;https://github.com/expressjs/express&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;expressjs/express&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Go的web服务器：&lt;a href=&quot;https://github.com/gin-gonic/gin&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gin-gonic/gin&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;版本选择&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%89%88%E6%9C%AC%E9%80%89%E6%8B%A9&quot; aria-label=&quot;版本选择 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;版本选择&lt;/h2&gt;
&lt;p&gt;wiki原文可以查看：&lt;a href=&quot;https://github.com/golang/go/wiki/Modules#version-selection&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Version Selection&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;主要内容是说明在使用一些go命令，比如说’go build’、‘go test’的时候，这些命令会怎么选择依赖的版本号。这里需要关注的是，如果有多个依赖对某个依赖都有版本要求，且版本号并不一致，这种情况下会发生什么：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As an example, if your module depends on module A which has a require D v1.0.0, and your module also depends on module B which has a require D v1.1.1, then minimal version selection would choose v1.1.1 of D to include in the build (given it is the highest listed require version). This selection of v1.1.1 remains consistent even if some time later a v1.2.0 of D becomes available. This is an example of how the modules system provides 100% reproducible builds. When ready, the module author or user might choose to upgrade to the latest available version of D or choose an explicit version for D.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;在工具第一次处理同个依赖的多处引入的情况下，会引入该依赖的最高版本。&lt;/li&gt;
&lt;li&gt;这个版本会在此后保持不变（go.mod中），即便这个依赖的新版本被release出来（作者更新）。这是为了保证产品100%可重复构建。用户可以自行选择升级与否。&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;值得注意的是原文wiki中有一句：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;require M v1.2.3, which indicates module M is a dependency with allowed version &gt;= v1.2.3 (and &amp;#x3C; v2, given v2 is considered incompatible with v1)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我没理解这是什么意思，后续需要尝试。猜测：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;虽然go.mod文件中对于M的版本定义是v1.2.3，但允许的版本可以&gt;=v1.2.3，并小于v2.x.x大版本&lt;/li&gt;
&lt;li&gt;如果git clone一个带go.mod文件的库（clone下来的时候磁盘上无cache文件），使用go mod download，go.mod里对于这个库的定义是v1.2.3，但最新的release是v1.3.9，那么会下载v1.3.9？&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;版本引入&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%89%88%E6%9C%AC%E5%BC%95%E5%85%A5&quot; aria-label=&quot;版本引入 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;版本引入&lt;/h2&gt;
&lt;p&gt;wiki原文可以查看：&lt;a href=&quot;https://github.com/golang/go/wiki/Modules#semantic-import-versioning&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Semantic Import Versioning&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;使用过modules之后，会发现某些依赖的引入的最后带上了&lt;code class=&quot;language-text&quot;&gt;.vN&lt;/code&gt;这样的字符，这里有点细节可以看下：&lt;/p&gt;
&lt;p&gt;major版本是v2或更高的，在require的时候都需要在路径最后带上&lt;code class=&quot;language-text&quot;&gt;.vN&lt;/code&gt;（官方给的例子里是&lt;code class=&quot;language-text&quot;&gt;/vN&lt;/code&gt;，但我实际看下来几个包都是&lt;code class=&quot;language-text&quot;&gt;.vN&lt;/code&gt;，先按实际例子来吧），比如说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;require gopkg.in/go-playground/validator.v8 v8.18.2&lt;/li&gt;
&lt;li&gt;require gopkg.in/yaml.v2 v2.2.2&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;此外，在使用的时候（import）：&lt;code class=&quot;language-text&quot;&gt;example&amp;amp;#46;com/my/mod/mypkg&lt;/code&gt;和&lt;code class=&quot;language-text&quot;&gt;example&amp;amp;#46;com/my/mod.v2/mypkg&lt;/code&gt;被认为是两个不同的包，会分开下载安装，且不会影响最后的编译。&lt;/p&gt;
&lt;h2 id=&quot;如何更新依赖的版本&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%A6%82%E4%BD%95%E6%9B%B4%E6%96%B0%E4%BE%9D%E8%B5%96%E7%9A%84%E7%89%88%E6%9C%AC&quot; aria-label=&quot;如何更新依赖的版本 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;如何更新依赖的版本&lt;/h2&gt;
&lt;p&gt;日常中对依赖进行版本升级或降级，应该使用&lt;code class=&quot;language-text&quot;&gt;go get&lt;/code&gt;命令：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;go get dep&lt;/code&gt;将依赖升级到最新版本（等同于&lt;code class=&quot;language-text&quot;&gt;go get dep@latest&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;go get -u dep&lt;/code&gt;将依赖升级到最新的minor或者patch版本&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;go get -u=patch dep&lt;/code&gt;将依赖升级到最新的patch版本&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;go get dep@v1.2.3&lt;/code&gt;将依赖升级（或降级）到指定版本&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：使用&lt;code class=&quot;language-text&quot;&gt;go get -u&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;go get -u=patch&lt;/code&gt;将会一并更新&lt;code class=&quot;language-text&quot;&gt;dep&lt;/code&gt;的所有直接和间接依赖。最佳实践是先不要带上&lt;code class=&quot;language-text&quot;&gt;-u&lt;/code&gt;参数运行&lt;code class=&quot;language-text&quot;&gt;go get&lt;/code&gt;，更新完成没有问题之后，再带上&lt;code class=&quot;language-text&quot;&gt;-u=patch&lt;/code&gt;，然后&lt;code class=&quot;language-text&quot;&gt;-u&lt;/code&gt;，逐步更新。更新依赖的时候也最好一个一个更新，便于排查。&lt;/p&gt;
&lt;p&gt;此外，同样会对go.mod文件进行更改的一系列命令，比如：‘go build’、‘go test’，或者是’go list’，会自动添加新需要的依赖进入go.mod来满足依赖（更新go.mod文件，并下载对应的新依赖）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果要查看所有可以使用的直接或间接依赖升级，请使用命令：&lt;code class=&quot;language-text&quot;&gt;go list -u -m all&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果需要查看一个依赖的可用版本，请使用命令：&lt;code class=&quot;language-text&quot;&gt;go list -m -versions $depname&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这部分，更详细的可以参见：&lt;a href=&quot;https://github.com/golang/go/wiki/Modules#how-to-upgrade-and-downgrade-dependencies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to Upgrade and Downgrade Dependencies&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;7-补充gomod--replace指令-go_mod_file&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-%E8%A1%A5%E5%85%85gomod--replace%E6%8C%87%E4%BB%A4-go_mod_file&quot; aria-label=&quot;7 补充gomod  replace指令 go_mod_file permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. 补充：go.mod &amp;#x26; replace指令 {#GO_MOD_FILE}&lt;/h1&gt;
&lt;p&gt;官方wiki里关于go.mod的说明可以看这里：&lt;a href=&quot;https://github.com/golang/go/wiki/Modules#gomod&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go.mod&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;go.mod文件里的指令有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;module, to define the module path;&lt;/li&gt;
&lt;li&gt;go, to set the expected language version;&lt;/li&gt;
&lt;li&gt;require, to require a particular module at a given version or later;&lt;/li&gt;
&lt;li&gt;exclude, to exclude a particular module version from use; and&lt;/li&gt;
&lt;li&gt;replace, to replace a module version with a different module version.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：exclude和replace指令只在主模块的go.mod文件中生效，在依赖中则会被忽略。&lt;/p&gt;
&lt;p&gt;比如说依赖库里用到了 golang.org/x 里的包，你因为网络关系，在你自己的go.mod将这个库replace掉了，但下载完成之后你会发现在cache里还是会有golang.org/x的代码文件，因为第三方依赖可能用到它们了。&lt;/p&gt;
&lt;h2 id=&quot;replace指令&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#replace%E6%8C%87%E4%BB%A4&quot; aria-label=&quot;replace指令 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;replace指令&lt;/h2&gt;
&lt;p&gt;在go.mod文件中，用得比较频繁的指令一般就只有require和replace。require不用多说，非常简单，replace还是有点细节的。&lt;/p&gt;
&lt;p&gt;一般的使用场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用本地代码：replace example.com/original/import/path =&gt; /your/forked/import/path&lt;/li&gt;
&lt;li&gt;指定特定版本：replace example.com/some/dependency =&gt; example.com/some/dependency v1.2.3&lt;/li&gt;
&lt;li&gt;指定特定下载地址（特别适合国内）：replace golang.org/x/dependency =&gt; github.com/golang/dependency&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;replace是一个指令，所以它是和require同等级别，相同的使用方法，并不是要和require组合起来使用的，单独使用即可。replace指令引入的包也会直接下载。&lt;/p&gt;
&lt;p&gt;可以试验下下面的例子：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;require &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;..&lt;/span&gt;.
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

replace golang.org/x/net &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; github.com/golang/net v0.0.0-20190301231341-16b79f2e4e95&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt; main

&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;golang.org/x/net/html&quot;&lt;/span&gt;
	&lt;span class=&quot;token string&quot;&gt;&quot;strings&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	z&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errp &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; html&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;strings&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NewReader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;html&gt;&amp;lt;/html&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; errp &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;errp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;z&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;8-实际经验&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-%E5%AE%9E%E9%99%85%E7%BB%8F%E9%AA%8C&quot; aria-label=&quot;8 实际经验 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. 实际经验&lt;/h1&gt;
&lt;p&gt;如果定义一个模块名为&lt;code class=&quot;language-text&quot;&gt;test-module&lt;/code&gt;（一般不会这么干，都是以代码仓库为模块名，e.g &lt;code class=&quot;language-text&quot;&gt;github.com/gin-gonic/gin&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;go.mod文件第一行为：&lt;code class=&quot;language-text&quot;&gt;module test-module&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;该模块代码文件必须存放在&lt;code class=&quot;language-text&quot;&gt;$GOPATH/src/test-module&lt;/code&gt;下&lt;/li&gt;
&lt;li&gt;代码包申明及引用相关：
&lt;ul&gt;
&lt;li&gt;代码文件的物理文件夹位置即包名&lt;/li&gt;
&lt;li&gt;源码文件中的包名申明只需要路径的最后一段在代码中写明，不需要完整路径
&lt;ul&gt;
&lt;li&gt;e.g&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;test-module/lib/dao&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;代码中的包为&lt;code class=&quot;language-text&quot;&gt;package dao&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;其他代码引用的时候永远以模块名为起始，不能使用相对路径，即便是同模块的其他代码，e.g &lt;code class=&quot;language-text&quot;&gt;import &quot;test-module/lib/dao&quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;正因此，go项目的源码总是散在根目录下面的，不可以自行组织子文件夹
&lt;ul&gt;
&lt;li&gt;✗ &lt;code class=&quot;language-text&quot;&gt;$GOPATH/src/test-module/src/lib/dao&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;✗ &lt;code class=&quot;language-text&quot;&gt;$GOPATH/src/test-module/dao/lib/dao&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;√ &lt;code class=&quot;language-text&quot;&gt;$GOPATH/src/test-module/lib/dao&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这也是为什么我的&lt;a href=&quot;https://github.com/agreatfool/dist-system-practice&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;分布式实践项目代码库&lt;/a&gt;不能作为一个go模块来使用，因为我的实践代码库中，源代码相关内容并不是存放在根目录下面的。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist-system-practice /-
                      | ... # 其他大量资料
                      | golang /- # 自定义的$GOPATH
                                | src /-
                                       | dist-system-practice # 这里才是真正的项目代码&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;而要作为一个go模块来使用，则文件结构只能是：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;dist-system-practice /-
                      | # 这里直接就是源码了
                      | lib 
                      | vendors
                      | web
                      | ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;代码直接放在代码库根目录下。&lt;/p&gt;
&lt;h1 id=&quot;资料&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%B5%84%E6%96%99&quot; aria-label=&quot;资料 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;资料&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/golang/go/wiki/Modules&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.11 Modules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/modules2019&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go Modules in 2019&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://windmt.com/2018/11/08/first-look-go-modules/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 包管理解决之道 —— Modules 初试&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Basic]]></title><link>https://xenojoshua.com/posts/2019/03/golang-basic</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/03/golang-basic</guid><pubDate>Mon, 04 Mar 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80&quot;&gt;2. 语言基础&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#21-%E4%BB%A3%E7%A0%81%E6%A8%A1%E5%9D%97-module&quot;&gt;2.1 代码模块 module&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#internal&quot;&gt;internal&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#22-%E5%8F%98%E9%87%8F-variable&quot;&gt;2.2 变量 variable&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%A8%8B%E5%BA%8F%E5%AE%9E%E4%BD%93&quot;&gt;程序实体&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B&quot;&gt;基本类型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B&quot;&gt;引用类型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%80%BC%E4%BC%A0%E9%80%92--%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92&quot;&gt;值传递 &amp;#x26; 引用传递&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F%E7%94%B3%E6%98%8E&quot;&gt;变量申明&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F%E5%88%9D%E5%A7%8B%E5%8C%96--new--make&quot;&gt;变量初始化 &amp;#x26; new &amp;#x26; make&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%B1%BB%E5%9E%8B&quot;&gt;表达式类型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D--%E5%86%8D%E5%AE%9A%E4%B9%89&quot;&gt;类型别名 &amp;#x26; 再定义&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%95%B0%E7%BB%84--%E5%88%87%E7%89%87&quot;&gt;数组 &amp;#x26; 切片&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#map&quot;&gt;map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%98%BE%E7%A4%BA%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2&quot;&gt;显示类型转换&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80&quot;&gt;类型断言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%89%93%E5%8D%B0%E7%B1%BB%E5%9E%8B&quot;&gt;打印类型&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#23-%E5%BE%AA%E7%8E%AF--%E5%88%A4%E6%96%AD&quot;&gt;2.3 循环 &amp;#x26; 判断&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#if&quot;&gt;if&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#for&quot;&gt;for&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#switch&quot;&gt;switch&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#range&quot;&gt;range&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#24-%E9%80%9A%E9%81%93--%E4%BF%A1%E9%81%93-channel-id_channel&quot;&gt;2.4 通道 / 信道 channel {#ID_CHANNEL}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%80%9A%E9%81%93%E7%BC%93%E5%AD%98&quot;&gt;通道缓存&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%A1%BA%E5%BA%8F&quot;&gt;顺序&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98&quot;&gt;内存&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%98%BB%E5%A1%9E&quot;&gt;阻塞&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#select&quot;&gt;select&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%85%B3%E9%97%AD&quot;&gt;关闭&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#25-%E5%87%BD%E6%95%B0-func&quot;&gt;2.5 函数 func&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%82%E6%95%B0&quot;&gt;参数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AE%98%E6%96%B9%E9%97%AD%E5%8C%85tutorial&quot;&gt;官方闭包tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#26-%E7%B1%BB%E5%9E%8B-struct&quot;&gt;2.6 类型 struct&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%8D%A2%E5%87%BD%E6%95%B0&quot;&gt;字符串转换函数&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B5%8C%E5%85%A5%E5%AD%97%E6%AE%B5--%E5%8C%BF%E5%90%8D%E5%AD%97%E6%AE%B5&quot;&gt;嵌入字段 / 匿名字段&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%B5%8C%E5%85%A5%E5%AD%97%E6%AE%B5%E4%B8%8E%E7%BB%A7%E6%89%BF%E5%8C%BA%E5%88%AB&quot;&gt;嵌入字段与继承区别&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%8E%A5%E6%94%B6%E8%80%85%E7%B1%BB%E5%9E%8B&quot;&gt;接收者类型&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#struct%E7%B1%BB%E5%9E%8B%E5%80%BC&quot;&gt;struct{}类型值&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#27-%E6%8E%A5%E5%8F%A3-interface&quot;&gt;2.7 接口 interface&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#28-%E6%8C%87%E9%92%88-pointer&quot;&gt;2.8 指针 pointer&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%93%8D%E4%BD%9C%E7%AC%A6&quot;&gt;操作符&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E5%8F%AF%E5%90%A6%E5%AF%BB%E5%9D%80&quot;&gt;可否寻址&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#%E6%89%93%E5%8D%B0%E6%8C%87%E9%92%88%E6%96%B9%E6%B3%95&quot;&gt;打印指针方法&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#29-go%E7%A8%8B-goroutine&quot;&gt;2.9 Go程 goroutine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#210-%E9%94%99%E8%AF%AF-error&quot;&gt;2.10 错误 error&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#%E9%94%99%E8%AF%AF%E5%88%A4%E6%96%AD&quot;&gt;错误判断&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#panic&quot;&gt;panic&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#defer&quot;&gt;defer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8&quot;&gt;3. 工具使用&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#31-go-build&quot;&gt;3.1 go build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#32-go-install&quot;&gt;3.2 go install&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#33-go-get&quot;&gt;3.3 go get&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#34-go-clean&quot;&gt;3.4 go clean&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#35-go-doc--godoc&quot;&gt;3.5 go doc &amp;#x26; godoc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#36-go-run&quot;&gt;3.6 go run&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#37-go-test&quot;&gt;3.7 go test&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#38-go-list&quot;&gt;3.8 go list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#39-go-fmt--gofmt&quot;&gt;3.9 go fmt &amp;#x26; gofmt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#310-go-fix--go-tool-fix&quot;&gt;3.10 go fix &amp;#x26; go tool fix&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#311-go-vet--go-tool-vet&quot;&gt;3.11 go vet &amp;#x26; go tool vet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#312-go-tool-pprof&quot;&gt;3.12 go tool pprof&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#313-go-tool-cgo&quot;&gt;3.13 go tool cgo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#314-go-env&quot;&gt;3.14 go env&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E8%BF%9B%E9%98%B6%E6%A6%82%E5%BF%B5&quot;&gt;4. 进阶概念&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#41-%E5%87%BD%E6%95%B0%E5%86%85%E8%81%94&quot;&gt;4.1 函数内联&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E6%9D%82%E9%A1%B9&quot;&gt;5. 杂项&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#map%E5%80%BC%E7%9A%84%E5%8F%96%E5%9D%80&quot;&gt;Map值的取址&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;本文是Go语言系列文章&lt;a href=&quot;/2019/02/golang-note/&quot;&gt;Golang Notes&lt;/a&gt;的其中一篇，完整的文章列表请去总章查看。&lt;/p&gt;
&lt;p&gt;本篇主要着眼于阐述一些Go语言中的基础知识点。当然，语法本身涉及的不会太多，看&lt;a href=&quot;https://tour.golang.org/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;官方的tutorial&lt;/a&gt;就好，Go语言本身就以语法不复杂著称。&lt;/p&gt;
&lt;p&gt;这里要介绍下极客时间上的专题：&lt;a href=&quot;https://time.geekbang.org/column/112&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go语言核心36讲&lt;/a&gt;&lt;br&gt;
随书附带的代码：&lt;a href=&quot;https://github.com/hyper0x/Golang_Puzzlers&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;hyper0x/Golang_Puzzlers&lt;/a&gt;&lt;br&gt;
总的来说讲的内容不算很深，一看作者的专业功底就很好，用词和语言都非常专业和规范，和看一些大部头的技术书感觉很类似。优点在于讲解内容不是很深，适合新手使用。缺点在于部分章节的安排不是很好，前后关系以及一些对于新手来说需要介绍的内容过渡不够，此外，范例和文章的契合度不够，作者在很多情况下都是给了个github库的链接，让读者自己去匹配着看，体验不够好。&lt;/p&gt;
&lt;p&gt;此外，还有一个以范例来进行Go语言基础编码指导的站点：&lt;a href=&quot;https://gobyexample.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go by Example&lt;/a&gt;，可以利用。&lt;/p&gt;
&lt;h1 id=&quot;2-语言基础&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80&quot; aria-label=&quot;2 语言基础 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 语言基础&lt;/h1&gt;
&lt;h2 id=&quot;21-代码模块-module&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#21-%E4%BB%A3%E7%A0%81%E6%A8%A1%E5%9D%97-module&quot; aria-label=&quot;21 代码模块 module permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.1 代码模块 module&lt;/h2&gt;
&lt;p&gt;名称的首字母为大写的程序实体才可以被当前包外的代码引用，否则它就只能被当前包内的其他代码引用。小写，包私有；大写，公开。&lt;/p&gt;
&lt;h3 id=&quot;internal&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#internal&quot; aria-label=&quot;internal permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;internal&lt;/h3&gt;
&lt;p&gt;路径和包名为internal的是模块私有的代码，无法被外部引用。&lt;br&gt;
具体规则是，internal代码包中声明的公开程序实体仅能被该代码包的直接父包及其子包中的代码引用。当然，引用前需要先导入这个internal包。对于其他代码包，导入该internal包都是非法的，无法通过编译。&lt;/p&gt;
&lt;h2 id=&quot;22-变量-variable&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#22-%E5%8F%98%E9%87%8F-variable&quot; aria-label=&quot;22 变量 variable permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.2 变量 variable&lt;/h2&gt;
&lt;h3 id=&quot;程序实体&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%A8%8B%E5%BA%8F%E5%AE%9E%E4%BD%93&quot; aria-label=&quot;程序实体 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;程序实体&lt;/h3&gt;
&lt;p&gt;Go 语言中的&lt;code class=&quot;language-text&quot;&gt;程序实体&lt;/code&gt;包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;变量&lt;/li&gt;
&lt;li&gt;常量&lt;/li&gt;
&lt;li&gt;函数&lt;/li&gt;
&lt;li&gt;结构体&lt;/li&gt;
&lt;li&gt;接口&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;基本类型&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%9F%BA%E6%9C%AC%E7%B1%BB%E5%9E%8B&quot; aria-label=&quot;基本类型 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;基本类型&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;bool&lt;/p&gt;
&lt;p&gt;string&lt;/p&gt;
&lt;p&gt;int  int8  int16  int32  int64&lt;br&gt;
uint uint8 uint16 uint32 uint64 uintptr&lt;br&gt;
byte // uint8 的别名&lt;/p&gt;
&lt;p&gt;rune // int32 的别名&lt;br&gt;
// 表示一个 Unicode 码点&lt;/p&gt;
&lt;p&gt;float32 float64&lt;/p&gt;
&lt;p&gt;complex64 complex128&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;因为是强类型语言，且Go里面的类型转换都必须要显示进行，因此有的时候处理起来比较麻烦。这方面，比较常见的问题是字符串和数字类型之间的转换：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// string =&gt; int&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; strconv&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Atoi&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// string =&gt; int64&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; strconv&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ParseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// int =&gt; string&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; strconv&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Itoa&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// int64 =&gt; string&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; strconv&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;FormatInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;引用类型&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%BC%95%E7%94%A8%E7%B1%BB%E5%9E%8B&quot; aria-label=&quot;引用类型 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;引用类型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;slice&lt;/li&gt;
&lt;li&gt;map&lt;/li&gt;
&lt;li&gt;channel&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它们本身就是对某种类型指针的封装：slice封装的指针是一个数组，所以传递的时候直接传递其本身就够了，一般来说不需要取址（&amp;#x26;）&lt;/p&gt;
&lt;h3 id=&quot;值传递--引用传递&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%80%BC%E4%BC%A0%E9%80%92--%E5%BC%95%E7%94%A8%E4%BC%A0%E9%80%92&quot; aria-label=&quot;值传递  引用传递 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;值传递 &amp;#x26; 引用传递&lt;/h3&gt;
&lt;p&gt;Go 语言里不存在像 Java 等编程语言中令人困惑的“传值或传引用”问题。在 Go 语言中，我们判断所谓的“传值”或者“传引用”只要看被传递的值的类型就好了。如果传递的值是引用类型的，那么就是“传引用”。如果传递的值是值类型的，那么就是“传值”。从传递成本的角度讲，引用类型的值往往要比值类型的值低很多。&lt;/p&gt;
&lt;h3 id=&quot;变量申明&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F%E7%94%B3%E6%98%8E&quot; aria-label=&quot;变量申明 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;变量申明&lt;/h3&gt;
&lt;p&gt;Go 语言在声明变量时，自动对变量对应的内存区域进行初始化操作。每个变量会初始化其类型的默认值，例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;整型和浮点型变量的默认值为 0。&lt;/li&gt;
&lt;li&gt;字符串变量的默认值为空字符串。&lt;/li&gt;
&lt;li&gt;布尔型变量默认为 bool。&lt;/li&gt;
&lt;li&gt;切片、函数、指针变量的默认为 nil。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以看到某个被申明的变量直接被拿来使用的时候千万不要惊奇，并不是一定要进行初始化才可以使用。&lt;/p&gt;
&lt;h3 id=&quot;变量初始化--new--make&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%8F%98%E9%87%8F%E5%88%9D%E5%A7%8B%E5%8C%96--new--make&quot; aria-label=&quot;变量初始化  new  make permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;变量初始化 &amp;#x26; new &amp;#x26; make&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://golang.org/doc/faq#stack_or_heap&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How do I know whether a variable is allocated on the heap or the stack?&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.flysnow.org/2017/10/23/go-new-vs-make.html&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go语言中new和make的区别&lt;/a&gt;{:target:“_blank”}&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;两者都是内存的分配（堆内存）&lt;/li&gt;
&lt;li&gt;初始值：
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;make&lt;/code&gt;只用于slice、map以及channel的初始化（非零值）&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;new&lt;/code&gt;用于类型（struct）的内存分配，并且内存置为零&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;返回值：
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;make&lt;/code&gt;返回的还是这三个引用类型本身：&lt;code class=&quot;language-text&quot;&gt;func make(t Type, size ...IntegerType) Type&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;new&lt;/code&gt;返回的是指向类型的指针：&lt;code class=&quot;language-text&quot;&gt;func new(Type) *Type&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;表达式类型&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E8%A1%A8%E8%BE%BE%E5%BC%8F%E7%B1%BB%E5%9E%8B&quot; aria-label=&quot;表达式类型 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;表达式类型&lt;/h3&gt;
&lt;p&gt;你可以认为，表达式类型就是对表达式进行求值后得到结果的类型。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[]string&lt;/code&gt;是一个类型字面量。所谓类型字面量，就是用来表示数据类型本身的若干个字符。&lt;/p&gt;
&lt;h3 id=&quot;类型别名--再定义&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%B1%BB%E5%9E%8B%E5%88%AB%E5%90%8D--%E5%86%8D%E5%AE%9A%E4%B9%89&quot; aria-label=&quot;类型别名  再定义 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;类型别名 &amp;#x26; 再定义&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; MyString &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 这条声明语句表示，MyString是string类型的别名类型。    &lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; MyString2 &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 注意，这里没有等号。这里的MyString2是一个新的类型，不同于其他任何类型。这种方式也可以被叫做对类型的再定义。&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;数组--切片&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%95%B0%E7%BB%84--%E5%88%87%E7%89%87&quot; aria-label=&quot;数组  切片 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;数组 &amp;#x26; 切片&lt;/h3&gt;
&lt;p&gt;数组类型的值（以下简称数组）的长度是固定的，而切片类型的值（以下简称切片）是可变长的。Go 语言的切片类型属于引用类型，同属引用类型的还有字典类型、通道类型、函数类型等；而 Go 语言的数组类型则属于值类型，同属值类型的有基础数据类型以及结构体类型。（引用类型主要就这几种，不多的）&lt;/p&gt;
&lt;p&gt;Go 语言里的切片长度和容量。长度指当前切片中的真实元素有多少个，容量指切片申请的内存容量是多少。&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;[...]int{1, 2, 3, 4, 5, 6}&lt;/code&gt; 用三个点代替了长度申明，这句语句执行的结果仍旧是一个数组，而不是切片。&lt;/p&gt;
&lt;p&gt;从数组生成切片时，上界含，下界不含：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; s &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; primes&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;1号位包含，4号位不含&lt;/p&gt;
&lt;h3 id=&quot;map&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#map&quot; aria-label=&quot;map permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;map&lt;/h3&gt;
&lt;p&gt;判断map中键是否存在：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;elem&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ok &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// OR    &lt;/span&gt;
&lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ok &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;显示类型转换&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%98%BE%E7%A4%BA%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2&quot; aria-label=&quot;显示类型转换 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;显示类型转换&lt;/h3&gt;
&lt;p&gt;表达式 T(v) 将值 v 转换为类型 T。&lt;br&gt;
所有的类型转换必须是显示的。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;f &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;float32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;类型断言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E7%B1%BB%E5%9E%8B%E6%96%AD%E8%A8%80&quot; aria-label=&quot;类型断言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;类型断言&lt;/h3&gt;
&lt;p&gt;官方文档：&lt;a href=&quot;https://golang.org/ref/spec#Type_assertions&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Type assertions&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;类型断言表达式的语法形式是x.(T)。其中的x代表要被判断类型的值。这个值当下的类型必须是接口类型的，不过具体是哪个接口类型其实是无所谓的。&lt;br&gt;
&lt;code class=&quot;language-text&quot;&gt;value, ok := interface{}(container).([]string)&lt;/code&gt;&lt;br&gt;
一对不包裹任何东西的花括号，除了可以代表空的代码块之外，还可以用于表示不包含任何内容的数据结构（或者说数据类型）。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ok &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;TypeOK:&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ok&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// OR&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hello&quot;&lt;/span&gt;
&lt;span class=&quot;token boolean&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ok &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// OR&lt;/span&gt;
reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;TypeOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// return Type&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这个ok还是必要的，否则在类型不匹配的时候会发生panic&lt;/p&gt;
&lt;p&gt;根据不同类型进行不同行为&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;m_type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;打印类型&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%89%93%E5%8D%B0%E7%B1%BB%E5%9E%8B&quot; aria-label=&quot;打印类型 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;打印类型&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;The type of pet is %T.\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pet&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;The type of pet is %s.\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reflect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;TypeOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pet&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;23-循环--判断&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#23-%E5%BE%AA%E7%8E%AF--%E5%88%A4%E6%96%AD&quot; aria-label=&quot;23 循环  判断 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.3 循环 &amp;#x26; 判断&lt;/h2&gt;
&lt;h3 id=&quot;if&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#if&quot; aria-label=&quot;if permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;if&lt;/h3&gt;
&lt;p&gt;if 在判断之前可以添加一句简单的语句进行执行&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; lim &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; v
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;for&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#for&quot; aria-label=&quot;for permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;for&lt;/h3&gt;
&lt;p&gt;没有初始化语句和后置语句的 for 就是其他语言中的 while，这种情况下可以删除前后的分号&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;switch&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#switch&quot; aria-label=&quot;switch permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;switch&lt;/h3&gt;
&lt;p&gt;switch 只会执行符合的条件，不会一路 fallthrough 下去&lt;br&gt;
switch 还可以不带上判断条件，这样使用就等于if-else-else…&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Hour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Good morning!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Hour&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Good afternoon.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Good evening.&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;range&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#range&quot; aria-label=&quot;range permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;range&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;range表达式只会在for语句开始执行时被求值一次，无论后边会有多少次迭代；&lt;/li&gt;
&lt;li&gt;range表达式的求值结果会被复制，也就是说，被迭代的对象是range表达式结果值的副本而不是原值。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&quot;24-通道--信道-channel-id_channel&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#24-%E9%80%9A%E9%81%93--%E4%BF%A1%E9%81%93-channel-id_channel&quot; aria-label=&quot;24 通道  信道 channel id_channel permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.4 通道 / 信道 channel {#ID_CHANNEL}&lt;/h2&gt;
&lt;h3 id=&quot;通道缓存&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%80%9A%E9%81%93%E7%BC%93%E5%AD%98&quot; aria-label=&quot;通道缓存 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;通道缓存&lt;/h3&gt;
&lt;p&gt;通道，make函数除了必须接收这样的类型字面量作为参数，还可以接收一个int类型的参数。后者是可选的，用于表示该通道的容量。所谓通道的容量，就是指通道最多可以缓存多少个元素值。&lt;/p&gt;
&lt;h3 id=&quot;顺序&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%A1%BA%E5%BA%8F&quot; aria-label=&quot;顺序 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;顺序&lt;/h3&gt;
&lt;p&gt;一个通道相当于一个先进先出（FIFO）的队列。也就是说，通道中的各个元素值都是严格地按照发送的顺序排列的，先被发送通道的元素值一定会先被接收。&lt;/p&gt;
&lt;p&gt;对于同一个通道，发送操作之间是互斥的，接收操作之间也是互斥的。在同一时刻，Go 语言的运行时系统（以下简称运行时系统）只会执行对同一个通道的任意个发送操作中的某一个。直到这个元素值被完全复制进该通道之后，其他针对该通道的发送操作才可能被执行。对于通道中的同一个元素值来说，发送操作和接收操作之间也是互斥的。&lt;/p&gt;
&lt;h3 id=&quot;内存&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%86%85%E5%AD%98&quot; aria-label=&quot;内存 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;内存&lt;/h3&gt;
&lt;p&gt;元素值从外界进入通道时会被&lt;code class=&quot;language-text&quot;&gt;复制&lt;/code&gt;。更具体地说，进入通道的并不是在接收操作符右边的那个元素值，而是它的副本。另一方面，元素值从通道进入外界时会被移动。这个移动操作实际上包含了两步，第一步是生成正在通道中的这个元素值的副本，并准备给到接收方，第二步是删除在通道中的这个元素值。&lt;/p&gt;
&lt;h3 id=&quot;阻塞&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%98%BB%E5%A1%9E&quot; aria-label=&quot;阻塞 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;阻塞&lt;/h3&gt;
&lt;p&gt;发送操作和接收操作中对元素值的处理都是不可分割的。例如，发送操作要么还没复制元素值，要么已经复制完毕，绝不会出现只复制了一部分的情况。&lt;/p&gt;
&lt;p&gt;发送操作在完全完成之前会被&lt;code class=&quot;language-text&quot;&gt;阻塞&lt;/code&gt;。接收操作也是如此。&lt;/p&gt;
&lt;p&gt;针对&lt;code class=&quot;language-text&quot;&gt;缓冲通道&lt;/code&gt;的情况。如果通道已满，那么对它的所有发送操作都会被阻塞，直到通道中有元素值被接收走。如果通道已空，那么对它的所有接收操作都会被阻塞，直到通道中有新的元素值出现。&lt;/p&gt;
&lt;p&gt;对于&lt;code class=&quot;language-text&quot;&gt;非缓冲通道&lt;/code&gt;，情况要简单一些。无论是发送操作还是接收操作，一开始执行就会被阻塞，直到配对的操作也开始执行，才会继续传递。由此可见，非缓冲通道是在用同步的方式传递数据。也就是说，只有收发双方对接上了，数据才会被传递。并且，数据是直接从发送方复制到接收方的，中间并不会用非缓冲通道做中转。相比之下，缓冲通道则在用异步的方式传递数据。&lt;/p&gt;
&lt;h3 id=&quot;select&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#select&quot; aria-label=&quot;select permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;select&lt;/h3&gt;
&lt;p&gt;select语句只能与通道联用，它一般由若干个分支组成。每次执行这种语句的时候，一般只有一个分支中的代码会被运行。仅当select语句中的所有case表达式都被求值完毕后，它才会开始选择候选分支。&lt;/p&gt;
&lt;h3 id=&quot;关闭&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%85%B3%E9%97%AD&quot; aria-label=&quot;关闭 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;关闭&lt;/h3&gt;
&lt;p&gt;只有发送者才能关闭信道，而接收者不能。向一个已经关闭的信道发送数据会引发程序恐慌（panic）。
信道与文件不同，通常情况下无需关闭它们。只有在必须告诉接收者不再有需要发送的值时才有必要关闭，例如终止一个 range 循环。&lt;/p&gt;
&lt;h2 id=&quot;25-函数-func&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#25-%E5%87%BD%E6%95%B0-func&quot; aria-label=&quot;25 函数 func permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.5 函数 func&lt;/h2&gt;
&lt;h3 id=&quot;参数&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%8F%82%E6%95%B0&quot; aria-label=&quot;参数 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;参数&lt;/h3&gt;
&lt;p&gt;传入函数的参数值：数组是值类型，所以每一次复制都会拷贝它，以及它的所有元素值。对于引用类型，比如：切片、字典、通道，像上面那样复制它们的值，只会拷贝它们本身而已，并不会拷贝它们引用的底层数据。也就是说，这时只是浅表复制，而不是深层复制。&lt;/p&gt;
&lt;h3 id=&quot;官方闭包tutorial&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%AE%98%E6%96%B9%E9%97%AD%E5%8C%85tutorial&quot; aria-label=&quot;官方闭包tutorial permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;官方闭包tutorial&lt;/h3&gt;
&lt;p&gt;Go 函数可以是一个闭包。闭包是一个函数值，它引用了其函数体之外的变量。该函数可以访问并赋予其引用的变量的值，换句话说，该函数被“绑定”在了这些变量上。&lt;/p&gt;
&lt;p&gt;例如，函数 adder 返回一个闭包。每个闭包都被绑定在其各自的 sum 变量上。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;adder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	sum &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		sum &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; x
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; sum
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	pos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; neg &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;adder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;adder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;token function&quot;&gt;pos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token function&quot;&gt;neg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;26-类型-struct&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#26-%E7%B1%BB%E5%9E%8B-struct&quot; aria-label=&quot;26 类型 struct permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.6 类型 struct&lt;/h2&gt;
&lt;h3 id=&quot;字符串转换函数&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BD%AC%E6%8D%A2%E5%87%BD%E6%95%B0&quot; aria-label=&quot;字符串转换函数 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;字符串转换函数&lt;/h3&gt;
&lt;p&gt;在 Go 语言中，我们可以通过为一个类型编写名为String的方法，来自定义该类型的字符串表示形式。这个String方法不需要任何参数声明，但需要有一个string类型的结果声明。&lt;/p&gt;
&lt;h3 id=&quot;嵌入字段--匿名字段&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%B5%8C%E5%85%A5%E5%AD%97%E6%AE%B5--%E5%8C%BF%E5%90%8D%E5%AD%97%E6%AE%B5&quot; aria-label=&quot;嵌入字段  匿名字段 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;嵌入字段 / 匿名字段&lt;/h3&gt;
&lt;p&gt;Go 语言规范规定，如果一个字段的声明中只有字段的类型名而没有字段的名称，那么它就是一个嵌入字段，也可以被称为匿名字段。我们可以通过此类型变量的名称后跟“.”，再后跟嵌入字段类型的方式引用到该字段。也就是说，嵌入字段的类型既是类型也是名称。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Animal &lt;span class=&quot;token keyword&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    scientificName &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 学名。&lt;/span&gt;
    AnimalCategory    &lt;span class=&quot;token comment&quot;&gt;// 动物基本分类。&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a Animal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Sprintf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;%s (category: %s)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scientificName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AnimalCategory&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;当匿名字段是一个struct的时候，那么这个struct所拥有的全部字段都被隐式地引入了当前定义的这个struct。（有点继承的意思，应该更类似于Mixin）&lt;/p&gt;
&lt;p&gt;如果被嵌入的类型中有和嵌入者重名的方法，则被嵌入这的方法会覆盖掉嵌入者的方法。（这个可以理解为重载）&lt;/p&gt;
&lt;h3 id=&quot;嵌入字段与继承区别&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%B5%8C%E5%85%A5%E5%AD%97%E6%AE%B5%E4%B8%8E%E7%BB%A7%E6%89%BF%E5%8C%BA%E5%88%AB&quot; aria-label=&quot;嵌入字段与继承区别 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;嵌入字段与继承区别&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://golang.org/doc/faq#inheritance&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Why is there no type inheritance?&lt;/a&gt;&lt;br&gt;
简单来说，面向对象编程中的继承，其实是通过牺牲一定的代码简洁性来换取可扩展性，而且这种可扩展性是通过侵入的方式来实现的。而Go语言类型之间的组合采用的是非声明的方式，我们不需要显式地声明某个类型实现了某个接口，或者一个类型继承了另一个类型。同时，类型组合也是非侵入式的，它不会破坏类型的封装或加重类型之间的耦合。&lt;/p&gt;
&lt;h3 id=&quot;接收者类型&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%8E%A5%E6%94%B6%E8%80%85%E7%B1%BB%E5%9E%8B&quot; aria-label=&quot;接收者类型 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;接收者类型&lt;/h3&gt;
&lt;p&gt;类型的接收者类型：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;func (cat *Cat) SetName(name string)&lt;/code&gt; 指针类型&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;func (cat Cat) SetName(name string)&lt;/code&gt; 值类型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;值方法里获得到的是一个值拷贝，修改不会反应到原值&lt;/li&gt;
&lt;li&gt;一个自定义数据类型的方法集合中仅会包含它的所有值方法，而该类型的指针类型的方法集合却囊括了前者的所有方法，包括所有值方法和所有指针方法。但是，Go 语言会适时地为我们进行自动地转译，使得我们在这样的值上也能调用到它的指针方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;struct类型值&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#struct%E7%B1%BB%E5%9E%8B%E5%80%BC&quot; aria-label=&quot;struct类型值 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;struct{}类型值&lt;/h3&gt;
&lt;p&gt;struct{}类型值的表示法只有一个，即：struct{}{}。并且，它占用的内存空间是0字节。确切地说，这个值在整个 Go 程序中永远都只会存在一份。虽然我们可以无数次地使用这个值字面量，但是用到的却都是同一个值。&lt;/p&gt;
&lt;h2 id=&quot;27-接口-interface&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#27-%E6%8E%A5%E5%8F%A3-interface&quot; aria-label=&quot;27 接口 interface permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.7 接口 interface&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;动态值：赋予的值可以被叫做它的实际值（也称动态值）&lt;/li&gt;
&lt;li&gt;动态类型：赋予值的类型可以被叫做这个变量的实际类型（也称动态类型）&lt;/li&gt;
&lt;li&gt;静态类型：接口的定义类型&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接口类型间的嵌入也被称为接口的组合。只要组合的接口之间有同名的方法就会产生冲突，从而无法通过编译。接口的组合根本不可能导致“屏蔽”现象的出现。&lt;/p&gt;
&lt;p&gt;接口值可以看做包含值和具体类型的元组：&lt;br&gt;
&lt;code class=&quot;language-text&quot;&gt;(value, type)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;接口值保存了一个具体底层类型的具体值：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; I &lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;M&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; F &lt;span class=&quot;token builtin&quot;&gt;float64&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f F&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;M&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i I&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;(%v, %T)\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i I &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;F&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Pi&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;describe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// (3.141592653589793, main.F)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;28-指针-pointer&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#28-%E6%8C%87%E9%92%88-pointer&quot; aria-label=&quot;28 指针 pointer permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.8 指针 pointer&lt;/h2&gt;
&lt;h3 id=&quot;操作符&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%93%8D%E4%BD%9C%E7%AC%A6&quot; aria-label=&quot;操作符 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;操作符&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;表示的是取值操作，传过来的是一个指针，通过在前面附带&lt;code class=&quot;language-text&quot;&gt;*&lt;/code&gt;，就获得了这个指针所指向的值。&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;amp;&lt;/code&gt;表示的是寻址操作，传过来的是一个值，通过在前面附带&lt;code class=&quot;language-text&quot;&gt;&amp;amp;&lt;/code&gt;，就获得了指向这个值的指针。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;可否寻址&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E5%8F%AF%E5%90%A6%E5%AF%BB%E5%9D%80&quot; aria-label=&quot;可否寻址 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;可否寻址&lt;/h3&gt;
&lt;p&gt;下列表中的值都是不可寻址的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;常量的值。&lt;/li&gt;
&lt;li&gt;基本类型值的字面量。&lt;/li&gt;
&lt;li&gt;算术操作的结果值。&lt;/li&gt;
&lt;li&gt;对各种字面量的索引表达式和切片表达式的结果值。不过有一个例外，对切片字面量的索引结果值却是可寻址的。&lt;/li&gt;
&lt;li&gt;对字符串变量的索引表达式和切片表达式的结果值。&lt;/li&gt;
&lt;li&gt;对字典变量的索引表达式的结果值。&lt;/li&gt;
&lt;li&gt;函数字面量和方法字面量，以及对它们的调用表达式的结果值。&lt;/li&gt;
&lt;li&gt;结构体字面量的字段值，也就是对结构体字面量的选择表达式的结果值。&lt;/li&gt;
&lt;li&gt;类型转换表达式的结果值。&lt;/li&gt;
&lt;li&gt;类型断言表达式的结果值。&lt;/li&gt;
&lt;li&gt;接收表达式的结果值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;共性：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;不可变的&lt;/code&gt;值不可寻址。常量、基本类型的值字面量、字符串变量的值、函数以及方法的字面量都是如此。其实这样规定也有安全性方面的考虑。&lt;/li&gt;
&lt;li&gt;绝大多数被视为&lt;code class=&quot;language-text&quot;&gt;临时结果&lt;/code&gt;的值都是不可寻址的。算术操作的结果值属于临时结果，针对值字面量的表达式结果值也属于临时结果。但有一个例外，对切片字面量的索引结果值虽然也属于临时结果，但却是可寻址的。&lt;/li&gt;
&lt;li&gt;若拿到某值的指针可能会破坏程序的一致性，那么就是&lt;code class=&quot;language-text&quot;&gt;不安全的&lt;/code&gt;，该值就不可寻址。由于字典的内部机制，对字典的索引结果值的取址操作都是不安全的。另外，获取由字面量或标识符代表的函数或方法的地址显然也是不安全的。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;打印指针方法&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E6%89%93%E5%8D%B0%E6%8C%87%E9%92%88%E6%96%B9%E6%B3%95&quot; aria-label=&quot;打印指针方法 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;打印指针方法&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;a &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;%p\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;29-go程-goroutine&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#29-go%E7%A8%8B-goroutine&quot; aria-label=&quot;29 go程 goroutine permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.9 Go程 goroutine&lt;/h2&gt;
&lt;p&gt;在sync/atomic包中声明了很多用于原子操作的函数。可以用在协程竞争的时候的线程安全。&lt;/p&gt;
&lt;p&gt;e.g&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;atomic&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;AddUint32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;210-错误-error&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#210-%E9%94%99%E8%AF%AF-error&quot; aria-label=&quot;210 错误 error permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2.10 错误 error&lt;/h2&gt;
&lt;h3 id=&quot;错误判断&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#%E9%94%99%E8%AF%AF%E5%88%A4%E6%96%AD&quot; aria-label=&quot;错误判断 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;错误判断&lt;/h3&gt;
&lt;p&gt;对于具体错误的判断，Go 语言中都有哪些惯用法？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对于类型在已知范围内的一系列错误值，一般使用类型断言表达式或类型switch语句来判断；&lt;/li&gt;
&lt;li&gt;对于已有相应变量且类型相同的一系列错误值，一般直接使用判等操作来判断；&lt;/li&gt;
&lt;li&gt;对于没有相应变量且类型未知的一系列错误值，只能使用其错误信息的字符串表示形式来做判断。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;panic&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#panic&quot; aria-label=&quot;panic permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;panic&lt;/h3&gt;
&lt;p&gt;从 panic 被引发到程序终止运行的大致过程：建立panic，并从运行的代码开始按调用栈逐层返回，最终返回运行时系统，打印信息，程序崩溃。&lt;/p&gt;
&lt;p&gt;error返回可以被忽略，因此一般应用在”不致命”的场景。内建函数panic可用于引发 panic，一般用在”致命”错误的场景。&lt;/p&gt;
&lt;h3 id=&quot;defer&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#defer&quot; aria-label=&quot;defer permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;defer&lt;/h3&gt;
&lt;p&gt;defer是先进后出（FILO）的，相当于一个栈，需要注意：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;first defer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;defer in for [%d]\n&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;defer&lt;/span&gt; fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;last defer&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// last defer&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// defer in for [2]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// defer in for [1]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// defer in for [0]&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// first defer&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;3-工具使用&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%B7%A5%E5%85%B7%E4%BD%BF%E7%94%A8&quot; aria-label=&quot;3 工具使用 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 工具使用&lt;/h1&gt;
&lt;p&gt;Go语言官方附带了不少很好用的命令行工具，除了以go命令为开头的&lt;code class=&quot;language-text&quot;&gt;go xxx&lt;/code&gt;的命令之外，还有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;cgo: Cgo enables the creation of Go packages that call C code.&lt;/li&gt;
&lt;li&gt;cover: Cover is a program for creating and analyzing the coverage profiles generated by “go test -coverprofile”.&lt;/li&gt;
&lt;li&gt;fix: Fix finds Go programs that use old features of the language and libraries and rewrites them to use newer ones.&lt;/li&gt;
&lt;li&gt;fmt: Fmt formats Go packages, it is also available as an independent gofmt command with more general options.&lt;/li&gt;
&lt;li&gt;godoc: Godoc extracts and generates documentation for Go packages.&lt;/li&gt;
&lt;li&gt;vet: Vet examines Go source code and reports suspicious constructs, such as Printf calls whose arguments do not align with the format string.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go命令行工具官方文档入口：&lt;a href=&quot;https://golang.org/doc/cmd&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Command Documentation&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;此外，这里还引用了不少&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;hyper0x/go_command_tutorial&lt;/a&gt;这个文档库的内容，有兴趣的可以直接读一读。不过这库里的解释和范例都是以Go语言1.4-1.5版本为基准的，算是特别老旧了，只能说参考下。主要还是要看英语的官方手册。&lt;/p&gt;
&lt;p&gt;下文并不会穷举官方手册中所有的Go命令行工具，仅列举部分常用的。&lt;/p&gt;
&lt;h2 id=&quot;31-go-build&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#31-go-build&quot; aria-label=&quot;31 go build permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.1 go build&lt;/h2&gt;
&lt;p&gt;功能：编译指定的源码文件或代码包以及它们的依赖包&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Compile packages and dependencies&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.1.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go build&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;32-go-install&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#32-go-install&quot; aria-label=&quot;32 go install permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.2 go install&lt;/h2&gt;
&lt;p&gt;功能：编译并安装指定的代码包及它们的依赖包&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Compile_and_install_packages_and_dependencies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Compile and install packages and dependencies&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.2.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go install&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;33-go-get&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#33-go-get&quot; aria-label=&quot;33 go get permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.3 go get&lt;/h2&gt;
&lt;p&gt;功能：从互联网上下载或更新指定的代码包及其依赖包&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Download_and_install_packages_and_dependencies&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Download and install packages and dependencies&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.3.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go get&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;34-go-clean&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#34-go-clean&quot; aria-label=&quot;34 go clean permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.4 go clean&lt;/h2&gt;
&lt;p&gt;功能：删除掉执行其它命令时产生的一些文件和目录&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Remove_object_files_and_cached_files&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Remove object files and cached files&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.4.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go clean&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;35-go-doc--godoc&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#35-go-doc--godoc&quot; aria-label=&quot;35 go doc  godoc permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.5 go doc &amp;#x26; godoc&lt;/h2&gt;
&lt;p&gt;功能：展示指定代码包的文档&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Show_documentation_for_package_or_symbol&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Show documentation for package or symbol&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.5.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go doc与godoc&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;36-go-run&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#36-go-run&quot; aria-label=&quot;36 go run permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.6 go run&lt;/h2&gt;
&lt;p&gt;功能：运行命令源码文件&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Compile_and_run_Go_program&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Compile and run Go program&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.6.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go run&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;37-go-test&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#37-go-test&quot; aria-label=&quot;37 go test permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.7 go test&lt;/h2&gt;
&lt;p&gt;功能：对Go语言编写的程序进行测试&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Test_packages&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Test packages&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;&quot;&gt;go test&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;38-go-list&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#38-go-list&quot; aria-label=&quot;38 go list permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.8 go list&lt;/h2&gt;
&lt;p&gt;功能：列出指定的代码包的信息&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-List_packages_or_modules&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;List packages or modules&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.8.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go list&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;39-go-fmt--gofmt&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#39-go-fmt--gofmt&quot; aria-label=&quot;39 go fmt  gofmt permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.9 go fmt &amp;#x26; gofmt&lt;/h2&gt;
&lt;p&gt;功能：按Go语言代码规范格式化指定代码包中的所有Go语言源码文件&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Gofmt__reformat__package_sources&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Gofmt (reformat) package sources&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;&quot;&gt;go fmt与gofmt&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;310-go-fix--go-tool-fix&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#310-go-fix--go-tool-fix&quot; aria-label=&quot;310 go fix  go tool fix permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.10 go fix &amp;#x26; go tool fix&lt;/h2&gt;
&lt;p&gt;功能：把指定代码包的所有Go语言源码文件中的旧版本代码修正为新版本的代码&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Update_packages_to_use_new_APIs&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Update packages to use new APIs&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.10.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go fix与go tool fix&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;311-go-vet--go-tool-vet&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#311-go-vet--go-tool-vet&quot; aria-label=&quot;311 go vet  go tool vet permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.11 go vet &amp;#x26; go tool vet&lt;/h2&gt;
&lt;p&gt;功能：检查Go语言源码中静态错误&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Report_likely_mistakes_in_packages&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Report likely mistakes in packages&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.11.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go vet与go tool vet&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;312-go-tool-pprof&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#312-go-tool-pprof&quot; aria-label=&quot;312 go tool pprof permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.12 go tool pprof&lt;/h2&gt;
&lt;p&gt;功能：分析go应用程序，给出profile文件&lt;br&gt;
手册：这个工具没有官方文档，讨论相关可以见：&lt;a href=&quot;https://www.reddit.com/r/golang/comments/8neprv/theres_no_pprof_documentation/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;There’s *no* pprof documentation?&lt;/a&gt;，官方倒是有个pprof包的文档&lt;a href=&quot;https://golang.org/pkg/net/http/pprof/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Package pprof&lt;/a&gt;&lt;br&gt;
google手册：&lt;a href=&quot;https://github.com/google/pprof/tree/master/doc&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;google/pprof&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.12.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go tool pprof&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果有订阅&lt;code class=&quot;language-text&quot;&gt;Go语言核心36讲&lt;/code&gt;的话：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://time.geekbang.org/column/article/69812&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;48 | 程序性能分析基础（上）&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://time.geekbang.org/column/article/70805&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;49 | 程序性能分析基础（下）&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;313-go-tool-cgo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#313-go-tool-cgo&quot; aria-label=&quot;313 go tool cgo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.13 go tool cgo&lt;/h2&gt;
&lt;p&gt;功能：创建能够调用C语言代码的Go语言源码文件&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Calling_between_Go_and_C&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Calling between Go and C&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.13.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go tool cgo&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&quot;314-go-env&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#314-go-env&quot; aria-label=&quot;314 go env permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3.14 go env&lt;/h2&gt;
&lt;p&gt;功能：打印Go语言的环境信息&lt;br&gt;
手册：&lt;a href=&quot;https://golang.org/cmd/go/#hdr-Print_Go_environment_information&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Print Go environment information&lt;/a&gt;&lt;br&gt;
中文：&lt;a href=&quot;https://github.com/hyper0x/go_command_tutorial/blob/master/0.14.md&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;go env&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;4-进阶概念&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E8%BF%9B%E9%98%B6%E6%A6%82%E5%BF%B5&quot; aria-label=&quot;4 进阶概念 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 进阶概念&lt;/h1&gt;
&lt;h2 id=&quot;41-函数内联&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#41-%E5%87%BD%E6%95%B0%E5%86%85%E8%81%94&quot; aria-label=&quot;41 函数内联 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4.1 函数内联&lt;/h2&gt;
&lt;p&gt;比较细节的解释可以参考：&lt;a href=&quot;https://zhuanlan.zhihu.com/p/28347225&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;剖析使Go语言高效的5个特性(2/5): 函数调用不是免费的&lt;/a&gt;。此外，可以看下官方的wiki：&lt;a href=&quot;https://github.com/golang/go/wiki/CompilerOptimizations#function-inlining&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Function Inlining&lt;/a&gt;来了解官方对于内联的要求。&lt;/p&gt;
&lt;h1 id=&quot;5-杂项&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E6%9D%82%E9%A1%B9&quot; aria-label=&quot;5 杂项 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 杂项&lt;/h1&gt;
&lt;h2 id=&quot;map值的取址&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#map%E5%80%BC%E7%9A%84%E5%8F%96%E5%9D%80&quot; aria-label=&quot;map值的取址 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Map值的取址&lt;/h2&gt;
&lt;p&gt;Map的值是不可以取址的，见：&lt;a href=&quot;https://github.com/golang/go/issues/11865#issuecomment-124801193&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;spec: can take the address of map[x] #11865&lt;/a&gt;。如果有这样的需求，必须将其赋值给某个变量，然后对某个变量进行取址。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;go&quot;&gt;&lt;pre class=&quot;language-go&quot;&gt;&lt;code class=&quot;language-go&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// compiling error&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Address: %p&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;m&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// do this, but it&apos;s a little bit meaning less&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;key&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
fmt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Printf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Address: %p&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Golang Notes]]></title><link>https://xenojoshua.com/posts/2019/02/golang-note</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/02/golang-note</guid><pubDate>Mon, 25 Feb 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot;&gt;1. 前言&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E5%9F%BA%E7%A1%80&quot;&gt;2. 基础&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E7%89%88%E6%9C%AC%E5%8E%86%E5%8F%B2&quot;&gt;3. 版本历史&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E6%A8%A1%E5%9D%97&quot;&gt;4. 模块&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#5-%E5%86%85%E5%AD%98&quot;&gt;5. 内存&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#6-cpu&quot;&gt;6. CPU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#7-go%E7%A8%8B&quot;&gt;7. Go程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#8-debug&quot;&gt;8. Debug&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#9-%E7%9B%91%E6%8E%A7&quot;&gt;9. 监控&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#10-advanced&quot;&gt;10. Advanced&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#11-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98&quot;&gt;11. 常见问题&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#12-%E5%B7%A5%E5%85%B7&quot;&gt;12. 工具&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-前言&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%89%8D%E8%A8%80&quot; aria-label=&quot;1 前言 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 前言&lt;/h1&gt;
&lt;p&gt;Go语言系列专题汇总文章。基本上会将Go语言的方方面面都梳理一遍。&lt;/p&gt;
&lt;p&gt;版本申明，所有原创的代码及实验都是基于以下版本：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;$ go version
go version go1.12 darwin/amd64&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h1 id=&quot;2-基础&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E5%9F%BA%E7%A1%80&quot; aria-label=&quot;2 基础 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 基础&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;/2019/03/golang-basic/&quot;&gt;Golang Basic&lt;/a&gt;介绍了Go语言的语法基础及特点。并列出了Go语言的官方命令行工具以及如何使用。基本上熟悉Go语言的读者可以直接忽略这块。&lt;/p&gt;
&lt;p&gt;官方有个常见问题列表，这里放一下，有需求可以检索下：&lt;a href=&quot;https://golang.org/doc/faq&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Frequently Asked Questions (FAQ)&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;3-版本历史&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E7%89%88%E6%9C%AC%E5%8E%86%E5%8F%B2&quot; aria-label=&quot;3 版本历史 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 版本历史&lt;/h1&gt;
&lt;p&gt;一门技术，其历史版本更新的跟进是非常重要的，这对于了解功能演进以及了解变化都是非常有意义的。NodeJs我一直有跟进：&lt;a href=&quot;/2018/03/v8-blog-translation/&quot;&gt;V8博客摘要翻译&lt;/a&gt;。而Go语言于我来说是比较新的东西，历史的更新必然是没有跟进的。这里推荐&lt;a href=&quot;https://tonybai.com/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Tony Bai&lt;/a&gt;大神的Go博客，对我来说感觉算是Go语言类似布道者的角色了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2019/03/02/some-changes-in-go-1-12/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.12中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2018/11/19/some-changes-in-go-1-11/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.11中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2018/02/17/some-changes-in-go-1-10/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.10中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2017/07/14/some-changes-in-go-1-9/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.9中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2017/02/03/some-changes-in-go-1-8/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.8中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2016/06/21/some-changes-in-go-1-7/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.7中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2016/02/21/some-changes-in-go-1-6/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.6中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tonybai.com/2015/07/10/some-changes-in-go-1-5/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go 1.5中值得关注的几个变化&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;4-模块&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E6%A8%A1%E5%9D%97&quot; aria-label=&quot;4 模块 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 模块&lt;/h1&gt;
&lt;p&gt;深入1.11版本终于实装的官方Go语言模块系统：go modules（vgo），详见：&lt;a href=&quot;/2019/03/golang-modules/&quot;&gt;Golang Modules&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;5-内存&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#5-%E5%86%85%E5%AD%98&quot; aria-label=&quot;5 内存 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;5. 内存&lt;/h1&gt;
&lt;p&gt;从Go内存的分配，到内存回收，到Profiling工具，全方面的Go内存知识点分析，详见：&lt;a href=&quot;/2019/03/golang-memory/&quot;&gt;Golang Memory&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;6-cpu&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#6-cpu&quot; aria-label=&quot;6 cpu permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;6. CPU&lt;/h1&gt;
&lt;p&gt;CPU部分相对来说比较简单，其关键知识点和Gorountine结合比较紧密，会在后面的篇章一起说明。此外，Profiling相关的知识点可以直接看Memory部分的内容，工具应该说是一致的，只是API及命令有部分不同。细节详见：&lt;a href=&quot;/2019/03/golang-cpu/&quot;&gt;Golang CPU&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;7-go程&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#7-go%E7%A8%8B&quot; aria-label=&quot;7 go程 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;7. Go程&lt;/h1&gt;
&lt;p&gt;Go应用程序最为重要的设计，也是Go得以从那么多编程语言中脱颖而出的核心。详见：&lt;a href=&quot;/2019/03/golang-goroutine/&quot;&gt;Golang Goroutine&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;8-debug&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#8-debug&quot; aria-label=&quot;8 debug permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;8. Debug&lt;/h1&gt;
&lt;p&gt;Go程序Debug有点类似于C语言，拥有一款和GDB相似的工具Delve。详见：&lt;a href=&quot;/2019/03/golang-debug/&quot;&gt;Golang Debug&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;9-监控&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#9-%E7%9B%91%E6%8E%A7&quot; aria-label=&quot;9 监控 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;9. 监控&lt;/h1&gt;
&lt;p&gt;Go进程的基础监控可以使用：&lt;a href=&quot;https://github.com/prometheus/client_golang&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;prometheus/client_golang&lt;/a&gt;。此外，可以使用该库拓展其功能，添加应用级别的自定义metrics，可以说是相当通用。&lt;/p&gt;
&lt;p&gt;出乎意料的是，Grafana Dashboard竟然没有找到比较通用可靠的Go进程基本监控面板。一个热度如此之高的编程语言，其基本监控面板居然在Grafana Labs中缺失，简直不可想象。&lt;/p&gt;
&lt;h1 id=&quot;10-advanced&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#10-advanced&quot; aria-label=&quot;10 advanced permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;10. Advanced&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;通道管线：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/2019/05/golang-pipeline/&quot;&gt;Golang Pipeline&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;单例模式：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/golang-issue/how-singleton-pattern-works-with-golang-2fdd61cd5a7f&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How singleton pattern works with Golang&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;数组切片：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/slices&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Arrays, slices (and strings): The mechanics of ‘append’&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;错误处理：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/error-handling-and-go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Error handling and Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/defer-panic-and-recover&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Defer, Panic, and Recover&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/go1.13-errors&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Working with Errors in Go 1.13&lt;/a&gt;：1.13版本的最新错误处理相关改动&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;类型转换：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.csdn.net/erlib/article/details/24197069&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go语言 类型断言性能测试&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;泛型：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.golang.org/why-generics&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Why Generics?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;这只是一个设想，后面到底会如何实装还要看后续发展&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;并发：
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/2020/05/golang-concurrency/&quot;&gt;Golang Concurrency&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;11-常见问题&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#11-%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98&quot; aria-label=&quot;11 常见问题 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;11. 常见问题&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stackoverflow.com/questions/32815400/how-to-perform-division-in-go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;How to perform division in Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;12-工具&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#12-%E5%B7%A5%E5%85%B7&quot; aria-label=&quot;12 工具 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;12. 工具&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;ORM：&lt;a href=&quot;https://github.com/jinzhu/gorm&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;jinzhu/gorm&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/go-sql-driver/mysql#dsn-data-source-name&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Go-MySQL-Driver &gt; DSN (Data Source Name)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jinzhu/gorm/issues/1053#issuecomment-265344516&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Question on pooling/concurrency regarding recent documentation change, suggest clarification #1053&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jinzhu/gorm/issues/1427#issuecomment-332498453&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;[Question] Do you need to close the db connection every request? #1427&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/go-sql-driver/mysql/issues/461#issuecomment-227008369&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Best practice #461&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.jianshu.com/p/ed13eb3caa4e&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用Go，Gin和Gorm开发简单的CRUD API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Logger：&lt;a href=&quot;https://github.com/uber-go/zap&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;uber-go/zap&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gin-contrib/zap&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;gin-contrib/zap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/wantedly/gorm-zap&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;wantedly/gorm-zap&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://studygolang.com/articles/19388&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;使用zap配置结构体创建记录器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/uber-go/zap/blob/v1.10.0/config.go#L53&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;zap.Config&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/uber-go/zap/blob/v1.10.0/zapcore/encoder.go#L222&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;zapcore.EncoderConfig&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/uber-go/zap/blob/v1.10.0/example_test.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;zap/example_test.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sandipb/zap-examples/blob/master/src/simple1/main.go&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;zap-examples/src/simple1/main.go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hnakamur/go-log-benchmarks&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;hnakamur/go-log-benchmarks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/imkira/go-loggers-bench&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;imkira/go-loggers-bench&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cache：&lt;a href=&quot;https://github.com/bradfitz/gomemcache&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;bradfitz/gomemcache&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/memcached/memcached/wiki#memcached&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Memcached Wiki&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[EventLoop中的事件分类]]></title><link>https://xenojoshua.com/posts/2019/02/event-loop-spec</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/02/event-loop-spec</guid><pubDate>Fri, 22 Feb 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-macrotask-%E4%B8%8E-microtask&quot;&gt;1. macrotask 与 microtask&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E4%B8%A4%E8%80%85%E7%9A%84%E5%8C%BA%E5%88%AB&quot;&gt;2. 两者的区别&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#3-%E5%AE%9E%E7%8E%B0%E7%9A%84%E5%88%86%E7%B1%BB&quot;&gt;3. 实现的分类&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8%E7%9A%84%E5%BD%B1%E5%93%8D&quot;&gt;4. 使用的影响&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-macrotask-与-microtask&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-macrotask-%E4%B8%8E-microtask&quot; aria-label=&quot;1 macrotask 与 microtask permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. macrotask 与 microtask&lt;/h1&gt;
&lt;p&gt;一直有面试题以及技术帖提到Node中的事件循环中，有一个被称为&lt;code class=&quot;language-text&quot;&gt;macrotask&lt;/code&gt;的东西（另一个是&lt;code class=&quot;language-text&quot;&gt;microtask&lt;/code&gt;）。一直都知道有task和microtask的区分，但不太清楚什么是macrotask。甚至在&lt;a href=&quot;https://html.spec.whatwg.org/multipage/webappapis.html#event-loops&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;spec&lt;/a&gt;以及&lt;a href=&quot;https://v8.dev/blog/fast-async#tasks-vs.-microtasks&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;谷歌V8官方的技术博客&lt;/a&gt;中也没有提到macrotask，最多无非就是task（见下图）。于是就想要稍微查下。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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mzbN9kPXRtJFkltTFi5caLOe9FxnByx9rpbOGkdz5sxp9dpCTvaVZ3362ik61cp9BzXneFOPTn3av/Hjxzd1CscQQAABBIJYgABPEA8OTUMAAQQQQAABBBwBXXzXybbRHat0EeSWiu7YdMstt8jXX3/tNWiguzY5wQWdprVy5UrJysqyVevaO03tdKVvzpgxw3X7V155xZXx4zro8UTXm7nqqqvsLlL+XsDXvc3OOjcezenwy5NPPtlVx1NPPWV3BXMdaOKJTmfTRa2dcvbZZztPpXv37nL00Ufb1zrlS3eyaqnoQs3z5s2zp2m2TXM7ebnf11u9H3zwgd2ZTN+fNGmSzTDydi7HEUAAAQSCU4AAT3COC61CAAEEEEAAAQQaCVx44YWuY/fee2+zmRnvvPOOvPnmm7Jo0SK7Ro6z65Orgvon3bp1k2OOOca+WrZsmbz00kv2uU5B0jV6vBXdklu3a9eiU3v++Mc/urJTPK/RIMutt94qW7ZssW366quvPE/x6Wv3hY81GOaPLJ7DDjvMtS25bhn/0EMPeQ1ylZaWyp133unaLevEE0+UIUOGNOjz5ZdfLomJifbYs88+a7eub3CC2wt11J3LdAc0LTfeeKNrupfbaa6nixcvlscff9yrg35GnnzySdf555xzjus5TxBAAAEEQkcg6i5TQqe5tBQBBBBAAAEEEIhcAd3GWn+51zV4NCNEM250i+2EhAS7yK4uqKsBDc3c0QCPFn3v4Ycf9roIr56jU7GcXbOc7bZ1h61jjz1W326y6DQenWbkrNej7fr0009tkEODRvql7dS1fXRRaGctmIMPPliuvfbaBnV+9913smbNGntMt2T3tp6Mc5H2raioSGJjY+X88893DrsedYFgbVdJSYldMFqzkrRfGsDSKVCHHHKI69zmnug12ictmtXiTMvS19p/7YtOa9L7aJBLp2Bp9pCa65boTv/V35kmNXz4cLn77rtda/hoXVrUS8dX66upqbHT3tRU+6h16f3USPv+6KOPunbgOu+88xoF4jSY9/rrr9t6NetLrfRazfrSuvReWp+6vPrqq/L000+7glMa1CPAY+n4hgACCIScALtohdyQ0WAEEEAAAQQQiGQBnXKlGSrvvvuuzcjQAIQThPB00cCNZtY4U7s833deaybOULMblgYUnHLaaac5T70+9uvXzwYbnOyU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5R4tf6suT53kdi11y7ImThpvLVriuZPMhnMIQKB2E1jSYLaN7/So1Wu20IYdemOlGluyciVtpcooxptjttQWNfralpX+YqedNowdtKpkkF3sDyfuLGk0yo489Ehr1WrlsvUqqYpCIQCB3wnoczfafe5GW4d27e3www+HTBURWFY604lonzvvxD62/fbbV1EtFFsZAgg8laGX5t7aIu6kaR7JRUpgydIlNtl57iDuFOkA0y0IFCmBmAv0O7PN+za1/YvWslkb++dh91uLJi0r1Vv9+IAlElhW7xdb3GSk1XP7IpxwzAkubkLPxAycVZrACver9qImn9uK0nm215572eDBgytdJgVAAAKpCcRKFtvyerNtWclMW+52Xlxh823XXXe1fffdF/E6NbLKpZYss4UNvralDcZbvz5r2sknn1S58ri7yggg8OQZLeJOnoFSXFYEli5xy7JcQOUWLRsRcycrYmSCQM0RWLR0gS1v+qM1XZgY36vmWlQTNa+wBU0m24LG42xBs7HOo2SB7bT+vnbW3kOtScOmeWiQi39Sb4Yrd0YeyirMIuTFtKL0N8dglq2oP8uWm9sIoe+adtJJJ1rr1q3z0qmlK36zBnWYsSDGShf+wbhknnXssKqdeto51r17Xf585+XxopA0BEpLVwafn9vs2TQ56l5yhw4d7ZRTzs27cL283kz3E8Tyugc09Lh0uSmmkbx2YvV/tXpu85jDDjrMdthhh5CD91pIAIEnj4OCuJNHmBSVNYElS5bYpMny3EHcyRoaGSFQgwT0n8Xfmo32rxpsRo1WXeq2QO/copdtstoA23qDk2yD1Te21s3zt46/UaNGFitZ6kSkD2q0nzVZeYlTeFq3am99+/ax9dbf1b33tVVXXTVvTQrBS+syY8Fs3qyl9V2jl/XfYJBn3K1bNwJX5+0po6BUBPr372/77bef2wm3ZjcySdW26kxr0qSJ3wVQOwG2b98+r5+78P22qOG31dmlWldXg/oNrWuXHrZ+/21szbX6Wa9evQhcXetGqWyDSlxgWByZy3LJOaW2iDs77NHPGjaubx+/Nc602xNW3AQk7kycPN5WQdwp7oGmdxCAAAQgAAEIQAACEIAABMohgMBTDqBsLtcWcSebtpKneAgsduLOZAVUboXnTvGMKj2BAAQgAAEIQAACEIAABCBQMQIrF3FW7F7ucgQQ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77337LXXXrOJEyf6Z61169a+nxtttJENGTLEVlllFVMco+HDh/uildapU6d4Nc8884z9+uuvnseBBx4YT091MHfuXHvqqaf8pR49etjWW2+dKptP0xg+8MAD/jOg505tbd++vW/bdttt58ct3RiIi/jIwmfKn6T4s2LFCnvwwQf9FX3Odt111xS5Vibp2dfzGD4Lep51T+fOnW3bbbf1yx6bNGmS9n4uQAACEChEAiUxZ4XYcNoMAQhAAAIQgAAEqpvArbfeak888YSv9qGHHvKigN7T2W677WYnnnii/fLLL3bBBRd4ASFVXk1+jzjiCNtnn33KXJb4oe24ZWeccYYXLJIz6b9z99xzjz388MPJlxLONaE9/fTT/QQ3ekECx2GHHeaTDjjgAC8WnHvuub7d0XwSeI466qhokheCrrjiCnv//fcT0pNPttxySzvnnHOsUaNGCZck0Jx66qkJaalOdthhBzvrrLPilxYsWGA33HCDF83iiSkOJKSccMIJJoErlUnE+Pe//23Lly9PddmnSSgaOnSotWjRIiHPcccdV+426RKtTj75ZC8a6WaJXUceeWRCOeWdSAxU8OkghKTK36ZNG7v44ou90HbzzTf7LBqXDTbYIJ796KOPtnHjxlnDhg3t+eefj6enOlBdeiZlEnf0/KYyPf8S4jLx025ol156qRd8kstQuR999JFPfuSRR7wIk5wnnKsOCW6y3r172y233BIuJbxL5Lzuuuts8eLFCenREwmfl1xyibH8MUqFYwhAoNAJZP45o9B7R/shAAEIQAACEIBAFRGQx0cQd/r162cSAeQJI8+T4Iny9NNPe+8PTYDl2SLr27evrbvuuvbbb7+ZxA1NpJctW2a33367vyYPmlztyiuv9J4d4b4OHTr4OuSxIG8htWn+/PlejLnssst8fdtvv33InvAu74uzzz7b5JUhkyeGhA0JA8k2c+ZML7oE4aGkpMTWXHNN760jjxd59cizSQKUvE8kdFx++eUmMaKypn58/PHHvhjVK28oeQupvRLUxFbeJDq+6KKL7F//+pcXBaL1yvNH6cHk+SOPKk3+5Tml9kskkHfQKaec4vPm4vWh5+C0006Lizt77rlnzuKOxkF1h/FQW/UMqZ316tXzfH/44QfvEXbeeefZzjvvHLpT5e8Sxv73v//5ejQGEpNWW2013y497198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AAIQgAAEIAABCEAAAhCAAAQgkEAAgScBBycQgAAEIAABCEAAAhCAAAQgAAEIQKDwCCDwFN6Y0WIIQAACEIAABCAAAQhAAAIQgAAEIJBAAIEnAQcnEIAABCAAAQhAAAIQgAAEIAABCECg8Agg8BTemNFiCEAAAhCAAAQgAAEIQAACEIAABCCQQACBJwEHJxCAAAQgAAEIQAACEIAABCAAAQhAoPAIIPAU3pjRYghAAAIQgAAEIAABCEAAAhCAAAQgkEAAgScBBycQgAAEIAABCEAAAhCAAAQgAAEIQKDwCCDwFN6Y0WIIQAACEIAABCAAAQhAAAIQgAAEIJBAAIEnAQcnEIAABCAAAQhAAAIQgAAEIAABCECg8Agg8BTemNFiCEAAAhCAAAQgAAEIQAACEIAABCCQQACBJwEHJxCAAAQgAAEIQAACEIAABCAAAQhAoPAIIPAU3pjRYghAAAIQgAAEIAABCEAAAhCAAAQgkEAAgScBBycQgAAEIAABCEAAAhCAAAQgAAEIQKDwCCDwFN6Y0WIIQAACEIAABCAAAQhAAAIQgAAEIJBAAIEnAQcnEIAABCAAAQhAAAIQgAAEIAABCECg8Agg8BTemNFiCEAAAhCAAAQgAAEIQAACEIAABCCQQACBJwEHJxCAAAQgAAEIQAACEIAABCAAAQhAoPAIIPAU3pjRYghAAAIQgAAEIAABCEAAAhCAAAQgkEAAgScBBycQgAAEIAABCEAAAhCAAAQgAAEIQKDwCCDwFN6Y0WIIQAACEIAABCAAAQhAAAIQgAAEIJBAAIEnAQcnEIAABCAAAQhAAAIQgAAEIAABCECg8Agg8BTemNFiCEAAAhCAAAQgAAEIQAACEIAABCCQQACBJwEHJxCAAAQgAAEIQAACEIAABCAAAQhAoPAIIPAU3pjRYghAAAIQgAAEIAABCEAAAhCAAAQgkEAAgScBBycQgAAEIAABCEAAAhCAAAQgAAEIQKDwCCDwFN6Y0WIIQAACEIAABCAAAQhAAAIQgAAEIJBAAIEnAQcnEIAABCAAAQhAAAIQgAAEIAABCECg8Agg8BTemNFiCEAAAhCAAAQgAAEIQAACEIAABCCQQACBJwEHJxCAAAQgAAEIQAACEIAABCAAAQhAoPAIIPAU3pjRYghAAAIQgAAEIAABCEAAAhCAAAQgkEAAgScBBycQgAAEIAABCEAAAhCAAAQgAAEIQKDwCCDwFN6Y0WIIQAACEIAABCAAAQhAAAIQgAAEIJBAAIEnAQcnEIAABCAAAQhAAAIQgAAEIAABCECg8Agg8BTemNFiCEAAAhCAAAQgAAEIQAACEIAABCCQQACBJwEHJxCAAAQgAAEIQAACEIAABCAAAQhAoPAI1C+8JtNiCEAAAjVP4JlnnrHHH388p4acdNJJNn/+fBs0aJAddthhds899+R0f3Vk3m677eyNN96wUaNGWe/evW3p0qX273//25YtW2bHH3+8NWrUKKEZS5YssXvvvdc+//xz37fS0lK77bbbfL4ZM2bY7bffbj/++KMvp3v37vZ///d/Cfdzkp7AW2+9VauflfQt58rUqVP952a99dazPffcs84DqavP8rBhw+yCCy7w3/X6zq+tVlfHp7aOB+2CAAQgUBkCCDyVoce9EIBAnSXw/fff2wMPPJBT/3fddVdr3769v2fBggU53VtdmRcvXuyrknAje/755+3kk0/2x126dLF99tnHH4c/Z555pt10003h1L9ff/31XuDZZptt7Ntvv41f22ijjRB44jTKP1ixYoXPVNXPyvTp0+2iiy4yjf1dd91VfsPIUS6BK6+80q677jqfb9KkSda5c+dy76muDE888YRdcskl9sgjj9iaa65ZLdVW17NcLZ3JoRIJ47LwvZrNrRLL9Xn8y1/+YkcddVQ2t1Q6T10dn0qDowAIQAACtZAAS7Rq4aDQJAhAoPYTkOihiVv09c033/iGt2jRIiE95Pnzn/9c+zuW1MLoBLBv374JVzV5kfeO7IUXXrBZs2b5V8uWLb2wI3GnT58+NmLECJ+uX4mx2kfghx9+sFtvvdV+++232te4Am3RBhts4FsuUbRt27a1qhf/+te/7Msvv7Tly5fXqnbRmJUEXnzxRXv22We91yRMIAABCEAAArkSwIMnV2LkhwAEIOAING7cuMyv8s2aNYuzqU2/2McbVYEDiTqzZ8+2WCxmrVu3TihBXkzz5s0zTWZ33nnnhGvvvfeeP997771twIABCdc4gUCxEzj44INt8ODB1q5dO2vYsGGxd5f+QQACEIAABCBQSwgg8NSSgaAZEIBA3SMgD5iXX37Z3n77bZsyZYr169fPNDFUrJpkU97nnnvOPvvsMxszZozP279/f9tll12sQYMGydnLPf/oo498vfolf+2117YhQ4aYllClMi3TksCjtun9vvvu89l+/vln/z5t2rS4J0+4X32SablB8PLp0aOHbbvttj5dfz744AN79913vTdBp06dTP3Zaaed/KQ4ZJKXgZbCySto9913t08++cT++9//eg+p/fbbz6cpb7Z8Jk+ebK+88or3LNpwww1Nv5arrRKxxH///fc3tTOVvf766/bxxx/bV1995cUueTcdeOCBKT00sm1PqnpSpYn7+++/b6+99pqPaSTRTPGS1l9//VTZfX/0vHz66af+WPk22WQT23LLLeP5v/jiCz8+Eupkeg9jpWdBnlfiv9tuu5UR95588kmbM2eO7bXXXiaPtag99thjPh5TdEmi+JbXnmgZ2eZXG/UMb7311r4delY1nhJg11lnHR/rKiq8RutIPo4+Gxpb9UNCZdeuXW2rrbbyn5F69eqZ4uuoHj27ei61FDE5zo7ar+dMHjzbb799clWWzbMU+qbPjOp5+umn/fPasWNHv9RRabJff/3Vsx05cqT/HllrrbX8Z3mHHXZIqDeM7cSJE326Yojp+ahfv77/bIfMWhL4v//9z4+/vA9Vn4TeAw44oMyzrudSMbteffVVGzt2rDVp0sR/tvbdd1/r1atXKDLju1ipbzI9d/o+kn333Xd+DH766SdbuHChL1csxTtX0zPy1FNP+TZq+ak8C7fYYosyY6Nx1ZJFtX/ChAmet75zVl11Vdt0001NgnVJSUmZ6hVnTN/lyiuPLbGPfteVuSFFgr6LfvnlFz8muvzmm2/651jHWq7Vpk0bHVptGR/FWHvwwQf9OM2cOdO6detmG2+8sWekZwqDAAQgAIEaIuD+ccYgAAEIQCAPBNxEK+a+ymNuwpu2NDex83ncxDh26KGH+mPdE325pUwJ97sJR8wJMAl5Qn43iYi5SUFC/kwnLtZCbOjQoSnLcks3Ym7S4699/fXX8WJCXUpwQZdT3hvyZHp3YogvU2WcddZZKcvp0KFDzE0643W7iZ3Pp3QXrDThniOPPNLny4VP4O88jmI77rhjQnmh7W6yGq9fBy4wduyII45ImVf3uIldQv5c2pNwY9JJaKubbJbpe2irC4CddFcs5oSBmBMWUrb31FNPjbkJrr/nsssuS5lHZd98883xZ8EFA0+owwk78fuc0JNwzYkk8Wvhucy2PaGgXPJffPHFvr7T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&quot;&gt;
&lt;p&gt;其实之前就有读过两篇文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ccforward/cc/issues/47&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;44.理解事件循环一(浅析)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ccforward/cc/issues/48&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;45.理解事件循环二(macrotask和microtask)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今天再仔细读了下，其实很简单：&lt;/p&gt;
&lt;p&gt;所谓的macrotask其实就是一直提到的&lt;code class=&quot;language-text&quot;&gt;事件循环task&lt;/code&gt;。&lt;/p&gt;
&lt;h1 id=&quot;2-两者的区别&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E4%B8%A4%E8%80%85%E7%9A%84%E5%8C%BA%E5%88%AB&quot; aria-label=&quot;2 两者的区别 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 两者的区别&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Node的事件循环有两个队列，macrotask和microtask是分开存放的&lt;/li&gt;
&lt;li&gt;事件循环触发的时候，每次只处理一个macrotask&lt;/li&gt;
&lt;li&gt;处理完目标macrotask之后（如果有的话），会将当前所有的microtask清空（全部处理完）&lt;/li&gt;
&lt;li&gt;上面V8博客的图也能说明这一点&lt;/li&gt;
&lt;li&gt;macrotask导致的新macrotask会在之后的事件循环中处理&lt;/li&gt;
&lt;li&gt;microtask导致的新microtask会在当前事件循环中处理&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;3-实现的分类&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#3-%E5%AE%9E%E7%8E%B0%E7%9A%84%E5%88%86%E7%B1%BB&quot; aria-label=&quot;3 实现的分类 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;3. 实现的分类&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;macrotask:
&lt;ul&gt;
&lt;li&gt;setTimeout&lt;/li&gt;
&lt;li&gt;setInterval&lt;/li&gt;
&lt;li&gt;setImmediate&lt;/li&gt;
&lt;li&gt;I/O&lt;/li&gt;
&lt;li&gt;UI渲染&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;microtask:
&lt;ul&gt;
&lt;li&gt;Promise&lt;/li&gt;
&lt;li&gt;process.nextTick&lt;/li&gt;
&lt;li&gt;Object.observe&lt;/li&gt;
&lt;li&gt;MutationObserver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&quot;4-使用的影响&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#4-%E4%BD%BF%E7%94%A8%E7%9A%84%E5%BD%B1%E5%93%8D&quot; aria-label=&quot;4 使用的影响 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;4. 使用的影响&lt;/h1&gt;
&lt;p&gt;因为microtask会在当前事件循环中全部处理清空完毕，因此其执行优先级是比macrotask高的。当某些业务逻辑可以放在&lt;code class=&quot;language-text&quot;&gt;Promise.resolve&lt;/code&gt;中，也可以放在&lt;code class=&quot;language-text&quot;&gt;setTimeout&lt;/code&gt;中的话，两者的先后关系就有点微妙了，需要理解上述的顺序关系才不会出错。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[V8 Blog | Trash talk: the Orinoco garbage collector 2019-01-03]]></title><link>https://xenojoshua.com/posts/2019/02/trash-talk</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/02/trash-talk</guid><pubDate>Wed, 20 Feb 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%8E%9F%E6%96%87&quot;&gt;1. 原文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%91%98%E8%A6%81%E7%BF%BB%E8%AF%91&quot;&gt;2. 摘要翻译&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#major-gc-full-mark-compact-id_mgc_fmc&quot;&gt;Major GC (Full Mark-Compact) {#ID_MGC_FMC}&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#marking&quot;&gt;Marking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sweeping&quot;&gt;Sweeping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#compaction&quot;&gt;Compaction&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#generational-layout&quot;&gt;Generational layout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#minor-gc-scavenger&quot;&gt;Minor GC (Scavenger)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#orinoco&quot;&gt;Orinoco&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#parallel&quot;&gt;Parallel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#incremental&quot;&gt;Incremental&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#concurrent&quot;&gt;Concurrent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#state-of-gc-in-v8&quot;&gt;State of GC in V8&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#scavenging&quot;&gt;Scavenging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#major-gc&quot;&gt;Major GC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#idle-time-gc&quot;&gt;Idle-time GC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#takeaways&quot;&gt;Takeaways&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-原文&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%8E%9F%E6%96%87&quot; aria-label=&quot;1 原文 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 原文&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://v8.dev/blog/trash-talk&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Trash talk: the Orinoco garbage collector&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;当前这篇技术博客的目的是针对过去几年的V8垃圾回收机制的改进做一个总结性回顾，整体来说偏理论、偏概念性，技术的深度并不是很足。因此如果想要详细深入了解V8的GC细节的读者，需要打开所有当前博文中链接的历史博文，一篇篇仔细过一下。或者可以阅读我之前整理的Node系列性能博文：&lt;a href=&quot;https://xenojoshua.com/2018/01/node-profile/&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Node.JS Profile&lt;/a&gt;。&lt;/p&gt;
&lt;h1 id=&quot;2-摘要翻译&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%91%98%E8%A6%81%E7%BF%BB%E8%AF%91&quot; aria-label=&quot;2 摘要翻译 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 摘要翻译&lt;/h1&gt;
&lt;p&gt;Over the past years the V8 garbage collector (GC) has changed a lot. The Orinoco project has taken a sequential, stop-the-world garbage collector and transformed it into a mostly parallel and concurrent collector with incremental fallback.&lt;/p&gt;
&lt;p&gt;在过去的几年里V8的垃圾回收器（GC）改变了很多。Orinoco项目将一个线性的、stop-the-world的垃圾回收器转变成了一个大部分情况下并行以及并发运作的垃圾回收器。&lt;/p&gt;
&lt;p&gt;Any garbage collector has a few essential tasks that it has to do periodically:&lt;/p&gt;
&lt;p&gt;任何垃圾回收器都有一些周期性必须要完成的任务：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Identify live/dead objects&lt;/li&gt;
&lt;li&gt;Recycle/reuse the memory occupied by dead objects&lt;/li&gt;
&lt;li&gt;Compact/defragment memory (optional)&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;识别存活/死亡的对象&lt;/li&gt;
&lt;li&gt;回收/重用死亡对象占用的内存空间&lt;/li&gt;
&lt;li&gt;压缩/回收内存空间（可选）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These tasks can be performed in sequence or can be arbitrarily interleaved. A straight-forward approach is to pause JavaScript execution and perform each of these tasks in sequence on the main thread. This can cause jank and latency issues on the main thread, which we’ve talked about in &lt;a href=&quot;https://v8.dev/blog/jank-busters&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;previous&lt;/a&gt; &lt;a href=&quot;https://v8.dev/blog/orinoco&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;blog posts&lt;/a&gt;, as well as reduced program throughput.&lt;/p&gt;
&lt;p&gt;这些任务可以被序列执行，也可以被强制交叉执行。最简单直白的方法就是在主线程上序列处理这些任务，并在运行的时候暂停JavaScript的执行。这会造成应用程序闪断，以及主线程的延迟问题，我们已经在&lt;a href=&quot;https://v8.dev/blog/jank-busters&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;之前&lt;/a&gt;的&lt;a href=&quot;https://v8.dev/blog/orinoco&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;博客&lt;/a&gt;中讨论过这些问题了，并且这也会降低应用程序的吞吐量（throughput）。&lt;/p&gt;
&lt;h2 id=&quot;major-gc-full-mark-compact-id_mgc_fmc&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#major-gc-full-mark-compact-id_mgc_fmc&quot; aria-label=&quot;major gc full mark compact id_mgc_fmc permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Major GC (Full Mark-Compact) {#ID_MGC_FMC}&lt;/h2&gt;
&lt;p&gt;The major GC collects garbage from the entire heap.&lt;/p&gt;
&lt;p&gt;Major GC负责从整个堆回收垃圾。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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dvsuAQlIQAISkECdEpjoiMzo+/fff1+nCOy2BCQgAQl0JgGc548++iisv/76rVbbs2fP6BhXEgJaPbmdBZ577rnw7rvvhrXXXjtMMskk7Ty79op/+umn4fjjj49iBwIBY4Hwct9990Uh5YMPPojiy8QTj/5t6J577gmnn356/Hth5plnjqIPAtrDDz8chYm+fftGSP/5z3/CZZddFr7++usonvBOXQhFiy++eEjlGhsbwwUXXBCuuOKKKMDNMssssRzRXggaCCcLL7xw4FpFQ6j629/+FgUa6kWwGjFiRHj77bcDCae/++67MGTIkHDeeedF8Yhxpwz9W2mllaIIRZ2INCeeeGKcUjjttNPG61Lm3nvvjfXNP//88dKIKDfccEOAxYUXXhj30SfayHRERK+TTz453l/8PcW1/ve//0WBC1EMo7//+Mc/4nRH7r/ll18+tg2h6v77748iURJ96AcCJWIZLGHG+TBCGIPxCiusMI54hTB09913R9EO8UyTgAQkIAEJSKC+CRjhU9/jb+8lIAEJtJnAl19+GW677bYY6YBYMOOMM0ZHl+icXr16jVVPitDAmX3llVeiAET0CE4qkSHJcLiJdiASYvbZZ0+74ztObxKPpptuuhgBseCCC45zLeq45ZZb4jVoBw42jvNCCy0UI1Vw/HHKcfqx//73v1HwyV8zRaQQ7YFTTYRHcvbjSTX2D/1EvCF6hN99pp566thDonAQJeCRN8YQYWbbbbeNQkU6RnLns88+O1x66aVhv/32i7unmmqqsOiii4addtqpSVhD/PjXv/4V69h7771jOSJ0GJdNN900Rt6kOonI+fvf/542W3x//fXX4z24//77R3GEyCMEHMQpopT22muvOI708+qrrw533XVX7BuROtg555wThg8fHo466qgYpcM+2Jx11lnhjjvuiAJVEmE4dvvtt4c999wzLLDAApHd5ZdfHgWyI488Ml5n5513jqIQ0T+nnnpqnKq49NJLc2qsj+gehJ5tttmmSXQijxXi1VVXXRWjkOaee+5Ynn/ox5ZbbhkjgBB8aCvH4XbnnXeGzTffvKksghdiFW2bZpppmvbXygfGAwZrrrlmFPUQcHkO8T1FxGW8Gf+nnnoqCofTTz99WGONNZrGNXGgDgQ5hEEi1n7+85/HKKv0vKAcQh73IUIe4hzfB6LVeL5svPHG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gAQkIAEJSEACEqgbAgo+dTPUdlQCEpCABCQgAQlIQAISkIAEJCCBeiGg4FMvI20/JSABCUhAAhKQgAQkIAEJSEACEqgbAgo+dTPUdlQCEpCABCQgAQlIQAISkIAEJCCBeiGg4FMvI20/JSABCUhAAhKQgAQkIAEJSEACEqgbAgo+dTPUdlQCEpCABCQgAQlIQAISkIAEJCCBeiGg4FOjI/3jjz+G999/v0Z7Z7ckIAEJSEACEpCABCQgAQlIQAISaInAxC0d9FjnELjpppsCL+zggw8Os8wyS4sVX3/99eHWW2+NZQ499NAw00wztVi+0sHjjjsufPDBB+GQQw4JAwYMqFSkXfvOOuus8PTTT7d6zk477RSWXnrp8Ne//jW88sor4bTTTguTTjppq+dVa4GLL744PPDAA5HjzDPPXK3NtF0SkIAEJCABCUhAAhKQgAQkIIGxCCj4jIWj6zcefPDBFgWfxsbG8NBDD3WoISNHjgyff/55GDVqVPj44487RfCZccYZwzfffNPULur98ssvw8CBA8Mkk0zStH+KKaZo+uwHCUhAAhKQgAQkIAEJSEACEpCABCYMAQWfbuSOMPLII4+ELbbYIvTs2bPilV944YUopFD2+++/r1imtZ0TTTRRjCQaNmxYmHXWWVsr3qbjG2ywwVjlLrjggvDwww+H7bbbLiAGaRKQgAQkIAEJSEACEpCABCQgAQlUDwFz+HTjWCy55JJRxHniiSeaver9998fGhoawhJLLNFsmbYcmGaaaTpN7GnL9SwjAQlIQAISkIAEJCABCUhAAhKQQPUQMMKnG8discUWC4899lhgWteyyy47zpW//vrr8Nxzz4VFFlkk9O7de5zj7HjrrbfC7bffHvPjDB8+POb3IWJo7rnnHqv8NddcEwYNGhR+//vfxylXTz31VLj77rvDuuuuG/r27RsuvPDC8N5774XJJ588TvnabLPNxitX0FgXrbCBeHXttdeGu+66K5BIuk+fPmGdddYJa621VlPpH374IZx66qlh/vnnD4svvng455xzYtt69eoVTj755KYpY+QEuueeeyID6pptttnCqquuGhZYYIGmutKHzz77LNx2223h+eefD3zu169fWHvttcPqq6+eijS9M43u0UcfjRFLb7/9dphqqqli3WussUbo0UNNtAmUHyQgAQlIQAISkIAEJNACgX333Tcsv/zyYZVVVgn8AK1JQAITloCCTzfyR/wgyoepUIgQU0899VhXRwhCfFh55ZVDpSigO++8M1x99dVRDEqJmD/88MOYIHmTTTYZS0RBzHnttdcC+XywoUOHxm2meN17771RcJp33nnDSy+9FF5++eVw7LHHhgMPPLDF/EJjNbYNG0wtu+666+L15phjjhi5NHjw4CgAIVZtvPHGsRZyDdFWxKf77rsvjBgxIgou77zzTuRBoZtvvjnceOONUTBaeOGFowj04osvxqTQCEipLsq++uqr4cwzzwz/396ZwMlTVAe4uBEEBOVUkBvkFDkVRQE5AgIqIZ4QMYEogiiICpiASmK8UEEFE8OlCAh4oZwKBuQSEBBBUG65QcKNnJP6St7Y29uzO7P/2d3Z3e/9frvd011VXfVVdXX161evUCThIBvOlP+kk04q5/7lX/4lkTcE3l//+teLYmjJJZdMW265ZbrvvvvSVVddlS677LK0zjrrlHD+k4AEJCABCUhAAhKQgARGJsDHU/6OP/74tPLKK5ePs69//evLB+eRY3pWAhIYDwIqfMaDaoc0US5ssskmReGD0mXHHXccEhJlB8oJFDEoG6qC4gYFCFO98JsTjpJRjmAFw8peG220UbFkqcar759zzjkJzXtYBJGno48+Ol1yySVlNarRVhCrpzfSb/JMuvvuu2/p8An75JNPpoMPPrhY38CiqvS64ooripXR/vvvX8qBk2jKyUMDZc+y2UH0PvvsM2TVLyymvv3tb6fVVlutXSY4Lb744gnFTqRPOb/73e+WMqLMwZIIoR6wAuKBtPfee7d9K5H3E044ITHFbrzkjjvuKEqwSJ88IigGkfhdfrzwr36s/jviRRrxu5pGt8dIG0UZ27mvPqCexAz9/dc6yrX0Qvnj99hwPJPTuW/2OdOn53jJ2BKYTrFeaP/5BvhrqeL3AJdx1mq/fwXD4nHOOX2c949olylFG402S7Q41mUSkxGs2m551s2BJWu1DJORKa85PgTGsz0+n9Lsv/l4forF83B8itBrqs8//9cPnb3GG8Twb33rWwcxW6PmiTEoY0f++AjL35FHHpk22GCD9M53vrN81B01EQNIQAJ9I+AIsW8ou0uIaUiLLbZYWYkLq5x4MaczxOoHJVAcq6aIRQpLnteFJc+32267YqXCdK/RLFJQCoWyh7S4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b5w233zzkudbbrklHX744Ylvbl/4whfSXHPNNdnZ9PoSkIAEJCABCUxDAk7pmoaVapEkIAEJSEACE0kARQ9/TFHaa6+92pd+85vfnD7zmc+U6UzrrbdeW4GDNc9Xv/rVorTZb7/90rLLLlvioAA55ZRT0jnnnJN++MMfpre//e3ttNg55phjirJnxx13TJtttllbUYICBUXQoYceWq43SAoUlFKPP/542mWXXdrlX2655YoC6KyzzkrkfeWVVx5STn9IQAISkIAEJCCBfhCY4+AsJPT000/3Iz3TkIAEJCABCUhghhFYbLHFirJngw02SC960YvapZ9nnnnSE088kX7729+mddddtz3l6vvf/36xynnve987ZLoXFj1Mz7rsssvS7373u/Ta1762WO6Q4E033ZROPvnktMoqq6Sdd965WPbEhRZeeOGye+WVV6a55547rbTSSnFq2PaOO+5Id999dyIOY59f/OIXJW2slJgeFlPJbr311nTBBRcUBRNloIx1i6Nnn302XXHFFemXv/xluvDCC4uPniWWWKLkIS6MMocpavW4lOcPf/hDOffSl740gruVgAQkIAEJSEACfSOghU/fUJqQBCQgAQlIYOYSCCudOgGUPshzzz1XtkzLwv/OAgsskDbccMNyrPoPxQiWQccff3y66KKLim8ezp977rkl2BZbbFEN3t7fdNNN02mnnVaUNNtss037eH0H58nXXntt2nPPPYvFUNWHIUqd/fffvyhvsDSqCuX72Mc+1lbm3H///WUaG1PQll9++cR0NBROP/3pT4tvntVXX70afcg+09iY5sVUNqx9FAlIQAISkIAEJDAeBFT4jAdV05SABCQgAQlIoPiowQIGpc/LX/7yQuSGG24ofnuY4oX/nSbBhw8KH6x8cMaMoKRhqhYWQE2CDx+sf37/+98XP0CLL754U7D2saOOOiq95S1vKX51sPhBEXTNNQLEG/gAAC6OSURBVNekr3zlK+muu+5Ku+66a9poo40SFkE4o8Ya54wzzihOqEnkhBNOKNd53/veV6x0OIZvoeOOO65MR1t11VUby4fC64gjjijXwGnzIE0/owyKBCQgAQlIQALTh0DzEhjTp3yWRAISkIAEJCCBSSKAH57bb7+9KFVCuROrVWFN00le8pKXFEUIDp8RrIOYVsVxnDV3kpe97GXl1AMPPNAp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PPJIOfZf//VfKStuEozzS08lpruDQuBVr3pVOytYZ42X3HDDDemII45Ijz322HhdwnQlMJAEXvOa15R80e+/9KUvHcg8mqm/Epio/lDeEhiJwBlnnJFOO+209Oyzzw4LlpVv5dgGG2ww7JwHJCCBqUlAhc/UrDdzPcUIjKbMyV90E9O5+iFzzz13uummm4pC5X3ve18/khxTGkzj+s///M8S93//93/TAQcckFZYYYU0++x/7XaWWmqp9B//8R/pxBNPLGFQ2Dz44IPta6HUyRYb5feXv/zldNxxx6V11lknzTPPPOXYi1/84rTbbruliy66qCh9vv71r6ff/va37fjuDAYBlDz/93//V+p2rbXWGoxMmQsJTCMC733ve0t/T78f/eM0Kt60Kor94bSqzmlZGD6k3XLLLek73/nOtCyfhZLATCQw50wstGWWwEQRyCax6Q9/+EP62te+lvL0qo6D8ZNPPrlYrET4pvzhx+akk04q6f35z39Oyy23XFpzzTXTO97xjjTXXHMNiXL++eenO+64I+2www5p4YUXHnLuoYceSnnKWbrqqqvS3XffnbL5blp//fXTlltuOSQcljg88BdaaKHie+eyyy5LeUpOebHgmvjjGUnyNK1y+lOf+lTaZJNNOgYlLSx0zjnnnHT66acnXl4QmGHZ84Y3vCHts88+HeNjxbT33nsXH0E/+tGPUq9KhUsvvTT9/Oc/T9mUPC2//PJp2223Ta973euGXQ8eeXpMOvfcc9Of/vSnNO+88ybq6y1veUtaffXVh4T/2c9+VhQc73rXuxI+CYhzySWXpJe//OVp3XXXTdtvv/2QtkDdnn322UWhtdJKK5X8/OpXvyo+mKibzTbbbNg14oIoU6jPyy+/vChW1l577bThhhum17/+9RGkbLGOQiFGXWAVRR5RxFEOGKIcnH/++YfEwecObZO6xyJr0UUXLWHf/e53D2tXQyLWfnAtrLqibqNtkY8dd9wxXXDBBYXR9ddfnyj/1ltv3VgHtWTLT3w44XOAuAjbY445puzDDiVjVUar78hbN+0eZSN5h+uSSy6ZXv3qV5e8v+xlL6tesr3fa/h2xBd2Im/4wfq7v/u7xH3O3+9///tyH+PXirbSSfiae9ZZZ5V6595fddVVS5288pWvHBbliSeeSKeeemqxqqPuuSYvq7TpuhUJdUsb5x7mReFFL3pRuTfyNLK04oorDkubfNBm8RGBDy/yAbttttlmWF/Wa9rDLjbCgeo98fzzzxcfOLQn8gJH7lUEP2x8Eeceo99929veVvrMetLd9hFRj53aGO2/kxCXexJLRyx63vzmN5f7nv4jfhM3+hT6KMpB/rnf6S/g/c53vjMtu+yyjZehndKuUNpzP9IHY2nJsTxlOG2xxRalL2uM3MXBbvoV+mSeYVgZ8IyqCn0p9zl9XL19cT+i+KLMPB+RXtpbL+GDMR8ieum3+9kf9rOuem2/Y+m/qTvaIX0mz03aEv30WIXnNn7Kwt8M/f1OO+1U+qqmNLn+hRdeWHz/cf9Rd9xvfICqCnV0//33J/ow+gl+02cyNmCsFPfOeeedV/q+m2++uZSH52g1rbG2EfJC3G7HfISnT8Bqh+ch9wD9AdZ/8OBDIEI/cO+995a+jN/knzEAwrhkkUUWKc8TnpPrrbdeed5zrtpXdjt+IN7DDz+c8jTGkic+4jH+oM/ig92Pf/zjxLOSMZQiAQmMM4E8mFIkIIE+EwgfPvlB28pKlzIf+rvf/W7Hq2QlRQmTFR+Nc6cvvvjicjx3B8O2xK37bciDqBIuP6SHXDO/sLTyIGBYGqSLj4+sDGqHDz8Siy22WOtf//Vfh8QZzS/RAw880A6frXbaaXbayQOw1qc//elWfmFsB8kvKiUNfJCMJnlg1srKohblG02iXHnQ0sqWV+18Vtlma6shyeSBcLseq+FiPzslHhI+/BFkhVlj+pzPjlbbccLPyh577NHaaqutGuMcffTR7fCxQ/12qs+PfOQjrez8NYK2slPXki7+PpriZGVXK79gtcNTb1EHUc7Ywq7ettoRG3YiXpyq1sG//du/NZb3c5/7XAQfcZutxBrjc81s9dWqXqub+o7wI7V7/EXtt99+jdclXr0d9hq+U4Ejb9zz2bF74/X33HPPIfUebSsr1lr/+I//2BgnvzANuST3b1MbgSl1n1/Y2uG5N7LyoDFdwtOnVYV7NfqnaBexzUqFVn4ZaQfvJe38Ut/KjkZb2eqvxTW6kbgn6PsoV+Qjtj/5yU9aWUE27Djn8/TBIZfopY+IeuzUxuI8eapKVpS0stK05Ie44e+E9kae6DtCot6zYrBjn1Ltb4lHO83TbBvL+4EPfKBdz/V4cc1utt32K9G+8wv0sGSjf6Uvq0v0WVn5X0710t6I0Ev4YNxrvx3tK/Jere9u+8N+19VY2i/ts9v8ZoVq6zOf+Uxj2/rGN77RijqNNh1sRtrSvwfL+vazn/3skKjcO536bMrBmK0qkR/GOvW0CZ8VKmXM0nQuK5XaSY21jfQ65rv99ttbWXE2LK/kj76c80invpdwWdldwuQFFko62UK7/OZf9JXdjh+IQ3qMK5oYZcvuchzOigQkMP4E+OqqSEACfSZQVfjkL9/lwZa/tDRehZcnHoicz9YgZZ9BawgvQAzuCcMLDQ/RbOHT4oFJHI7XHdXGQ736Up6/FpWwhGcQc+2117by195W/sLTfrHHiV9IDEIJzx8P5mOPPbaFEqM+OIo4sf31r39d4my00UZxqKctL29x3ccff7ynuKMFrpcrr/5VeKLsQEkS17311lvbSaF84DiDF8oOf9hWB7vZkqsdPgaLxMmWAq38NbOVLSZa2aqqlb+Wl7QYnDEIRmJQGNfmJZmXbuo+m1e384RSKwQnxQw8icNAlvxm/zWtbBnUbhe8vIXEgI3w5I/88/JF+4xBGS/LIfEST1gUcoTNX89b2bqnXLPaRiNOp22UK87X6wCFGeVhUEobj/DZ+iOidNyi7KQMUUfw5Td/pFe/1mj1XQ/f1O6j3uHGy2+2RCvKsqryifKE9Bo+4tW39bwx+M4WNa385bTko9pPRNxq24oXG8LzYkXbhDV1yT2HsEVJwHH6A9pT/krbyhYXRSnMccodysRvfetbJSxp0z55Yaa988IV9RiKRNp73BsoJ+jLuL+zhVK7XXFfhPSSdvSjXJM67kaq90S22mnR3lCeoNyIvLPNqwEWpXr+wt9uZxyvKtqj/XXTR9Trsd7G4jxMQ+CUrQ9LvqgvnPOHjKTwIZ+0C/ot7uFstTMkHRQHIdUX6BNOOKGEpx1/85vfHMJjVhQ+3fYrtA3yDoNqHqsfE2BdlXh+Eg9evba3XsNX7y2u2U2/TX4Jy19I1Hcc76Y/7HddzUr77Sa/cS9TRtoW9Ujb+sIXvtDmwbluFT58QAteR+ePITwradt8rInj1eclC0NwnPaULUvK9bnfq31AtmSNKmn3U8RBUcW9TnoxtoprcG8wHiAtPvBxHIV8yFjaSK9jPu4P+gSuTd8dY0TKGfmNfpXnPs/GeI4z5onnJc8FZCSFD9egvxpt/MBYJJ5HfPSkj6edMwaKZ0CkFazcSkAC40fgb0+c8buGKUtgxhGoKnwYRMaqB7ww14UXDR58KFJiwFp9mcbyhfM8NEmrKtk8t5yrvhhwPh7yPJRD4ktVk3UOLwLxcI7BfHUQyks0v7sVBnTkOTtaHhaFdLI5fuMf+UBipTHy1G+plovBXlV42YVl1AfnGATxm79s5lwNXvbjqxoDv5AY0FCP2cw6Dpct14/BGRYESHVQ2GQJFpZCKPiiDWDJQZ54CawLA+koB4NRJAa2MI1jES++JlbbES9TpB/tIcLy8h9thfbajQS/CFutg+pXxDgfCgcscroV7i2ug7VGVarX6qa+q+Gb2j2KtShPU3uI+xUlD9Jr+Gre6/vVvFWVcxEu+g/yh4IXqbYt9qvCC1KUJU9JKKciPF+F436MOPyO8Ch1kFCOYAVYl1BQ8EKG5KlIJT7trK7IpV1j4UP60eZ6SZs2He2yqV5KBmr/4p7gmvGyQxCsHSItXt5CGRbRw/opL4NeDvXaR1TrsamNxfm4H+EefQr9Td2CaTSFDwrbqnAPR/9AX4xg3RnHgn81Dsr+qPum89WwI+330q9EP5mnkrWTZKW/yAfbyD8BDjvssHIOSzak1/bWa/i4V8hHt/02+Yr8s49EfXO8m/6w33U1K+23m/zysSPuJ5QLdakqh7tR+PBMjXsQpUZd8hTwwjieBdV+sdpeIl72EVjCc4+FxP3G/VkV4kf91S3M6EPjHEobZCxtJJ4h3Y75wnKV8UFVOcr1UVRFnqps8yIa5XjdUpE4Iyl8qMduxg/x8QOO9KdVof6iH6gyr4ZxXwIS6C8BFT795WlqEigEqgofDsTS5HwBqgpmwTyMGWjzEIyBSVXhQ3ge4vUHOccxU45BevXlrK7w4WUqHvq33HILUYdJPORRJCDVQWjVRHlYxIYD8TUv0qoGQQkVealvMY1HGJhwrs6hms5Y96vlqn6hj/T4ms+1GXRVpa64iXPBDSubkBgs1qezxPn4Ys4LLRKDQgZTTfWMNUXUc5hmx+9QGkXasd1rr71KObAEQ+LlluN1qbYPrFWQ+AKIspJpLWHRwTkGcPWXYI53kqjnOF+tA6wm6oKFBnGy/6f6qY6/u1H4dFPf1bw1tfuwuKp+xa1mivKQ97A+6DV8Na36fjVvTS8uhI+vzChdkWhbne6leHHC0i+E9kDf0iRY/VC+7CuinGZZX37THunnqtNCSYd2whaJNpX9mZXf9X+nnHJKSSs7ay+nekmbCNw7dUVS/RrV33FPkK+6hLIpO5uvn2qFspUXxap020dU67GpjcV5mNKeaGswxioq7s/qdUdS+HSq95hqzL2NYMnFNXhpbBLYxkv7rCh8og1006+EIgDrjBCmeJHPUIJj6RISFms8f5G4VrftrdfwcW/10m+TL/LPX0jUN8e66Q/Hq67G0n67yS9tnLJ1alv0GcGkqpQIPvVttHfadvQt1TB88ODZgQIQCWuopo9dnEchFc/TUJTHM5z+uy6hrIh7p3qePFEWrJyRsbYR7remsUDTmC/6ZJShTcIYAB4o+EPGqvDpdvwQY9CqlVVcm2307Sp8qlTcl8D4EdBpc+6ZFQmMNwEcE+NYGGeb+Yt/2+FfVoyUS3/84x8f4sS3nh9WtsKJJc7vssKm/OUXqZRfwotjY8LngUA9Wvt3HpSV/TwwbV+7ffKFnViCEweldQnnpfXjnX7nAVE5hePAuuCkLw8ahhzOL6/F4Wvu6srxZZZZpmxxeM2x2WabbUj4fv2oOleMNOGQB3nFAWIcY5sVamWlsKywKvxxRkgd5K/tJVgeLFeDl/38ojbsGAfiOOWuCs6W55xzeLeMU+48Pa7tFBfnyji0RvKX9/S9732vmkzZj3rEmWRVqssCx3H4UmeEZVlzHCoeeuihxTEq5c0vmsXRc7a8KQ4WcbJYdwYeafWyzYPstMQSSwyLgoNgBMb9lF7qm+s2tXuWf0eyD6biwLj8aPgHS9pHr+Gb6r8h+eIUuek4TkjpZ/IUgyGnm+qdANmqJmXrhCHtnfZA26Rd0Y5w1Eu7oL/BkS4S/Q1OSnGCiqPsPLW0/OHwOL+EFCeg0RcQJ7/MsSmOQnH+XJf85bgcirz3kjYRYdctv+q16w7OOYdzZqTJAXecy4rPEib+jaWPaGpjkR73eH4hKvclx3hOcG/2IjhxbxKcjCPRj0RfTftpErhyLr/kNp3u+lgv/QoO3bPlWGnP2ZIkwRtH4tnKKf393/99yhakxZnuhz70odI/Z+uR0k/hFBbptb31Gj4K3W2/vfTSS0eUxm23/eF41VWv7bfb/DJmQXCG3iQ4T86KkrIgRdP5+rF4psG9aWzA4gJZWdiOFs/ZpsUYCISTec7RtmEb9wbneO7WBQfd5AEHx3XhHOOWet/QaxvpZcwXz5gYV9TzxPiTv35I03OkafyQp5WVyzWF50TdEXs/8mYaEpBAZwLD3yw6h/WMBCQwRgLzzTdfyua/Kc8FT0ceeWRZrpyBdjanLSn+8z//c8eUeWnkBTsG2jzUWS2HwRaKAF74RxNWZkFe8pKXdAwa53iRrQpKol5fomJlpPxFqZpU2WfQm7+8DTmev0AVZUYcpGz8wYiVKljdaiRBMZAtbcrL0Mc+9rGRgrbPkX6TxLLx1XP5K11ZWYJjxOMljZc+lkBGgZetS6rB2/sMZJskrp2/RA45HXUw5OALP+Icg3L+Qjpdm/PUXbyYR/im8sW56halS/5KWVYmy1/Mi7KRVdr4Q/IXujRSu62m1et+0yC+1zTq4YN5/XgnHp3afSglqDteMJuEuEj+cp16Dd+kYKhfg/Q7MYo2V20jxO+0XHdTOoccckh50SYeChteYliZa4455ijKnXjh4jx9Q56ylbIviLLqCiuvwIU/+rxsrVPud8JF35ItGduKI9KoCmWLl6Ve0q6m0et+pzYwWjqhoCbcWPqITm2sel1Yx8swKyOigMtWWdUgI+431S8R6seDeX3Fx2riY+VUTaOXfoWXRV4MKTMvtTwP+IMDKwuxWhofQbJVV/v5wepj0dZ7bW+9ho9yRd8cv6vbOFe/H6thRtufiLoaS/vtlO96fukHkZGUlbQLFCXdSPb/U4J1+9EhnrPRNzZdI9KK/jrC9KPNk1a0g0i3uo1z0UZ6HfPFB71Ip5p2v/d75dFp7MizRJGABCaOwOwTdymvJIGZTSBPFSoA8nSeMmjlqzqDV75iN1k5BK08paAoe/jSi3KBLyd5Gk86/vjjy1f1Ti+yEZ/tsi8sv8uAKptAV0+19/NUobLf6YtMO2AXOyh1yBfWACgLxiKxlDuKhdEEi4Y8BassJzpa2F7Pw4UXCyRP0SrKljz9pSyXetxxx6VddtmlY5JhDVEPEC8WvEhXhfrtJCwFj2D9VP1STP6yv4COfwcffHCJN5Z/DMpYghYFHdfnS2l2BF2Syj5kyjLNY0l3KscJZSZKkZG4cw7lTa/hu2HDC0yTRRlxY/D/yoal1rtJm/sVqwruXyx3+OJ95plnlv6G9t70xZt0sSTJfovK8siUHSs50kCp/fnPf75cOr7qssTxSOx4+axKN2lXw0/0/qz0EaPlFaYoPOiDeF68/e1vT3kK0GjRej4f7bRJSU9iKIRi6eueE69F6KVfyf54Suw8NSSx9DwSy9bHcs4sF88zEcl+W8qWf722t17Dx4W67bcj/Kxu+11X49l+KWv0RdE3NZU/rICaztWPhQVwnqJbP1V+01ZROLNkPYLCFIlnaPlR+xdWU2G9Vzs9yz97aSO9jvliHEGf2iRYTMJjJP5N8WblWNxLnZR42YnzrCRvXAlIoEcCKnx6BGZwCYyVAFYqeUndMmjnxSmvJlGS+vCHPzxiktkXRzmPoigGThHhyiuvLOnF705bpgDF1Irs6Lkx2EknnVSOdzILbozU4SBfdbC4QbL/hTIdpEPQjofznPNyDkXOSAM1vvblFUZK2OyDoWN6Yz3BywQvWkwvYMpK/YsVLyKdpJOyixdopK5cw1oHi6a6MFDLfhDKYeqRL9hRn9mfQz14+Y0ikRfliNcYqMNBrsfUNl6s+NoYgmVZdsaYsg+TcohB5EwTGCCd7iN4wz0Ugb2G75ZnvPxWw2NxEi++8ZJTPd/Nfl7OugTjnqpPgci+LsrU0mo6WFvQVmIaFuewXEEhiIIUCVbxElBX6JRA+V9enrmwY4v0knaJMEn/ZqWPGCnLKMzo/1CQHJOnzFGneSWhYjU1UryxnFtzzTVLNJR82UfKsCRQqoelxLCTXR4YS7+CggvBkif7jSptK6YGxdQt2jzn4PXGN76xnZte21uv4eNC3fbbEX5Wt/2uq/Fqv1HOFVdcsezy3MMaqy55xdCOFn/1sPyO9OgDmWpaF6wMN9988/bU8dVXX70EyX6fyhTxengsDrmvkFCm1cPM6u9e2kivY75ot2EFXs0rH/iyv67Cg+nZEyVMFUayP75hzBlTxJitBPKfBCQw7gRU+Iw7Yi8ggb8RiBdltpjq5xUgil+Ev4UYvoffDKT+BQwlCH4MQupm1HE8tgcddFDZzStYJL7oVYXBNC8USFgilR+z8I8vsyiP+DrNC3DTSwTJo7TC2qkuWBIwUEEYsOVll+tBipn/NttsU1gSNgYZwwLOwoGwiGJQWJ3Cwf4Xv/jF8iJC8k388VfBtKiq8DuUYU1TopgGk501tqNQ//juQLLTybZpOIo0hPqMKXvlQP4HT6b6oZwK30xxrpstPgzw28IAkul2VYmvpxzDV8KgCC97SKevvv3KZ155qkypCb811XSxvKCO8gpWbUuDXsNX0xtpPzsJL1Yy1TBY03BtlIHZaWb1VNf7MbUnvnhHRJQ9KBHjpT/aO9MIeFnCx0pdYrohCiAkO0IuW5QYdUsSpuzQL5L/sKjrJW3uE/KHkmi820ApROXfrPQRlWRG3F1wwQVTKOO4t3mR6qcwpSUssfDBxEszU2VRqGNl2eRzievz4rb99tsXa7DR8jOWfoWX++zst0ybRZlK/ca0Eiw9eNllmjRKeXz6VKek9dreeg1fLW+3/XY1zlj3x1pXna433u0XCxT8v1FHWA/G9cgP/Up2qt0pa43HUaLTv5EeFnDV9FAmZIfEJV74raE/oU9E4ZGXgR+SJtPNot55pvJxbLyk2zbS65iPabMIfovCn0+UAUUoYzCE+zokpreNl9UPU3x5JnN9xoLki+nl9O/UXZPlD3WHP673vOc97em/kV+3EpDArBGYc9aiG1sCEuiFAI77cDgZX5MYAIwmKHWw7kERw4AX5cdVV12V8goxZRCDPwemDlWVEU1pYl3Eyztf29dYY43yYkpcFBBVvywjTS9rSrfTMZQNKAx4CWNLuRmc83WWgTpKJ5xkMgBAGBzEF9tIky9yDMZwHosyhy/cMMSfCCbB8UWLtJniNh7zwlHKIeQTR7Qolhi4wJKXfs7zYtvEnzyTXwY/vLhQXl5OEMy2618T4UP9MJ0NiyKm7aCMY6DKS3NYPREfayN8p9AmVl111bY/Hb6ixpe8ww8/vP1yRJxehJdyBpK8ROXlp8tUHqaioXiLASTTvQZFaNO0IeoEJ7w4aEaxRlvpp+CPC8UKbWHXXXdNWHih0GRAyws5LyE4uY7pJr2G7zavKNvWW2+9ch8zeKdeeElHmIJXt0TrNl0UqCh/YcfXc9o3/QsKBpQ90X9Fe8cZPQoIrHlQEtHmOcd0iryaU7lsTLPBMoGXKhQLKINR8OC7g7BhBYQCIZxr95I29R7+zLh/UIROlMxKH9FLHrEIzCuZFUU/zw7afL3P7CW9elj6KT4k5FWNimKlep7nT16+e4gCmD6cfgyh/ddfNqvxY38s/QrPrujTaJ9VQQEU/VFeoa56KvXa3noNHxfrpd+OOLO67bWuRrreRLRfFMJYo9Kv8JEHBRCKDaxZqD+eb6FMHimvcQ4Lafr5SI9nEdOmSI8+mDqJD2xYxOaly4vC45Of/GRxGr/pppuWDyVYrvHxjfAxXTmu0c9tL22k1zEflpiMs+i36Z/56ABPLN8YHyB8BMI5dUhMmcevJONR+lwY9Ut4JmGBxXiJcRx/ITynqae6Epk+nLEuQjlo44oEJNAnAnlgpkhAAn0mkKfytPIt2soOJIelzNKZnGM55Pqym03LsueXrlZ+YSpxiMdffmC28ot4K8/ZbsVStHm1qPa1YknMPEhuH2Mnf0Epy41HOrHNX79a1WWZCRtLxeaBAz/HLNlioMUy2/kFb0gZ4tp5INTKljKNyw3HRbOSpDE+ecsDhI5LSEf86jbKBcMmydPtSj7z4K99On+lai9JHPnOA5KyNHBW9pTw+QWsHT6WdM3+llqxPHrE47p5yko7LDt5iktJg3pmydms2BrCKg/IW/mle0gcflAWloOPtGNL/KwMGxI+ljiGZZPQBogf7Sh/NW1lhVF7udpImy11SZ67lYgb4Uerg6xMK3mpMo24I22zwqVFe4rrZaVgux13W9+Rt9HafR5ID6snrpunaLay881h2ew1/LAE8oHIG2XJzkVbcZ9HeelTaI9VyYqgwoO21SRZcVjOZ4VL+3S0lUiXbX5BK0sNx3K+sA5hme56myUODKvLZkf4rJgZ1q4oE2HrfWK3aWdlRGmXMKguPxzXbNpGOZvuiayUKly4B+rCcuyUr7osey99RNRjpzYW5zu12aw0K9fnPMtIxzLVLNseMlq9Z2VuSaNajxE3T9VsZd9frax0buUX5BZtg3rJL28lTn4xK0Hp26Ovg0e2CIokOm7H0q/kF/ly3aZr5OlI5Rws620nMtFLeyNOt+HH2m9TDv5CRqvvkfrDbusqrtVpO5b226l9dspvtuooS7NH+dlSbyzdnadjFyb5o0inLA47zngpWwK320akS1pNz8s8dWzY9YmTPyq18lSzIelnxXXH/HCfEa8+viKBbNFZzuUPaSW9sbSRsYz5uBcZRwWD2MI3K1uGlI0f3Id5ena7H67WZVailXSykq4db6S+kkD18UNEzBaCLfrXrDAudZxXpm1xP2d/YOUaPMNCsqVySYe8NLGNcG4lIIHeCcxGlNwxKBKQwIATwLcLX6JwBItJc0ypaMo2X7v4us5X0aZldpm2QVpYbJBWHhQ0JdP3Y1jGYMrLFCQcSePXqBerHOLzFZkveJhoY400Eod+FgBrG6Z1YQKORQdTLDoJXx75WoVFDxZZfMmkLjDFx7w9piREfHzh4HMAS4jwpYRVBdOqiD/a6hv5RafkjRVG4MLXun5xIW3aCvnJA7GyZG3VaXSUYaZus4KstEnaA1ZcWPSMJL2Gr6ZFG+QrLfWAtQVCe2R6FNZiYRlTjTPWfdKlvSNY5VWnyjSlyVCCNkJbwbqIexNLvk7xCE/7zoP/MkWO/qCTVVIvaRO2X22/qZwjHeuljxgpnck69/Of/7xMj2HqR1Nd8Kyg/6aeqysnMnUGC61ok93kf6L7lV7aG/nvJvys9tvdcOoUZqx11Sk9jk9U++X5j98e2lA/nCQz9RCLX9osz7+m5dKr5aZvw6qIfhTr2E59VDXOWPdnpY30MuaL/DG2Y/o/9ygW3CP1qxFnPLbkgecHfifpN+py6qmnFktFrIjDqocwTM9jatfcc89dj+JvCUhgVgjkh5oiAQlMIwJY8fBVJ/cLrWxyP41KNnWKEl+9u/1aWf0KOHVKaU4nmsBolgATnR+vN70IYLXIcyNPWRxWsDwdp5zj6zvWBCF5ymk5nqd2xaEZs53MfnssdTVjKmaACjqZbWQyMWC1RV+CxWXdeop8hXVqU18zmfn22hKYrgT04TMr2jLjSmCACORpJIn56HxpZS48y7hriTFAFWRWJCABCQwwAVZWw58HTuKx1sFSER9YF198cYrVJHFUHxaKLNOOQ1z8WR144IEDXLLpl7Ve62r6EbBEg0wAK0EsjLA0YvVU/PWsu+66xQk8fpewQOd8rGY5yGUxbxKYDgRU+EyHWrQMEsgEWJkmVptgVRNWr1AkIAEJSEAC3RBAiYDjbZxqxyqA1Xg4vMUhbAirbqEMYkVFZWIJ9FpXE5s7rzbTCeAomwUNsh/LsphALCgQXHBinf0ljjoFOsK7lYAEZo2APnxmjZ+xJTAwBFhRhy+uzJlm3rYyeQRYhYQv5Kyi1M0yr/g0YBUw/DPhs0eRQBMB/BuwIhy+KrDgUyQwHgTou1hO+frrry/+TVgdkb4MH1XK3wgMQr9tXf2tPgZxbxDayGRzYTzEiqr4WsKqBz+GrOaon57JrhmvP5MIqPCZSbVtWSUgAQlIQAISkIAEJCABCUhAAhKYEQRmnxGltJASkIAEJCABCUhAAhKQgAQkIAEJSGAGEVDhM4Mq26JKQAISkIAEJCABCUhAAhKQgAQkMDMIqPCZGfVsKSUgAQlIQAISkIAEJCABCUhAAhKYQQRU+MygyraoEpCABCQgAQlIQAISkIAEJCABCcwMAip8ZkY9W0oJSEACEpCABCQgAQlIQAISkIAEZhCB/wdOjgNg8XFU5AAAAABJRU5ErkJggg==&quot;&gt;
&lt;h3 id=&quot;marking&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#marking&quot; aria-label=&quot;marking permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Marking&lt;/h3&gt;
&lt;p&gt;Figuring out which objects can be collected is an essential part of garbage collection. Garbage collectors do this by using reachability as a proxy for ‘liveness’. This means that any object currently reachable within the runtime must be kept, and any unreachable objects may be collected.&lt;/p&gt;
&lt;p&gt;找出哪些对象可以被回收是垃圾回收过程中的一个必须步骤。垃圾回收器根据&lt;code class=&quot;language-text&quot;&gt;可达性&lt;/code&gt;来作为”存活”的指标。这意味着任何在运行时中可以被访问抵达的对象都必须被保留，而任何无法抵达的对象则可以被回收。&lt;/p&gt;
&lt;p&gt;Marking is the process by which reachable objects are found. The GC starts at a set of known objects pointers, called the root set. This includes the execution stack and the global object. It then follows each pointer to a JavaScript object, and marks that object as reachable. The GC follows every pointer in that object, and continues this process recursively, until every object that is reachable in the runtime has been found and marked.&lt;/p&gt;
&lt;p&gt;标记（Marking）是找出可达对象的流程。垃圾回收器从一系列已知的对象指针开始查找，它们被称为根节点。这包含了执行栈（execution stack）以及全局对象（global object）。接下来只需要跟着指针走，将一个个可达的对象标记起来即可。垃圾回收器会追踪对象内的所有指针，然后递归继续这个流程，直到所有运行时内的可达对象都被找到并被标记起来。&lt;/p&gt;
&lt;h3 id=&quot;sweeping&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#sweeping&quot; aria-label=&quot;sweeping permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Sweeping&lt;/h3&gt;
&lt;p&gt;Sweeping is a process where gaps in memory left by dead objects are added to a data structure called a free-list. Once marking has completed, the GC finds contiguous gaps left by unreachable objects and adds them to the appropriate free-list. Free-lists are separated by the size of the memory chunk for quick lookup. In the future when we want to allocate memory, we just look at the free-list and find an appropriately sized chunk of memory.&lt;/p&gt;
&lt;p&gt;清除（Sweeping）是一个流程，将死亡对象所遗留的内存空间地址添加到一个被称为free-list数据结构中。一旦当标记流程结束，垃圾回收器寻找连续的不可达对象占用的内存空间，并将它们加到适当的free-list中。Free-list根据内存块的大小分类，以便引擎可以快速定位利用。之后，当有内存分配需求的时候，只需要查找对应尺寸的free-list即可。&lt;/p&gt;
&lt;h3 id=&quot;compaction&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#compaction&quot; aria-label=&quot;compaction permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Compaction&lt;/h3&gt;
&lt;p&gt;The major GC also chooses to evacuate/compact some pages, based on a fragmentation heuristic. You can think of compaction sort of like hard-disk defragmentation on an old PC. We copy surviving objects into other pages that are not currently being compacted (using the free-list for that page). This way, we can make use of the small and scattered gaps within the memory left behind by dead objects.&lt;/p&gt;
&lt;p&gt;Major GC也会根据内存碎片的程度，选择性地执行某些内存页的撤出（evacuate）/压缩（compact）。你可以将压缩行为类比老式PC上的磁盘碎片整理行为。引擎会将存活的对象从一个内存页拷贝到另一个当前并未在进行压缩的内存页上（根据那个内存页上的free-list指引）。用这种方法，我们可以利用那些死亡对象留下来的小块的、分散的内存空间。&lt;/p&gt;
&lt;p&gt;One potential weakness of a garbage collector which copies surviving objects is that when we allocate a lot of long-living objects, we pay a high cost to copy these objects. This is why we choose to compact only some highly fragmented pages, and just perform sweeping on others, which does not copy surviving objects.&lt;/p&gt;
&lt;p&gt;内存回收器执行这样的内存对象拷贝行为有一个潜在弱点，就是当存在大量长期存活对象（long-living）的情况时，拷贝行为的代价会非常大。这也是为什么我们选择仅仅针对那些碎片化程度非常剧烈的内存页进行压缩操作，而针对那些不那么严重的，就对它们进行清除（sweeping）操作，清除操作则不会对存活对象进行拷贝。&lt;/p&gt;
&lt;h2 id=&quot;generational-layout&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#generational-layout&quot; aria-label=&quot;generational layout permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Generational layout&lt;/h2&gt;
&lt;p&gt;The heap in V8 is split into different regions called &lt;a href=&quot;https://v8.dev/blog/orinoco-parallel-scavenger&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;generations&lt;/a&gt;. There is a young generation (split further into ‘nursery’ and ‘intermediate’ sub-generations), and an old generation. Objects are first allocated into the nursery. If they survive the next GC, they remain in the young generation but are considered ‘intermediate’. If they survive yet another GC, they are moved into the old generation.&lt;/p&gt;
&lt;p&gt;V8的堆内存会划分成多个不同的区域，被称为&lt;a href=&quot;https://v8.dev/blog/orinoco-parallel-scavenger&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;代&lt;/a&gt;。其中一个被称为&lt;code class=&quot;language-text&quot;&gt;新生代&lt;/code&gt;（其中还进一步分为”nursery”和”intermediate”两种不同的子代），另一个被称为&lt;code class=&quot;language-text&quot;&gt;老生代&lt;/code&gt;。对象一开始被分配在新生代的nursery里。如果他们在下一次GC中存活下来了，就被认为是”intermediate”。如果它们在更下一次的GC中存活下来了，它们就会被移到老生代中。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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NS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMTM5PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjQzMzwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpDD9LJAABAAElEQVR4AezdCbxt5fw/8Ke5bqNugyZNNI8iaaBJKjIkhZ+h+FVKhhS/Qj/5G0oK8ZMpiYTED4UfKQqVpElJadZcQvPc/d/PYh377LvPcO89996913o/r9e5Z5+1117red7Pvns/67ueYa77779/SpEIECBAgAABAgQIECBAgAABAgQGQmDugcilTBIgQIAAAQIECBAgQIAAAQIECFQCgjneCAQIECBAgAABAgQIECBAgACBARIQzBmgypJVAgQIECBAgAABAgQIECBAgIBgjvcAAQIECBAgQIAAAQIECBAgQGCABARzBqiyZJUAAQIECBAgQIAAAQIECBAgIJjjPUCAAAECBAgQIECAAAECBAgQGCABwZwBqixZJUCAAAECBAgQIECAAAECBAgI5ngPECBAgAABAgQIECBAgAABAgQGSEAwZ4AqS1YJECBAgAABAgQIECBAgAABAoI53gMECBAgQIAAAQIECBAgQIAAgQESEMwZoMqSVQIECBAgQIAAAQIECBAgQICAYI73AAECBAgQIECAAAECBAgQIEBggAQEcwaosmSVAAECBAgQIECAAAECBAgQICCY4z1AgAABAgQIECBAgAABAgQIEBggAcGcAaosWSVAgAABAgQIECBAgAABAgQICOZ4DxAgQIAAAQIECBAgQIAAAQIEBkhAMGeAKktWCRAgQIAAAQIECBAgQIAAAQKCOd4DBAgQIECAAAECBAgQIECAAIEBEhDMGaDKklUCBAgQIECAAAECBAgQIECAgGCO9wABAgQIECBAgAABAgQIECBAYIAEBHMGqLJklQABAgQIECBAgAABAgQIECAgmOM9QIAAAQIECBAgQIAAAQIECBAYIAHBnAGqLFklQIAAAQIECBAgQIAAAQIECAjmeA8QIECAAAECBAgQIECAAAECBAZIQDBngCpLVgkQIECAAAECBAgQIECAAAECgjneAwQIECBAgAABAgQIECBAgACBARIQzBmgypJVAgQIECBAgAABAgQIECBAgIBgjvcAAQIECBAgQIAAAQIECBAgQGCABARzBqiyZJUAAQIECBAgQIAAAQIECBAgIJjjPUCAAAECBAgQIECAAAECBAgQGCABwZwBqixZJUCAAAECBAgQIECAAAECBAgI5ngPECBAgAABAgQIECBAgAABAgQGSEAwZ4AqS1YJECBAgAABAgQIECBAgAABAoI53gMECBAgQIAAAQIECBAgQIAAgQESEMwZoMqSVQIECBAgQIAAAQIECBAgQICAYI73AAECBAgQIECAAAECBAgQIEBggAQEcwaosmSVAAECBAgQIECAAAECBAgQICCY4z1AgAABAgQIECBAgAABAgQIEBggAcGcAaosWSVAgAABAgQIECBAgAABAgQICOZ4DxAgQIAAAQIECBAgQIAAAQIEBkhAMGeAKktWCRAgQIAAAQIECBAgQIAAAQKCOd4DBAgQIECAAAECBAgQIECAAIEBEhDMGaDKklUCBAgQIECAAAECBAgQIECAgGCO9wABAgQIECBAgAABAgQIECBAYIAEBHMGqLJklQABAgQIECBAgAABAgQIECAgmOM9QIAAAQIECBAgQIAAAQIECBAYIAHBnAGqLFklQIAAAQIECBAgQIAAAQIECAjmeA8QIECAAAECBAgQIECAAAECBAZIYN4ByqusEiDQJwJnnHFGefTRR8vmm29eJk+ePGKuzjnnnHLfffeV9dZbr6y66qoj7tfkJ+69995ywQUXlDvvvLP87W9/K4ssskhZYYUVKpMVV1yxyUWfkLL98pe/LE8++WTZbrvtylxzzTUhx3QQAgQIECAwKAL5DvzjH/9Yrr766qod8dhjj5UllliiLL/88mXTTTctiy66aM+ipN3xu9/9rqyyyipl/fXX77lPr43/93//V23eaaedej094rb777+/Ot9tt91W5XPhhReu8rjuuuuWlVdeecTXeaJU7Zxf/OIXZf755y8vfOELkRAYt4Bgzrip7EiAQC2QL5vvfve75aabbioHHHBAvXnY7z/96U/l5JNPLosttljZYYcdhj3Xhj8efvjh8o1vfKP8/ve/L1OmTJmmyP/7v/9bVlpppfK6172urL766tM835YNaaRee+21ZYEFFqganJ3lvv7668u3vvWtalMCX2uttVbn0x4TIECAAIFGC6QN8e1vf7u6MdaroKeeemp53vOeV7Ul8j3ame64445y+umnl6222mq6gjk//vGPq5sn4w3mJLj0zW9+s/z2t78tTz31VGcWqsc/+MEPqptYr3nNa8qaa645zfNt2ZC24J///OcqYNN9g/PKK68sqcuk1VZbrWoftsVFOWdOQDBn5vy8mkArBXLX4De/+U35wx/+UC6//PJpGgm5QD/ppJMqmwQruhsYTUf761//Wo455phyzz33lLnnnru6c7b11ltXd6geeuihcvPNN5fLLrusnHvuueXoo48u73jHO8raa6/ddJae5XvwwQcrq/RW+uAHPzhsn6WXXrrkzl4aQMsuu+yw5/xBgAABAgSaLJB21K9//euqiOld85KXvKQ84xnPKJMmTSq333579dx5551Xzj///CpIcNBBB5WlllpqtpL8/e9/r77D77rrrioAtMkmm5Rtt9225AbMI488Uv7yl79U7cSU45Of/GTZb7/9ykYbbTRb89gvJ3v88ccrq/RoP+KII4ZlK72scqM0P6P1eB/2In8QmCogmONtQIDAdAtkuMub3/zm8uEPf7jqfZPf880339Bxfvazn5UENNK19tnPfvbQ9jY8SCDr85//fBXIedrTnlb22WefYT1vFlpooeqLOo2ZDTbYoKRbbZt75oz2nkjX8U996lOj7eI5AgQIECDQOIEMU08AJDeEXvnKV5YXv/jFw8qY4E5+Ejj5n//5n6rN8YUvfKEceuihZZ555hm276z6o27vJJCTXthp76yxxhpDp0t7J+2gDTfcsGy88cblpz/9aat75gzB9HiQAE7qUSIwvQKCOdMrZn8CBCqB3EXI8KmMrU7w5qUvfWm1PfPCpItueuO88Y1vHFUr46vTe2XJJZesGgKj7jwTT954443VHD/JU8ZtjzX3Sua5+cc//lF1C5533un7mIxFet5kbpxDDjmkasiM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NTVi+s+lYwYr33JLgACBCRVIICFdZHsFojK8KXey0kDJMB6JAAECBAh0C+QiKjclcqdeYLhbx98ECBAgMNEC5syZaFHHI0Bg4ATSVfa9731vtZRkGuPdKcN5sn3dddftfsrfBAgQIECAAAECBAgQmO0C5syZ7eROSIBAvwmkO2q6tCaoc+yxx1ZDmNJtOJP4/u53v6vGRKdra7qzSgQIECBAgAABAgQIEJjTAoI5c7oGnJ8AgTkukHHR6ZmTQE5WU8pPZ8rQq0zgW8/j0vmcxwQIECBAgAABAgQIEJjdAoI5s1vc+QgQ6EuBTCycpR+zLGeW0cyKU5lALxPRZRK9TJAsESBAgAABAgQIECBAoB8EBHP6oRbkgQCBvhDIigBZ0So/EgECBAgQIECAAAECBPpVwATI/Voz8kWAAAECBAgQIECAAAECBAgQ6CEgmNMDxSYCBAgQIECAAAECBAgQIECAQL8KCOb0a83IFwECBAgQIECAAAECBAgQIECgh4BgTg8UmwgQIECAAAECBAgQIECAAAEC/SogmNOvNSNfBAgQIECAAAECBAgQIECAAIEeAoI5PVBsIkCAAAECBAgQIECAAAECBAj0q4BgTr/WjHwRIECAAAECBAgQIECAAAECBHoICOb0QLGJAAECBAgQIECAAAECBAgQINCvAoI5/Voz8kWAAAECBAgQIECAAAECBAgQ6CEgmNMDxSYCBAgQIECAAAECBAgQIECAQL8KCOb0a83IFwECBAgQIECAAAECBAgQIECgh4BgTg8UmwgQIECAAAECBAgQIECAAAEC/SogmNOvNSNfBAgQIECAAAECBAgQIECAAIEeAoI5PVBsIkCAAAECBAgQIECAAAECBAj0q4BgTr/WjHwRIECAAAECBAgQIECAAAECBHoICOb0QLGJAAECBAgQIECAAAECBAgQINCvAoI5/Voz8kWAAAECBAgQIECAAAECBAgQ6CEgmNMDxSYCBAgQIECAAAECBAgQIECAQL8KCOb0a83IFwECBAgQIECAAAECBAgQIECgh4BgTg8UmwgQIECAAAECBAgQIECAAAEC/SogmNOvNSNfBAgQIECAAAECBAgQIECAAIEeAoI5PVBsIkCAAAECBAgQIECAAAECBAj0q4BgTr/WjHwRIECAAAECBAgQIECAAAECBHoICOb0QLGJAAECBAgQIECAAAECBAgQINCvAoI5/Voz8kWAAAECBAgQIECAAAECBAgQ6CEgmNMDxSYCBAgQIECAAAECBAgQIECAQL8KCOb0a83IFwECBAgQIECAAAECBAgQIECgh4BgTg8UmwgQIECAAAECBAgQIECAAAEC/SogmNOvNSNfBAgQIECAAAECBAgQIECAAIEeAoI5PVBsIkCAAAECBAgQIECAAAECBAj0q4BgTr/WjHwRIECAAAECBAgQIECAAAECBHoICOb0QLGJAAECBAgQIECAAAECBAgQINCvAoI5/Voz8kWAAAECBAgQIECAAAECBAgQ6CEgmNMDxSYCBAgQIECAAAECBAgQIECAQL8KCOb0a83IFwECBAgQIECAAAECBAgQIECgh4BgTg8UmwgQIECAAAECBAgQIECAAAEC/SogmNOvNSNfEyJw1113ldNPP72ce+65Ix7v2muvrfa59957R9zHEwQIEIjAddddV31e/P3vfwcyhsDvfve78uMf/3horz//+c/lJz/5SXnwwQeHtnlAgAABAgQIECAwYwKCOTPm5lUDInDnnXdWF15f+9rXyvXXX98z19dcc021zz/+8Y+ez9tIgACBWqAO/s5oMOf+++8vV199dXnggQfqQzb2d3cw5xvf+Eb5wQ9+UH7zm99Md5kfe+yxyu2ee+6Z7td6AQECBAgQIECgiQKCOU2sVWXqKfDVr361PPnkkz2fs5EAAQKzQ+DKK68sxxxzTElQqG1pq622KmuvvXZ59rOfPd1FT7A9buecc850v9YLCBAgQIAAAQJNFBDMaWKtKtM0Attss01JL5108ZcIECBAYPYLvOhFLyoHHnhgWXrppWf/yZ2RAAECBAgQINAwgXkbVh7FIdBTIHeDMyfOT3/607LpppuWZZddtud+2ZigT4YHbLTRRmWllVYatt9ll11W/vKXv5SddtqpzDvvvOXCCy8smZdn5513Lr/4xS/KJZdcUhZccMGy3377lXnmmaeaG+KCCy4oV111VZk8eXJ5/vOfX57xjGcMO2b+eOSRR8qvf/3raihYjrvGGmuUzTbbrMw333xD+5533nklQzRyQfSzn/2s/PGPfyyLLrpo2W233cpf//rXsuKKK5aFF154aP/6wS233FLl45nPfGaVp3q73wQIzLxAhkv98pe/LBtssEFZYoklqs+O9LpZaKGFqs+addZZpzrJ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PwsI5vRz7cgbAQIECBAgQKCFArfeemv59Kc/Xe69996y5JJLluc973klPWnmnnvucuONN5Yrr7yy/OlPfypHHHFE+cAHPlCWXnrpaZTOOeec8q1vfatMmTKlrLnmmmX99dcvyy23XNXDJ8dIoOeMM84od911V9lvv/3KXHPNNc0xbCBAgAABAv0qIJjTrzUjXwQIECBAgACBFgokgPPJT36ypGfODjvsUHbdddcqiFNTbLLJJuVVr3pVueCCC8pll11WJk+eXD819PuSSy4pJ598cll44YXLAQccUFZfffWh5+oHCfJ85StfKSuttJJATo3iNwECBAgMjIBgzsBUlYwSIECAAAECBJov8PWvf70K5GyzzTZlt912G7HA6a2Tn+70yCOPlBNOOKEK5BxyyCFl2WWX7d6l+js9cf7zP/+z53M2EiBAgACBfhewmlW/15D8ESBAgAABAgRaInDPPfeUK664ogrEjBbIGY0jvXIeffTRai6ckQI5o73ecwQIECBAYBAEBHMGoZbkkQABAgQIECDQAoGLLrqomuPmBS94wQxPSpxgUNJmm23WAjFFJECAAIG2CgjmtLXmlZsAAQIECBAg0GcCmYw4aZVVVql+z8g/d999dzWPzoILLjgjL/caAgQIECAwEALmzBmIapJJAgQIECBAgEDzBR5++OGqkIsuumjPwr797W+vhlD1evId73hHWW+99UqOMWnSpF672EaAAAECBBojIJjTmKpUEAIECBAgQIDAYAsstdRSVQGyklWvtPPOO5cnnnhi2FN//vOfq2XG66XFF1988XL77bcP28cfBAgQIECgaQKCOU2rUeUhQIAAAQIECAyoQD286rrrrisbb7zxNKXYaaedptn21a9+tdpWT3a84oorlgR4EtBZbrnlptnfBgIECBAg0AQBc+Y0oRaVgQABAgQIECDQAIENNtigWsnqnHPOKVnZaqyUXjqXX355WX755Uvdq6dervxHP/rRWC/3PAECBAgQGFgBwZyBrToZJ0CAAAECBAg0S2CeeeYpL3vZy6p5cb7whS+Uxx57bNQC/vjHPy4PPPBA2XbbbYf2W3XVVcs666xTLrzwwupn6IkeD66//vpy7LHHjnmeHi+1iQABAgQIzFEBwZw5yu/kBAgQIECAAAECnQLbbLNN2WSTTcpNN91UjjzyyFKvcNW5zyOPPFJOPfXUkmDOM5/5zLLVVlt1Pl323nvvakWr448/vvzsZz+bJliTOXnOPPPMcswxx1RDsm688cZhr/cHAQIECBDod4G5pn6ZTen3TMpffwo8+uij5dxzzy1XXXVVtXJEf+ZSrvpZYKGFFiprrbVW2WKLLcoCCyzQz1mVtwEVOO+888pZZ55R3eV/8KGHBrQUsj2nBRac+vmUZa6fvclzyy677DKns9OK80+ZMqX88Ic/LD/5yU+q8q688solP5nc+MEHHyz5v512SL4/dt9996p+umGy33HHHVeuueaaMv/881evzz5//etfy9///vdq9yWXXLLst99+Q891H2N6/k6e991333LYYYeVlVZaaXpeal8C0whkmOGvf/3rcvHFF1ft7Mcff3yafWwgMJbA3HPPM3Xo6qTqM3K33XYra6655lgv8fwACQjmDFBl9VNWMz79+K+eVJ5YYIXywDwrlsfL/P2UPXkZEIH5pr5zFil3lbkfvL7s8+Y3lPXXX39Aci6bgyBw+OGHl6ceuqE8f9VrByG78jgAAn++a6nyx1uXLR/60IdMrDub6uvOO+8sv/zlL6vVqhKESQBnvvnmKxtuuGHJZMhjBU0SYLnyyivLb37zm3LLLbeUv/3tb2WRRRYpK6ywQrWM+fOf//ySGwsTkQRzJkLRMSKQIYInff2EssLid5cNVrAym3fFxAice8PaZZU1Niv/+Z//OTEHdJQ5LmA1qzleBYOXgauvvrp89rOfLY88bYty73J7Dl4B5LivBP4xNTeL3v6t6j110EEHuWPQV7UzuJnJ59RD995SPvOa7w9uIeS8LwV+eOl65fe/+3XZ5eW792X+mpaprFD1mte8ZoaLleXK11133epnhg/ihQRms8CZU3uU7rTu5eWVG/9hNp/Z6Zos8PzVbyzv/8Hc5f779yiLLrpok4vamrKZM6c1VT1xBf3hj88oDy29Y7l3hT0n7qCO1GqB+5d7bfWeyntLIjARAhkCuvQi/xxGMRHHcwwCtcAay949NZhzbv2n3wQIEJhwgZv/8pey1tPvnPDjOmC7BZ6++P1lhSXuK2eddVa7IRpUesGcBlXm7ChKJhy89qrLyyOLbzo7TuccLRLIe6p6b019j0kEZlYgc2WUMtfMHsbrCfQUMHdFTxYbCRCYIIEnnjSl6QRROkyXwJQpT5nrtMtkkP8UzBnk2psDec/KEkmPL2hivznA3+hT1u+p+j3W6MIq3CwXyLwaEoFZJfDEk0/NqkM7LgECLRC4/vrry9FHH11N5J0bpRKB2SngPTc7tWftucyZM2t9HZ0AAQIECBBokMDUKVgkAgQIzJRAJsv+85//XK699tpy0kknlY022qhsttlm1aTc88wzz0wd24sJEGiPgGBOe+paSQkQIECAAAECBPpcIBf66V348MMPl9xBz+PllluuLLDAAlXOs/0vU+dU6UxLLbVUmTx58tCm6667rjzxxBNDf+e1q6yyytDfd999d7Wy19CGqQ+y9PuCCy5Ybcp5u3vKZhn3pZdeeugl6V3SOeQwq4ytttpqQ89n9bEsr92ZnvGMZwytHvbYY4+VG264ofPp8rSnPa0ss8wyQ9uyktkDDzww9HeWmH/xi1889HcCIpnwvjMlKFLnM0Nuf/GLX3Q+XZKHrIZWpyz//Y9/ZDmGf6a55567vOQlL6n/LLHMimid6bnPfW55+tOfXm2K1c9//vPOp8vyyy9fNtlkk6Ft55133jCLv//97yXneeqpf/byu/TSS8tFF11U7f/CF75w6HUeECBAYDQBwZzRdDxHgACBWSRw//33V92rb7vttqmrCtxfNcLTMExje/XVVx/XWW+88cZyySWXlDSY05jM69OAXGuttYY16sd1sAHbKRcQH/jAByq7xRZbrLpoefLJJ8s/58op1cXA4npQDFitDl52zz777Oo9WOc8F7M77rhj/We55pprylVXXTX0dx50Xmg+9NBD00xEueKKK5aNN9546DUnn3xyuf32fy9NnLv2Bx544NDzuQDMBW9nevnLX16e9axnVZvyf+Lzn/9859PVqoG77LLL0LZTTjml3HzzzUN/58G73/3u6mIzjy+77LJpLlZ33nnnss466+TpKtiQVS47Uy7qd91116FN3/ve96a5cH/7298+FKC44oorymmnnTYUwMhn2u6771622mqr6hgJTOy///5Dx8uDNddcs2QVxDqlnPlM7EwZypLPiKRYffGLX+x8ujrH9ttvP7Rt3333LQmm1GnVVVcthx56aP1n+cpXvlIuuOCCob/z4Igjjhj2mfvhD3942POvfOUrq2XU640pd+dQ0CyT/sEPfrB+uuqpkaXUO9OHPvShKqCTbQmyfPKTn+x8ugo+pN7rdNxxxw17bya48dGPfrR+ugpw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vxx55JFjnqf7dbPi70mTJlXDqI444oiqF05WqJIIECBAgAABAgQIEJg5AcOsZs7PqwkQIDBugb333rscffTR1cpNWeFq5513LqutttrQUuOPPfZYOfvss6teLCussEI54IADhp7LSRLI2W+//cqxxx5bPvGJT1STBm+66abVMTIvzy233FKuvfbacsYZZ5QEdNZff/Yty3311VeX8847rzz00EPlbW9725BJlhaXCBAgQIAAAQIECBCYWAHBnIn1dDQCBAiMKLDAAguU9773veXb3/52tQz35ZdfXrJt+eWXr5YsT4+cueeeu+y6665l6623HhbIqQ+6+uqrl8MOO6wcf/zx5bLLLqt+6ufq3/PPP3/ZZ599Sj1Eq94+K35nHpwzzzyzmpg5Q6i23377WXEaxyRAgAABAgQIECBAoENAMKcDw0MCBAjMaoH55puvvOENb6iGHP32t78td9xxR7nvvvuq1Zy23HLLsvHGG1cBntHykeXKDz300JLgz8UXX1wyWfIjjzxSsjrUKqusUh0jq2fNjpSeONttt13ZYostqgmNZ8c5nYMAAQIECBAgQIBA2wUEc9r+DlB+AgTmiMASSyxRdtxxx5k6d+bUyc/sSFkS/dJLL61+DjrooKFTWo1qiMIDAgQIECBAgAABArNNQDBntlE7EQECBAZPIHPhZChVAjkrrbRS1QsnK2VlWXGJAAECBAgQIECAAIE5IyCYM2fcnZUAAQIDIZAeOVmRKvP0JJgjESBAgAABAgQIECAw5wUEc+Z8HcgBAQIE+kIgEyqfe+65JStQ1UuIZ1Lj/EgECBAgQIAAAQIECPSPgGBO/9SFnBAgQGC2C6TnTZYUr5cVzwTM6YkjESBAgAABAgQIECDQvwKCOf1bN3JGgACBWS6Q1agyL04mMtYDZ5ZzOwEBAgQIECBAgACBCREQzJkQRgchQIBA/wukF04mM15jjTXKRhttVGU48+AcfPDB/Z95OSRAgAABAgQIECBAYEhAMGeIwgMCBAg0UyBDqM4///yqB04CORtuuGEzC6pUBAgQIECAAAECBFoiIJjTkopWTAIE2imQZcTr3jh77rnn0MTG7dRQagIECBAgQIAAAQLNEBDMaUY9KgUBAgRKAjeXXHJJyTw422+/fSWy0EILVcuK4yFAgAABAgQIECBAoDkCgjnNqUslIUCgpQI333xzOfPMM8ull15arUS13XbbtVRCsQkQIECAAAECBAi0Q0Awpx31rJQECDRY4MQTTyxLLrlk2WuvvYYmNm5wcRWNAAECBAgQIECAQOsFBHNa/xYAQIDAIAmkF0564GQp8Toddthh9UO/CRAgQIAAAQIECBBogYBgTgsqWREJEBhsgXounExknGDO5ptvPtgFknsCBAgQIECAAAECBGZKQDBnpvi8mAABArNe4JRTTqmWFc9cOAcffHDJpMYSAQIECBAgQIAAAQLtFRDMaW/dKzkBAn0okF445513XumcxDhLiksECBAgQIAAAQIECBCoBQRzagm/CRAgMAcFrr766iqIc/7555fJkydXExnnt0SAAAECBAgQIECAAIFuAcGcbhF/EyBAYDYLpCdOhlJtvPHG5aCDDiprrrnmbM6B0xEgQIAAAQIECBAgMEgCgjmDVFvySoBAIwQuu+yysuKKK1Y9cFKgBHHyYy6cRlSvQhAgQIAAAQIECBCY5QKCObOc2AkIECBQyj333FMNo0ovnIceeqjsscceQ6tSCeJ4hxAgQIAAAQIECBAgMD0CgjnTo2VfAgQIzIBAJjU+9NBDy0orrVR22WUXvXBmwNBLCBAgQIAAAQIECBD4t4Bgzr8tPCJAgMCECKQXTnrfJHiTlJ43hx122NDfE3ISByFAgAABAgQIECBAoLUCgjmtrXoFJ0BgogUyhCqrUWVlqs0337x0LileB3Ym+pyOR4AAAQIECBAgQIBA+wQEc9pX50pMgMAsEMgwqvTGqYM4lhWfBcgOSYAAAQIECBAgQIBAJSCY441AgACBGRBI75vOJcT3339/w6hmwNFLCBAgQIAAAQIECBCYfgHBnOk38woCBFoqkLlwzjrrrHLuueeWSZMmlSOOOGJIwjCqIQoPCBAgQIAAAQIECBCYxQKCObMY2OEJEGiGwCmnnFIFcjbccMOy1157lY022qgZBVMKAgQIECBAgAABAgQGTkAwZ+CqTIYJEJgdAjfffPOwYVOZC2f77bcv5sKZHfrOQYAAAQIECBAgQIDAaAKCOaPpeI4AgVYJPPzww+WSSy6peuAkmJNhVHXwxjCqVr0VFJYAAQIECBAgQIBAXwsI5vR19cgcAQKzSyDLimcoVebCSS+cTGhcB3JmVx6chwABAgQIECBAgAABAuMREMwZj5J9CBBonEB64SQttNBC1e+sTGUunIrCPwQIECBAgAABAgQI9LmAYE6fV5DsESAwsQJZUjy9cM4///yy5557Vr1wcob0wtETZ2KtHY0AAQIECBAgQIAAgVkjIJgza1wdlQCBPhPIsuJHH310ye8MozrooINKeuNIBAgQIECAAAECBAgQGDQBwZxBqzH5JUBg3AIZSlUPo0qvm+22265sscUWQ9vGfSA7EiBAgAABAgQIECBAoI8EBHP6qDIGKSvzPXj1IGVXXlskkABOhlGdeeaZVc+bDKWqU5YWlwgQIECAAAECBAgQIDDoAoI5g16Dszn/Wa45ackbjp7NZ3a6tgjkPTajw5+OO+64cumll5YsI77LLruUjTfeuC1sykmAAAECBAgQIECAQIsEBHNaVNkTWdSvv+XbE3k4xyJQCbzxK6+ZKYk11lijCuIkmCMRIECAAAECBAgQIECgqQKCOU2tWeUi0GCByy67rJx77rklvXiOOOKIoZIaRjVE4QEBAgQIECBAgAABAg0WEMxpcOUqGoGmCWQenLPOOqs89NBD1RCq/fffv2lFVB4CBAgQIECAAAECBAiMKSCYMyaRHQgQ6BeBSZMmDc2FU69S1S95kw8CBAgQIECAAAECBAjMLgHBnNkl7TwECIxb4J577ql64GQo1ZFHHjm0lPjmm28+7mPYkQABAgQIECBAgAABAk0VEMxpas0qF4EBFTj77LPLd77znZLJjPfYY4+hQM6AFke2CRAgQIAAAQIECBAgMOECgjkTTuqABAjMjMDiiy9eDjzwwDJ58uSZOYzXEiBAgAABAgQIECBAoLECcze2ZApGgMBACmy88cYCOQNZczJNgAABAgQIECBAgMDsEhDMmV3SzkOAAAECBAgQIECAAAECBAgQmAABwZwJQHQIAgQIECBAgAABAgQIECBAgMDsEhDMmV3SzkOAAAECBAgQIECAAAECBAgQmAABwZwJQHQIAgQIECBAgAABAgQIECBAgMDsErCa1eySbth5/nT7sg0rkeIQIECAAAECBAgQIECAAIHBEBDMGYx66ptcTpo0qSw43xPliJ9s0zd5kpHmCOS9lfeYRIAAAQIECBAgQIAAAQIjCwjmjGzjmR4CkydPLo88Pm+5c70v93jWJgIzJ7DsFXtblnzmCL2aAAECBAgQIECAAIEWCJgzpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECBAgQIECAAAECBAi0QEAwpwWVrIgECBAgQIAAAQIECBAgQIBAcwQEc5pTl0pCgAABAgQIECBAgAABAgQItEBAMKcFlayIBAgQIECAAAECBAgQIECAQHMEBHOaU5dKQoAAAQIECBAgQIAAAQIECLRAQDCnBZWsiAQIECBAgAABAgQIECBAgEBzBARzmlOXSkKAAAECHQJPPtXxh4cECBAgQIAAAQIEGiQgmNOgypwdRVlqqaWq08zzxL2z43TO0SKB+j1Vv8daVHRFnQUCCy+8cJlvyoOz4MgO2XaBeZ58qCy88KS2Myg/AQKzUGD+BRcu8z56+yw8g0O3UWDuJ+6rij1pku+wptS/YE5TanI2lWPy5MllyaVXKPM+dN1sOqPTtEVg3oduqN5beY9JBGZWYMkllyxzPXpXmfexu2f2UF5PYJjAPI/cXFZe4Z83NoY94Q8CBAhMkMAyyyxdFrj3wgk6msMQ+KfA/P+6fnva056GpCECgjkNqcjZWYwtNnt2mXznN8u8D/9ldp7WuRousMRfPlfy3pIITITARhttVJZddtmy+B3fmojDOQaBSmDBe39XFrnr9LLWWmsRIUCAwCwT2HyzTavPmll2AgdupcASd3yzbL755mWRRRZpZfmbWOh5m1goZZq1Arvssku59oZby5Srjir3LblDeWKhVctTc88/a0/q6I0UmOupx8q8j9xWFr3zu2XjjTcueW9JBCZK4EMfPKwceNB7yzy3f6E8uMAa5bEFVpioQztOywTme+zOqT1SbygL/f031efU+uuv3zIBxSVAYHYKbL/99uXhhx8up5++d3lgmV3Kkws8vTw57+KzMwvO1RCBuZ96dOqQvdvKYv/4RXnWM1cue+65Z0NKphgRmOv++++fgoLAjAicd9555Wc//0W5+647yxOPPzojh/CalgvMM98CZamlly077bBtdaeg5RyKP4sEvvjFL5Zrr7+p3Pv3v86iMzhs0wUmLbJEWW7ZpcqrX71bWW211ZpeXOWbQYEpU6aUfffdtxx22GFlpZVWmsGjeBmBfwtcdNFF5Uc//mm5++67y2OPPvTvJzwiME6Beeadvyw5eamy2aabuGk6TrNB2k0wZ5BqS14JECBAgAABAgT6UkAwpy+rRaYIECDQWAFz5jS2ahWMAAECBAgQIECAAAECBAgQaKKAYE4Ta1WZCBAgQIAAAQIECBAgQIAAgcYKCOY0tmoVjAABAgQIECBAgAABAgQIEGiigGBOE2tVmQgQIECAAAECBAgQIECAAIHGCgjmNLZqFYwAAQIECBAgQIAAAQIECBBoooBgThNrVZkIECBAgAABAgQIECBAgACBxgoI5jS2ahWMAAECBAgQIECAAAECBAgQaKKAYE4Ta1WZCBAgQIAAAQIECBAgQIAAgcYKCOY0tmoVjAABAgQIECBAgAABAgQIEGiigGBOE2tVmQgQIECAAAECBAgQIECAAIHGCgjmNLZqFYwAAQIECBAgQIAAAQIECBBoooBgThNrVZkIECBAgAABAgQIECBAgACBxgoI5jS2ahWMAAECBAgQIEBgdgrsuOOOs/N0zkWAAAECLRaY6/7775/S4vIrOgECBAgQIECAAAECBAgQIEBgoAT0zBmo6pJZAgQIECBAgAABAgQIECBAoO0CgjltfwcoPwECBAgQIECAAAECBAgQIDBQAoI5A1VdMkuAAAECBAgQIECAAAECBAi0XUAwp+3vAOUnQIAAAQIECBAgQIAAAQIEBkpAMGegqktmCRAgQIAAAQIECBAgQIAAgbYLCOa0/R2g/AQIECBAgAABAgQIECBAgMBACQjmDFR1ySwBAgQIECBAgAABAgQIECDQdgHBnLa/A5SfAAECBAgQIECAAAECBAgQGCgBwZyBqi6ZJUCAAAECBAgQIECAAAECBNouIJjT9neA8hMgQIAAAQIECBAgQIAAAQIDJSCYM1DVJbMECBAgQIAAAQIECBAgQIBA2wUEc9r+DlB+AgQIECBAgAABAgQIECBAYKAEBHMGqrpklgABAgQIECBAgAABAgQIEGi7gGBO298Byk+AAAECBAgQIECAAAECBAgMlIBgzkBVl8wSIECAAAECBAgQIECAAAECbRcQzGn7O0D5CRAgQIAAAQIECBAgQIAAgYESEMwZqOqSWQIECBAgQIAAAQIECBAgQKDtAoI5bX8HKD8BAgQIECBAgAABAgQIECAwUAKCOQNVXTJLgAABAgQIECBAgAABAgQItF1AMKft7wDlJ0CAAAECBAgQIECAAAECBAZKQDBnoKpLZgkQIECAAAECBAgQIECAAIG2CwjmtP0doPwECBAgQIAAAQIECBAgQIDAQAkI5gxUdcksAQIECBAgQIAAAQIECBAg0HYBwZy2vwOUnwABAgQIECBAgAABAgQIEBgoAcGcgaoumSVAgAABAgQIECBAgAABAgTaLiCY0/Z3gPITIECAAAECBAgQIECAAAECAyUgmDNQ1SWzBAgQIECAAAECBAgQIECAQNsFBHPa/g5QfgIECBAgQIAAAQIECBAgQGCgBARzBqq6ZJYAAQIECBAgQIAAAQIECBBou4BgTtvfAcpPgAABAgQIECBAgAABAgQIDJSAYM5AVZfMEiBAgAABAgQIECBAgAABAm0XmGvK1NR2BOUnQIAAAQIECBAgQIAAAQIECAyKgJ45g1JT8kmAAAECBAgQIECAAAECBAgQmCogmONtQIAAAQIECBAgQIAAAQIECBAYIAHBnAGqLFklQIAAAQIECBAgQIAAAQIECAjmeA8QIECAAAECBAgQIECAAAECBAZIQDBngCpLVgkQIECAAAECBAgQIECAAAECgjneAwQIECBAgAABAgQIECBAgACBARIQzBmgypJVAgQIECBAgAABAgQIECBAgIBgjvcAAQIECBAgQIAAAQIECBAgQGCABBodzLn66qvLG9/4xun6Oemkk6rq22GHHcpcc81VcozZmfbbb78qv5dffvmYpz399NOrfT/1qU8N2/e8884re+yxR1l33XXLYostVjbccMPyH//xH+X3v//9sP3G+mNOGYyVr4l6/o477iiHH354+d///d+JOuRsO86VV15ZvT933nnnoXM+/vjj5bOf/WzJ++HRRx8d2j4zD374wx+WD37wg+W2226bmcN4bR8LDPL/g/GyPvHEE+Ub3/hGefvb31623HLL6nNx0003Lfm8Pf7443v+f3nssceq/2MrrbTSeE9T7ffd7363+lyJq0RgVgqcffbZ1Xv0LW95y0yfZkbf7zN94tl8gI985COV2Yknnjibz+x0EbjkkkvKIYccUi666KJW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&quot;&gt;
&lt;p&gt;In garbage collection there is an important term: “The Generational Hypothesis”. This basically states that most objects die young. In other words, most objects are allocated and then almost immediately become unreachable, from the perspective of the GC. This holds not only for V8 or JavaScript, but for most dynamic languages.&lt;/p&gt;
&lt;p&gt;垃圾回收器遵循着一条原则：“代际假设”。基本上来说，假设认为大部分的对象都会在很短的时间内失效。换句话来说，从垃圾回收器的角度来看，大部分对象都是被分配出来，然后基本上马上就不可达了。这条原则不仅仅只针对V8或JavaScript有效，而是对几乎所有的动态语言都有效。&lt;/p&gt;
&lt;p&gt;V8’s generational heap layout is designed to exploit this fact about object lifetimes. The GC is a compacting/moving GC, which means that it copies objects which survive garbage collection. This seems counterintuitive: copying objects is expensive at GC time. But we know that only a very small percentage of objects actually survive a garbage collection, according to the generational hypothesis. By moving only the objects which survive, every other allocation becomes ‘implicit’ garbage. This means that we only pay a cost (for copying) proportional to the number of surviving objects, not the number of allocations.&lt;/p&gt;
&lt;p&gt;V8的代际堆内存布局则是根据这个对象生命周期现状来进行设计。这样设计的垃圾回收器是一种压缩（compacting）/移动（moving）式GC，这意味着这种垃圾回收器会将存活的对象进行拷贝。这有点违反直觉：拷贝对象在垃圾回收时间里是非常昂贵的。但我们知道，根据代际假设，仅仅非常一小部分的对象可以存活过垃圾回收。仅将存活的对象移动，任何其他的分配对象则成为”隐式”垃圾。这意味着我们只需要支付相对于死亡对象数量来说仅只占了一小部分的存活对象的拷贝代价，而不是所有分配出来的对象的数量。&lt;/p&gt;
&lt;h2 id=&quot;minor-gc-scavenger&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#minor-gc-scavenger&quot; aria-label=&quot;minor gc scavenger permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Minor GC (Scavenger)&lt;/h2&gt;
&lt;p&gt;There are two garbage collectors in V8. The &lt;a href=&quot;#ID_MGC_FMC&quot;&gt;Major GC (Mark-Compact)&lt;/a&gt; collects garbage from the whole heap. The &lt;code class=&quot;language-text&quot;&gt;Minor GC (Scavenger)&lt;/code&gt; collects garbage in the young generation. The major GC is effective at collecting garbage from the whole heap, but the generational hypothesis tells us that newly allocated objects are very likely to need garbage collection.&lt;/p&gt;
&lt;p&gt;V8有两种垃圾回收器。&lt;a href=&quot;#ID_MGC_FMC&quot;&gt;Major GC (Mark-Compact)&lt;/a&gt;从整个堆内存回收垃圾。&lt;code class=&quot;language-text&quot;&gt;Minor GC (Scavenger)&lt;/code&gt;仅只从新生代回收垃圾。Major GC的性能在从整个堆内存回收垃圾上已经足够高效，但代际假设告诉我们新分配的内存对象非常值得拥有一个专门的内存回收器。&lt;/p&gt;
&lt;p&gt;In the Scavenger, which only collects within the young generation, surviving objects are always evacuated to a new page. V8 uses a ‘semi-space’ design for the young generation. This means that half of the total space is always empty, to allow for this evacuation step. During a scavenge, this initially-empty area is called ‘To-Space’. The area we copy from is called ‘From-Space’. In the worst case, every object could survive the scavenge and we would need to copy every object.&lt;/p&gt;
&lt;p&gt;Scavenger仅处理新生代的内存，存活对象总是会被直接拷贝到一个新的内存页。V8使用一个被称为”semi-space”的设计来处理新生代内存。这种设计将一半的内存空间置空，在进行拷贝的时候将存活对象直接拷贝到这一半的内存中。在scavenge操作中，这个初始置空的内存空间被称为”To-Space”。我们将对象拷贝出来的被称为”From-Space”。在最糟糕的情况下，每个对象都在scavenge中存活下来了，我们就必须拷贝所有的对象。&lt;/p&gt;
&lt;p&gt;For scavenging, we have an additional set of roots which are the old-to-new references. These are pointers in old-space that refer to objects in the young generation. Rather than tracing the entire heap graph for every scavenge, we use &lt;a href=&quot;https://www.memorymanagement.org/glossary/w.html#term-write-barrier&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;write barriers&lt;/a&gt; to maintain a list of old-to-new references. When combined with the stack and globals, we know every reference into the young generation, without the need to trace through the entire old generation.&lt;/p&gt;
&lt;p&gt;对scavenging来说，我们还有一个额外的根节点集合，它们是老到新引用（old-to-new references）。这些是存在于老生代并指向新生代对象的指针。为了不在每次scavenge中追踪整个堆内存，我们使用了&lt;a href=&quot;https://www.memorymanagement.org/glossary/w.html#term-write-barrier&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;write barriers&lt;/a&gt;来维护一份老到新引用列表。结合栈内存以及全局对象，我们就了解了所有指向新生代的指针了，而不需要过一遍整个老生代。&lt;/p&gt;
&lt;p&gt;The evacuation step moves all surviving objects to a contiguous chunk of memory (within a page). This has the advantage of completing removing fragmentation - gaps left by dead objects. We then switch around the two spaces i.e. To-Space becomes From-Space and vice-versa. Once GC is completed, new allocations happen at the next free address in the From-Space.&lt;/p&gt;
&lt;p&gt;Evacuation步骤会将所有存活对象拷贝到一个连续的内存块中（在一个内存页中）。这样做的优点是完全避免了内存碎片 - 死亡对象遗留下来的内存空隙。然后就可以翻转这两个内存空间（指semi-space设计分隔开来的新生代两块内存空间），举例来说To-Space变成From-Space，反之亦然。当GC完成的时候，新的内存分配行为会在新的From-Space上发生。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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NS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMTM5PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjQyOTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpfzJsMAABAAElEQVR4AeydCbxV4/rHn+qU5jmNiKgITZQmkQZFCElcbrgXGa57b7iGmymJCInCReapTCFEGVNE5RJSZhWleaLxf76v+67/2qu9T/vMe+/zez6fdfZe8/t+1z5rvev3Ps/zllq7du12k4mACIiACIiACIiACIiACIiACIiACIiACKQFgdJpUUoVUgREQAREQAREQAREQAREQAREQAREQAREwBGQmKMfggiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERkJij34AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpBEBiTlpdLFUVBEQAREQAREQAREQAREQAREQAREQARGQmKPfgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERkJij34AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpBEBiTlpdLFUVBEQAREQAREQAREQAREQAREQAREQARGQmKPfgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERkJij34AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpBEBiTlpdLFUVBEQAREQAREQAREQAREQAREQAREQARGQmKPfgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERkJij34AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpBEBiTlpdLFUVBEQAREQAREQAREQAREQAREQAREQARGQmKPfgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERkJij34AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpBEBiTlpdLFUVBEQAREQAREQAREQAREQAREQAREQARGQmKPfgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERkJij34AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpBEBiTlpdLFUVBEQAREQAREQAREQAREQAREQAREQARGQmKPfgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERkJij34AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpBEBiTlpdLFUVBEQAREQAREQAREQAREQAREQAREQARGQmKPfgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikEQGJOWl0sVRUERABERABERABERABERABERABERABEZCYo9+ACIiACIiACIiACIiACIiACIiACIiACKQRAYk5aXSxVFQREAEREAEREAEREAEREAEREAEREAERyBICERABEcgNgSlTptjvv/9uHTt2tFq1aiXc9e2337Y1a9bY/vvvb3vuuWfC7TJ5xerVq+2DDz6wX375xVasWGGVK1e2hg0bOiaNGjXK5KoXSN3efPNN27p1qx1xxBFWqlSpAjmmDiICIiACIiAC6UKAZ+C8efNs/vz5rh2xadMmq169ujVo0MDatWtnVapUiVsV2h0ffvihNW7c2A444IC428Rb+Morr7jFvXv3jrc64bK1a9e68y1evNiVs1KlSq6MLVq0sD322CPhflphrp0zbdo0K1eunHXt2lVIRCBXBCTm5AqXNhYBEeBhM3HiRPv+++/tggsuiAvkiy++sMcee8yqVq1qPXv2jLtNJi/cuHGjPfroo/bRRx/Z9u3bd6jqs88+a7vttpudcsop1qRJkx3Wl5QFNFIXLlxou+yyi2twhuv9zTff2BNPPOEWIXw1b948vFrfRUAEREAERCCjCdCGePLJJ13HWLyKTpgwwdq3b+/aEjxHw/bzzz/biy++aF26dMmVmPPyyy+7zpNkxRzEpccff9xmzpxp27ZtCxfBfX/++eddJ9bJJ59szZo122F9SVlAW/Crr75ygk20g/Pzzz83riW21157ufZhSeGieuafgMSc/DPUEUSgRBGg1+C9996z//73v/bpp5/u0EjgBf2RRx5xTBArog2MTIf166+/2qhRo2z58uVWunRp13N22GGHuR6qDRs22I8//miffPKJTZ8+3W655Rb729/+Zvvuu2+mY4lbv/Xr1ztWeCtdffXVMdvUqVPH6NmjAVS3bt2YdZoRAREQAREQgUwmQDvq3XffdVXEu+aoo46y3Xff3SpWrGhLlixx695//32bMWOGEwmGDBlitWvXLlIkK1eudM/wpUuXOgGobdu21q1bN6MD5rfffrMffvjBtROpx6233mqDBw+2Vq1aFWkZU+VkmzdvdqzwaB8xYkRMsfCyoqOUKSeP95idNCMC/yMgMUc/BREQgVwRINzlzDPPtGHDhjnvGz7Lli0bHOO1114zBA1ca9u0aRMsLwlfELLGjRvnhJwaNWrY2WefHeN5U6FCBfegpjFz4IEHGm61JdkzJ6ffBK7jt912W06b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IAIiIAIiIAIiIAKpQEBiTipcBZVBBESg2AgQF41nDkIOoykxhY3QKxL4+jwu4XX6LgIiIAIiIAIiIAIiIAIiIALFQUBiTnFQ1zlFQARSigCJhRn6kWE5GUaTEadIoEciOpLokSBZJgIiIAIiIAIiIAIiIAIiIAKpQkBiTqpcCZVDBESgWAkwIgAjWjHJREAEREAEREAEREAEREAERCCVCSgBcipfHZVNBERABERABERABERABERABERABERABCIEJOZEgGhWBERABERABERABERABERABERABERABFKZgMScVL46KpsIiIAIiIAIiIAIiIAIiIAIiIAIiIAIRAhIzIkA0awIiIAIiIAIiIAIiIAIiIAIiIAIiIAIpDIBiTmpfHVUNhEQAREQAREQAREQAREQAREQAREQARGIEJCYEwGiWREQAREQAREQAREQAREQAREQAREQARFIZQISc1L56qhsIiACIiACIiACIiACIiACIiACIiACIhAhIDEnAkSzIiACIiACIiACIiACIiACIiACIiACIpDKBCTmpPLVUdlEQAREQAREQAREQAREQAREQAREQAREIEJAYk4EiGZFQAREQAREQAREQAREQAREQAREQAREIJUJSMxJ5aujsomACIiACIiACIiACIiACIiACIiACIhAhIDEnAgQzYqACIiACIiACIiACIiACIiACIiACIhAKhOQmJPKV0dlEwEREAEREAEREAEREAEREAEREAEREIEIAYk5ESCaFQEREAEREAEREAEREAEREAEREAEREIFUJiAxJ5WvjsomAiIgAiIgAiIgAiIgAiIgAiIgAiIgAhECEnMiQDQrAiIgAiIgAiIgAiIgAiIgAiIgAiIgAqlMQGJOKl8dlU0EREAEREAEREAEREAEREAEREAEREAEIgQk5kSAaFYEREAEREAEREAEREAEREAEREAEREAEUpmAxJxUvjoqmwiIgAiIgAiIgAiIgAiIgAiIgAiIgAhECEjMiQDRrAiIgAiIgAiIgAiIgAiIgAiIgAiIgAikMgGJOal8dVQ2ERABERABERABERABERABERABERABEYgQkJgTAaJZERABERABERABERABERABERABERABEUhlAhJzUvnqqGwiIAIiIAIiIAIiIAIiIAIiIAIiIAIiECEgMScCRLMiIAIiIAIiIAIiIAIiIAIiIAIiIAIikMoEJOak8tVR2URABERABERABERABERABERABERABEQgQkBiTgSIZkVABERABERABERABERABERABERABEQglQlkpXLhVLb0ILB48WJbu3ZtTGEbNmxolStXdsu2bNliX3/9dcz6qlWrWv369YNlP/74o23YsCGY50uzZs2C+VWrVtkvv/wSzPOF/TkOtnXrVlu4cKH77v9wfsrh7aeffrL169f7Wfe5zz77WOnSf2iaa9assSVLlsSsr1evnlWrVs0t2759u3311Vcx6ytWrGi77bZbsCwei7333tvKlCnjtoET24Rt1113tRo1agSLOAfn8la+fHnbY489/KwrI2UN21577WVly5Z1i6gjdQ1b7dq1rVatWsGiBQsW2LZt24L5XXbZxRo3bhzMwxrmYWM922EbN260H374IbzaoufgmnPtvUXP4ZfrUwSKggC/d36T4d99qVKlrGnTpsHpV65caUuXLg3m+dKgQQOrUqWKWxbvXsY6tvEW717GOTgXtnr1avv555/95u4zfC+jfPx/hi16L1u0aJGtW7cuvInt7F5Wt25dq169utsnr/eyJk2aWFbWH82GZO5l0ftM9F4GB3iELbf3Mu773P+9Re8z8e5le+65p5UrV87tksy9zB9bnyIgAiIgAiIgAiKQSgQk5qTS1UjDsmzevNmuueaaHUo+ePBga926tVvOS8eoUaNitmnbtq2dc845wbInn3xyhxeYu+++OxBaPvnkE3vssceC7fly5pln2iGHHOKWbdq0aYdzHHDAAXbhhRcG+zzzzDM2b968YJ4vd9xxh/GCgX322Wf24IMPuu/+z2mnnWZdunRxs7zIReuB4DRkyBC/ub3wwgs2Z86cYJ4vt9xySyA6zZ8/3+69996Y9QMGDLAjjjgiWMY5wmIOLx6XX355sH7y5Mn2wQcfBPN8GTFiRCDWfPPNNzZmzJiY9f369bPevXsHy0aPHm0w89aoUSO76qqr/Ky99tpr9t577wXzfLn22msDAe7777+3W2+9NWb9UUcdZccee2ywbOzYsTEiX506dWz48OHBen0RgaIkwP/M+PHjY06JkMt9xttHH31kEyZM8LPuk/sU9ysMoTR6D+A+x/3O29NPP238n4dt3LhxgaDLvezRRx8Nr7YzzjjDOnTo4JYlcy979tln7dNPP405Bv/TFSpUcMu4z0Xreuqpp1rXrl3degSjaD0QnC6++OLgmJMmTbLZs2cH83y5+eabA3Eb0fmee+6JWd+/f3/r0aNHsIx7RFhoQRC+4oorgvXcy2bOnBnM8+WGG25wwjDf493LjjvuOOvTpw+rnVHv33//3c86Af/qq68O5qdMmWLvvvtuMM8X1nuhH1E6yoLjcx6ZCIiACIiACIiACKQygVLZvWvbU7mAKltqE+DF44ILLrBhw4YZPb8yEdgZAXr0eQnkd+OFtJ3to/UikF8C06dPt2nTptnQoUPzeyjtX0IIzJo1y7777jtDpJKJwM4I0AmD+Ms9Juyxu7P9tF4EREAEREAE8kpAOXPySk77iYAI5IkAAiC9+uEe+zwdSDuJgAiIQCESIOwuGrJaiKfToUVABERABERABEQgVwQk5uQKlzYWAREQAREQAREQAREQAREQAREQAREQgeIloJw5xcs/7c9O0l1yxoQT+KZ9pVQBERCBjCOw//77B3lSMq5yqpAIiIAIiIAIiIAIiECJIyAxp8Rd8oKtMCO0hEedKtij62giIAIiUDAEGJXOj0xXMEfUUURABERABERABERABESg+AhIzCk+9jqzCJRIAgyRHh3Rq0SCUKVFQARSmkDPnj2NSSYCIiACIiACIiACqUhAOXNS8aqkUZkYvYFheMPDXKdR8VVUERCBEkJg9erVbmSiElJdVVMEREAEREAEREAERCDDCUjMyfALXNjV27x5s40aNcoY9UMmAiIgAqlK4LPPPrNHHnkkVYuncomACIiACIiACIiACIhArggozCpXuLRxYRLAu+e1115LeIpddtklrV3ef//9d1u4cKH98MMPVrp0aevSpYtVrFgxYX0zdcXGjRvtjTfesF69elm5cuUytZqqlwg4Ap9++ulOPYLq1KljhxxySKERwyvp66+/tsWLF7tk9ZyrTJkyhXa+TDkwzJYuXWodOnTIlCqpHiIgAiIgAiIgAhlEQGJOBl3MdK8KYseLL76YsBokL03X/AXTp0+3J554IiYc7ZVXXrGBAwda+/btE9Y5E1ds2LDBXedu3bpJzMnEC6w6xRDAI+jNN9+MWRadadGiRaGIOYTBPvroo/buu+/GnHLKlCn2l7/8xXbbbbeY5ZqJJYCYM2/ePIk5sVg0JwIiIAIiIAIikCIEJOakyIVQMf6fQKtWreyII474/wX/+8Yw6Olo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hMOo+vbta0zeCjpp/ebNm23BggW2detW27RpkzG/ZcsW27hxo/u+Zs0aq+JPrk8R+B+BxauqWa3sYcVLl9q2A5MG1dfY1m2lbenayla/2uod1muBCIiACIiACIiACKQagbQXczxQRJ1jjz028NR55JFHAk+d9u3b+830KQIiIAIiUMAELrroInfEogqjysrKsttvv92ds0yZMla6dGnbvn27E3RYSD41W+dW648IBAR2rbLOlq+raJu3ZlnZMluC5Xz5JTuXTinbbmwjEwEREAEREAEREIF0IFA6HQqZmzIyQsoxxxxjI0eOtAMPPNAee+wxGz58uM2cOTM3h9G2IiACIiACcQgQRkUenLBdfPHFNnr0aBswYIAbnSq8rjC+l8pOXIL3JSIO3jl45mB77LGH3XHHHYbAIxOBKIFGNVc5z5wnPmydLf7FJr+ZNLeFtW28WCFWUWiaFwEREAEREAERSFkCGeOZEyVcvnx55+ZPg5/wqyeeeMKFX3Xv3t06dOgQ3VzzIiACIiACORAIh1G1bNnSzj///GBr8uIUtSHcb9v2R7gMok6zZs3svPPOs7JlyxZ1UXS+NCGQlT30+D97vms3vHy4fb54V2u52xIrX3aLfbushq3eWN7+1futNKmJiikCIiACIiACIiACZhkr5viLi6hz9NFHB+FXTz/9dCDq+KFx/bb6FAEREAER2JHAsGHD7Ndff3XDiRfHaFR4A02dOtWOOOKIILEy9/VPPvnEvv/+ezvooIPsrLPOMjx2ZCKQEwHy4Qw//lWb/N997cfshMgVy26y/RostR77zc/2ytkxl05Ox9I6ERABERABERABEShOAhkv5ni45cqVs6OOOsq55vNSMGHChCBRskQdT0mfIiACJZ0ASYTnz59v4aTFgwYNKpLwqSh7vIFmzJjhytO0aVPbsGFDIOawLYIOIV98ykQgWQJVy/+WPXrVnGQ313YiIAIiIAIiIAIikJIESoyY4+kj6vTu3dsNYU741TPPPBMkSu7cubPfTJ8iIAIiUKII4OUyffp0mzt3rhNuwmJOcYRRIdK8+OKLTlRCTPJDnYcvCuFeTDIREAEREAEREAEREAERKGkESpyY4y8weRUQdXr27Ok8dJ5//vnAU0eijqekTxEQgZJA4MEHH7Q5c+ZY69atrTjCqPAG4vwINuS+wRCQRowYkSf8hGUt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pXbt2kHYVKdOnQwBN5M8cKIXGK+jp556ynk+ZapYFa2z5kVABERABERABERABEQgPwQk5uSHXorsS/4MRJ1PP/3UxowZY6+//rpLkkyi5Jo1a6ZIKVUMEUgdAniBMBpVo0aNnLeLL1lxhVER2kWZmBBzhgwZEninkAsnE/PheOZ4GOIRFa6zX6dPERABERABERABERABERCB+ASyzj77bLemf//+1qBBAzfVqFEj/tZamtIEDjjggBhRh/AMQq8QdTK5Vz+lL4oKl1IExo8fHxNGxf9Gcdv8+fNt1KhR7n+U/1eG4c5k8SbKGw/DcA6g6HrNi4AIiIAIiIAIiIAIiIAI7Egga+DAgfbEE0/YhAkTdlh7+OGHBwJPw4YN3TCxO2ykBSlHICrqEMLQrVs3F34lUSflLpcKVIQECF8q7tGoyM3DkNtesCEvT0n3StF9qQj/CXQqERABERABERABERCBjCCQhWDD5I0XjcWLF9uSJUts4sSJfnHMJ0NiI+54T56yZcvGrNdMahDwos68efNs9OjRNm3aNHetyanDS61MBDKVAOFKhO9wPxs6dGhQTYbxLi4jtxWjUVEuyhEuSyokWi4qLoSR3XLLLXbeeecFoWRFdW6dRwREQAREQAREQAREQAQyhcAOOXPoIWVCCEC08fbzzz87kWfRokX24osv+sXBZ9u2bQNxB5Gnfv36wTp9KV4CLVq0cOFXn3/+ud1+++325ptvugINHz7c6tSpk+vC1fj25lzvox1EoCgIkEQXIQcjke6AAQOK4rQ5noN8ONddd51t2LDBJTJGXGKY85JoCFmEupHQuSQJWCXxWqvOIiACIiACIiACIiAChUtgBzEn0enq1atnTG3atAl6lLds2WKIO3jyMMUTeTp06BAj8sidPhHhwl++3377OVHniy++sNtuu82uvPJKd9Jhw4ZZ3bp1ky7AiftMSnpbbSgCyRKYNLd5spsG2yGU+HAlFiKSFHcYFeXAI8jf6ygfohK5YUqyIbIx9DhJpjViVUn+JajuIiACIiACIiACIiACBUEgaTEn3smysrJsjz3+r707gZeqvO8//lxWAQHZBGQRUREiRnCJCiavqESNEeISQatVTENooUnaSLO1qG0al4hpTaImNhHatFFpbBLQRGv2BGI0BE2wihsqCpFFxSuyyvyf7xN/539m7szcOXNn5p6Z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9u0LrYjWr19f1UOtXbs2tDx64403qnqcamSuLxLUKkfpBz/4gVOAUT/9+/cPy/iFAAIIIIBAuQK0zClXjv0QQKCmAkOGDGlzvMGDB4dlAwYMqLuuFG0qwwIEEKiIgLoaqVulul6pu2UzpHe+850hQKDA9wEHHNAMVa6bOupabG1tdcccc4x7//vfXzflpqAIIIAAAukXIJiT/nNECRFAoEICzz77rPvhD38YWu1onI0TTjjBzZw50+kGKDc9/fTT7n//93/dqlWrnMafmDRpknvve9+beNwddQv47//+b/fwww+H1kMKSk2cONH92Z/9mVMQKjdp7Ivly5eHsRWeeeYZN3LkyHATcMEFF4Ry5G6vVhLqYrFu3TqncRnGjRvnpk6d6qZNmxZt+p//+Z9hPJEZM2a4gQMHRsvtyT333OO2bNniTjnlFHfwwQeHxfo2WctVf1mMHz8+GJx11lmue/futqvbsGFDcNJxjz322OD785//3L366qthnwsvvNCN8d0+cpNadqiecnnuuefccccd50499dTQkkJdNuR2ySWXhDFAbF/lqTL99re/Dfmr1YXO4cknn2ybhEeNlSIXnS99+63xU3Tedc4///nPl/SNeCnH+tGPfuRefPFFd/zxx7sjjzwyqwx6oXKuWbMmdEdSOZVU7x//+MfuJz/5iVNrhv322y+cs7PPPjtvHtpHefzsZz8L50KvDz30UKfrIT4GlJ0HtUh5z3veo82y0oMPPhgCHO973/uyAhyllsdaFqi+St/5zndC/RQ40XmyVOp1o+3VRUcOGtNK12+vXr2Chd6THW1d8qtf/co9//zzobuRWupU8z1gdW/vUe9nXTOPPPKI0/tcnyl6zykQUyipK4yuFxnpPaH3yQc+8IG8wWu9N3Q+LrroojbZqaXiL3/5y/C+GD58eDj2mWee6SwgnrtDe9fcH//4R3ffffc5tcxRUrDCrpFRo0a50047LSxP+vkXdor9evTRR8NnoQIiSnq04+S+71577bXw+SDfjRs3OrVW0jYaGyZpKvV9UShfXdv//u//HlbrOlRScNHKrve9Phvvvfdepy5ks2bNCmW295UCP5/5zGfCfvqV5O+RPst1vT/++ONu69atbvTo0e5d73qX+9CHPpT1eRpl7p8k+dsY38+eqx5qbaRr76mnngrva33mKJiqvwv625NvfKBy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&quot;&gt;
&lt;p&gt;We quickly run out of space in the young generation with this strategy alone. Objects that survive a second GC are evacuated into the old generation, rather than To-Space.&lt;/p&gt;
&lt;p&gt;当使用这个策略之后，我们很快就会在新生代耗尽内存。存活过两次GC的对象将会被清理到老生代，而不是To-Space。&lt;/p&gt;
&lt;p&gt;The final step of scavenging is to update the pointers that reference the original objects, which have been moved. Every copied object leaves a forwarding-address which is used to update the original pointer to point to the new location.&lt;/p&gt;
&lt;p&gt;Scavenging的最后一步是更新指向已经被移走的对象的指针。每一个被拷贝的对象都会留下一个forwarding-address，用来将老的指针更新成新的。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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NS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMTQxPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjQzMTwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpr1pfuAABAAElEQVR4AeydB7gURdaGDxmJiuSgKCAKiAFBUAkqSDKhmNaE+q/omta4a0BxDZgw513XnDNiRBFUREEMCCISxEBWchBJ/33Lrbammbkz93KBO3O/8zwz091VXeHtnurqU6dOlVq6dOl6k4iACIiACIiACIiACIiACIiACIiACIiACGQVgdJZVVoVVgREQAREQAREQAREQAREQAREQAREQAREwBGQUkc3ggiIgAiIgAiIgAiIgAiIgAiIgAiIgAhkIQEpdbLwoqnIIiACIiACIiACIiACIiACIiACIiACIiClju4BERABERABERABERABERABERABERABEchCAlLqZOFFU5FFQAREQAREQAREQAREQAREQAREQAREQEod3QMiIAIiIAIiIAIiIAIiIAIiIAIiIAIikIUEpNTJwoumIouACIiACIiACIiACIiACIiACIiACIiAlDq6B0RABERABERABERABERABERABERABEQgCwlIqZOFF01FFgEREAEREAEREAEREAEREAEREAEREAEpdXQPiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEAWEpBSJwsvmoosAiIgAiIgAiIgAiIgAiIgAiIgAiIgAlLq6B4QAREQAREQAREQAREQAREQAREQAREQgSwkIKVOFl40FVkEREAEREAEREAEREAEREAEREAEREAEpNTRPSACIiACIiACIiACIiACIiACIiACIiACWUhASp0svGgqsgiIgAiIgAiIgAiIgAiIgAiIgAiIgAhIqaN7QAREQAREQAREQAREQAREQAREQAREQASykICUOll40VRkERABERABERABERABERABERABERABEZBSR/eACIiACIiACIiACIiACIiACIiACIiACGQhASl1svCiqcgiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIKWO7gEREAEREAEREAEREAEREAEREAEREAERyEICUupk4UVTkUVABERABERABERABERABERABERABERASh3dAyIgAiIgAiIgAiIgAiIgAiIgAiIgAiKQhQSk1MnCi6Yii4AIiIAIiIAIiIAIiIAIiIAIiIAIiICUOroHREAEREAEREAEREAEREAEREAEREAERCALCUipk4UXTUUWAREQAREQAREQAREQAREQAREQAREQASl1dA+IgAiIgAiIgAiIgAiIgAiIgAiIgAiIQBYSkFInCy+aiiwCIiACIiACIiACIiACIiACIiACIiACUuroHhABERABERABERABERABERABERABERCBLCQgpU4WXjQVWQREQAREQAREQAREQAREQAREQAREQASk1NE9IAIiIAIiIAIiIAIiIAIiIAIiIAIiIAJZSEBKnSy8aCqyCIiACIiACIiACIiACIiACIiACIiACEipo3tABERABERABERABERABERABERABERABLKQgJQ6WXjRVGQREAEREAEREAEREAEREAEREAEREAERkFJH94AIiIAIiIAIiIAIiIAIiIAIiIAIiIAIZCEBKXWy8KKpyCIgAiIgAiIgAiIgAiIgAiIgAiIgAiIgpY7uAREQAREQAREQAREQAREQAREQAREQARHIQgJS6mThRVORRUAEREAEREAEREAEREAEREAEREAEREBKHd0DIiACIiACIiACIiACIiACIiACIiACIpCFBKTUycKLpiKLgAiIgAiIgAiIgAiIgAiIgAiIgAiIgJQ6ugdEQAREQAREQAREQAREQAREQAREQAREIAsJSKmThRdNRRYBERABERABERABERABERABERABERABKXV0D4iACIiACIiACIiACIiACIiACIiACIhAFhKQUicLL5qKLAIiIAIiIAIiIAIiIAIiIAIiIAIiIAJS6ugeEAEREAEREAEREAEREAEREAEREAEREIEsJCClThZeNBVZBERABERABERABERABERABERABERABKTU0T0gAiIgAiIgAiIgAiIgAiIgAiIgAiIgAllIQEqdLLxoKrIIiIAIiIAIiIAIiIAIiIAIiIAIiIAISKmje0AEREAEREAEREAEREAEREAEREAEREAEspBA2Swss4osAiKwhQi88847tmrVKttnn31s2223TVmKESNG2NKlS61Vq1a2ww47pIyXywGLFy+2Tz/91ObOnWsLFiywKlWqWIMGDRyThg0b5nLVi6Ru77//vq1du9YOPPBAK1WqVJGkqUREQAREQAREIFsI8AycOHGiTZ482fUjfv/9d9t6662tfv361q5dO6tatWrSqtDvGDNmjDVu3Nh23XXXpHGSHXzzzTfd4Z49eyYLTnmM/h75zZo1y5WzcuXKrowtW7a07bffPuV5CjDXzxk+fLiVL1/eOnfuLCQiUGgCUuoUGp1OFIGSR4CHzgsvvGDfffedXXjhhUkB0AF56qmnrFq1anbQQQcljZPLB1euXGlPPPGEffbZZ7Z+/foNqvrSSy9Zo0aN7C9/+Ys1adJkg/CScoDO6tSpU61ChQqu4xnWe/r06fb000+7QyjAdt555zBY2yIgAiIgAiKQ0wToQzzzzDO2ZMmSpPV8/vnnbe+993Z9CZ6jocyZM8dee+0169ixY4GUOq+//robRMlUqYOSif7eJ598YuvWrQuL4LZfeeUVN5h17LHHWvPmzTcILykH6AvSb6YPHR/o/Oabb4xriey4446uf1hSuKieRUtASp2i5anURCCnCTCK8NFHH7lRo7Fjx1rbtm0T6ssD/rHHHnPHUFrEOxoJkXNw55dffrHBgwfbr7/+aqVLl3YjaV26dHEjVitWrLCffvrJvvrqKxs1apTdcsstdu6559ouu+ySgyTSV2n58uWOFdZLV111VcIJtWrVMkb66AjVqVMnIUw7IiACIiACIpDLBB5//HH78MMPXRWxtundu7dtt912VqlSJZs9e7YL+/jjj2306NHRIFvNmjU3K5KFCxe6Z/i8efOcIqhNmzZ2wAEHGAMxv/32m/3444/29ddfu7LeeuutduaZZ9ruu+++WctYXDJbvXq1Y4WF+6BBgxKKhdUVyh4++VnAJ5ykHRFIQkBKnSRQdEgERCA5AabBnHrqqXbNNdfYc889Z61bt05Q3AwZMsR40GNyu+eeeyZPJEePYnly3333OYXONtts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REAEREAEREAEREAERKC4EZBPneJ2RVQeERCBzUaAOcvvvvuuczh31113OVNnzIlx9ovChznTTBFiLrhEBERABERABERABERABERABIobASl1itsVUXlEQAQ2GwGmXeHAmaU8Wflh0qRJCXk3znNUiOO7+LzlhEjaEQEREAEREAEREAEREAEREIEtREBKnS0EXtmKgAgUDwKsWIDjYpb7nD59uv36669uZSgc1OXnzLh4lF6lEAEREAEREAEREAEREAERKMkEpNQpyVdfdRcBEYgIsIIBH4kIiIAIiIAIiIAIiIAIiIAIZAsBOUrOliulcoqACIiACIiACIiACIiACIiACIiACIhAQEBKnQCGNkVABERABERABERABERABERABERABEQgWwhIqZMtV0rlFAEREAEREAEREAEREAEREAEREAEREIGAgJQ6AQxtioAIiIAIiIAIiIAIiIAIiIAIiIAIiEC2EJBSJ1uulMopAiIgAiIgAiIgAiIgAiIgAiIgAiIgAgEBKXUCGNoUAREQAREQAREQAREQAREQAREQAREQgWwhIKVOtlwplVMEREAEREAEREAEREAEREAEREAEREAEAgJS6gQwtCkCIiACIiACIiACIiACIiACIiACIiAC2UJASp1suVIqpwiIgAiIgAiIgAiIgAiIgAiIgAiIgAgEBKTUCWBoUwREQAREQAREQAREQAREQAREQAREQASyhYCUOtlypVROERABERABERABERABERABERABERABEQgISKkTwNCmCIiACIiACIiACIiACIiACIiACIiACGQLASl1suVKqZwiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEBCQUieAoU0REAEREAEREAEREAEREAEREAEREAERyBYCUupky5VSOUVABERABERABERABERABERABERABEQgICClTgBDmyIgAiIgAiIgAiIgAiIgAiIgAiIgAiKQLQSk1MmWK6VyioAIiIAIiIAIiIAIiIAIiIAIiIAIiEBAQEqdAIY2RUAEREAEREAEREAEREAEREAEREAERCBbCEipky1XSuUUAREQAREQAREQAREQAREQAREQAREQgYCAlDoBDG2KgAiIgAiIgAiIgAiIgAiIgAiIgAiIQLYQkFInW66UyikCIiACIiACIiACIiACIiACIiACIiACAQEpdQIY2hQBERABERABERABERABERABERABERCBbCEgpU62XCmVUwREQAREQAREQAREQAREQAREQAREQAQCAlLqBDC0KQIiIAIiIAIiIAIiIAIiIAIiIAIiIALZQkBKnWy5UiqnCIiACIiACIiACIiACIiACIiACIiACAQEpNQJYGhTBERABERABERABERABERABERABERABLKFQNlsKajKWTwJzJo1y5YuXZpQuAYNGliVKlXcsTVr1ti0adMSwqtVq2b16tWLjv3000+2YsWKaJ+N5s2bR/uLFi2yuXPnRvtscD7pIGvXrrWpU6e6bf9F/pTDy88//2zLly/3u+63WbNmVrr0H3rNJUuW2OzZsxPC69ata9WrV3fH1q9fb999911CeKVKlaxRo0bRsWQsmjZtamXKlHFx4EScUGrXrm3bbLNNdIg8yMtLxYoVbfvtt/e7royUNZQdd9zRypUr5w5RR+oaSs2aNW3bbbeNDk2ZMsXWrVsX7VeoUMEaN24c7cMa5qEQTjxk5cqV9uOPP4bBFs+Da8619xLPwx/XrwhsDgLc79yT4X1fqlQp22mnnaLsFy5caPPmzYv22ahfv75VrVrVHUvWlhFGHC/J2jLyIC9k8eLFNmfOHB/d/YZtGeXj/xlKvC2bOXOmLVu2LIxi6dqyOnXq2NZbb+3OKWxb1qRJEytb9o8uQyZtWbydibdlcIBHKAVty2j3af+9xNuZZG3ZDjvsYOXLl3enZNKW+bT1KwIiIAIiIAIiIALFlYCUOsX1ymRBuVavXm0DBw7coKRnnnmm7bHHHu44Lx+DBw9OiNOmTRvr379/dOyZZ57Z4EXm/vvvjxQuX331lT355JNRfDZOPfVUa9++vTv2+++/b5DHrrvuauecc050zosvvmgTJ06M9tm48847jRcNZMKECfbII4+4bf914oknWseOHd0uL3TxeqB4uvDCC310e/XVV+2LL76I9tm45ZZbIuXT5MmT7cEHH0wIP+aYY+zAAw+MjpFHqNThBeTSSy+Nwt944w379NNPo302Bg0aFCltpk+fbnfddVdCeJ8+faxnz57RsTvuuMNg5qVhw4Z25ZVX+l17++237aOPPor22bj66qsjRdwPP/xgt956a0J479697bDDDouO3XvvvQnKvlq1atl1110XhWtDBDYnAf4zDz/8cEKWKHRpZ7x89tln9vzzz/td90s7RXuFoDCNtwG0c7R3Xp577jnjfx7KfffdFyl2acueeOKJMNhOOeUU69ChgzuWSVv20ksv2ddff52QBv/prbbayh2jnYvX9fjjj7fOnTu7cBRH8XqgeLrooouiNIcMGWKff/55tM/GzTffHCm5UT4/8MADCeFHHXWUdevWLTpGGxEqXFAMX3bZZVE4bdknn3wS7bNx/fXXOwUx28nassMPP9x69epFsBPqvWrVKr/rFPlXXXVVtP/OO+/Yhx9+GO2zQbhX+KOcjrMgffKRiIAIiIAIiIAIiEC2ECiVN+K2PlsKq3IWLwK8gJx99tl2zTXXGCPBEhFIR4ARfl4GuW+8Qi3dOQoXgY0lMGrUKBs+fLgNGDBgY5PS+SWEwNixY23GjBmGskoiAukIMBiDEpg2JrTgTXeewkVABERABESgKAjIp05RUFQaIiACGRFAEcgofziCn9GJiiQCIiACm5EA0/HiU1k3Y/bKSgREQAREQAREQAQyJiClTsaoFFEEREAEREAEREAEREAEREAEREAEREAEig8B+dQpPtci60qCc158yoSOfrOuEiqwCIhAzhNo1apV5Ecl5yurCoqACIiACIiACIiACJQoAlLqlKjLXbSVZUWXcJWqok1dqYmACIhA0RBgFTu/kl3RpKhUREAEREAEREAEREAERKB4EJBSp3hcB5VCBEoEAZZWj68AViIqrkqKgAhkFYGDDjrI+EhEQAREQAREQAREoLgTkE+d4n6FinH5WO2B5XvD5bGLcXFVNBEQgRJKYPHixW4loxJafVVbBERABERABERABEQghwlIqZPDF3dTV2316tU2ePBgY5UQiQiIgAgUVwITJkywxx9/vLgWT+USAREQAREQAREQAREQgUIT0PSrQqPTiUVJAGuft99+O2WSFSpUyGpT+FWrVtnUqVPtxx9/tNKlS1vHjh2tUqVKKeubqwErV660d99917p3727ly5fP1WqqXiLgCHz99ddpLYRq1apl7du332TEsFKaNm2azZo1yzm1J68yZcpssvxyJWGYzZs3zzp06JArVVI9REAEREAEREAEcpSAlDo5emGzrVooPV577bWUxcbJabb6Nxg1apQ9/fTTCdPU3nzzTTvuuONs7733TlnnXAxYsWKFu84HHHCAlDq5eIFVpwQCWAi9//77CcfiOy1bttwkSh2mxz7xxBP24YcfJmT5zjvv2P/93/9Zo0aNEo5rJ5EASp2JEydKqZOIRXsiIAIiIAIiIALFkICUOsXwopTkIu2+++524IEHboCA5dOzUaZPn26PPfaY7bbbbtajRw/bfvvtjZHz//73v/bQQw8Z9dpzzz2zsWoqswiIQBoCXbt2Tfh/P/PMM2666plnnhmdWbly5Wi7KDdQ3qDQOfjgg61t27ZWr149++6771y7c+ONN9rVV19tOC6XiIAIiIAIiIAIiIAIZDcBKXWy+/pt0dJjwn/IIYdYlSpViqwcW2+9dU4tkz569GgrW7asGxn3041q1KhhZ599tvGCR30lIiACm5YAVimdOnXatJkkSZ2pVXy8bLXVVrZkyZLN0sZ99NFHLp9DDz3UZ2877bSTnX766fbFF19Ex7QhAiIgAiIgAiIgAiKQ3QSk1Mnu67dFS++VOpuzEHPnzrUxY8bYHnvsYThqHjp0qJvWxItLs2bNXFGY4oPflq+++sqIzwg1ljL777+/haPiTIGqWLGidenSxcaNG2f4v1iwYIGF1kJTpkxx6cyePdsaNGjgRr29ciaTepcqVcrWrVtnTIUIhXz79esXHrK33nrL6tevbzvvvLN9/vnnRt7Lly+3Fi1auGla+BUKZe3ata7M+OqhfCiIiNumTZswmtsmLty+/fZblyYWQ/vss0/SkXpG8+Hxyy+/OHb77ruv+90gUR0QgSwhsN122xmfbJCPP/7YUAbPmDHDKcybN29u3bp1c+1PUZS/SZMmxsfLokWLnEUPFoP4+eK/T9vDNm1h69atjXYsFJzj075+//33Rntbt25d69y5s9WsWTOM5raxTETBRH1of2mn27Vr56wUw8i+jWJFRdLcYYcdbL/99rOqVauG0bQtAiIgAiIgAiIgAiIQI1DmsssuGxg7pl0R2OwEcJTMdIHGjRvbrrvumjJ//BzgJwJnw0899ZQx8u0VN5zLy8BNN93kXkxQcvCSgfJn7NixTqnhX1zI4M4777Q5c+bYN998Y59++qnh14eXFPxgIChU7rrrLvdCM3PmTBePuChDyD8T+e233+yzzz5z0x54kcrvBYXyrFmzxl599VVXVqZmobBBwfPJJ584ZQ++hRAcDg8aNMiGDx/uys0LEf4fqOfPP//splv48lHHm2++2aWJwgilFPHeeOMN5zg1fNnF9w9cOYcXMBw7ozhDeLncWOHlkHphMSBnrRtLU+dnGwH8a9Gu4Cg8mfD/e+WVV1wQymiUv7Q5I0eOtDp16hRIsUM7gEUOlkG0PamU0fzXmQqK0vjhhx+2n376ybV5tCe0iyh5UaL7KbAoc2hPKBfHUIRzbMSIEU5xRjm9MP3rjjvucHVGmYPjYXwMobhC0e6V7LS9t9xyiwujDaR9RbmEch4rqzBNn/bm+N1mm23ke2hzgM6RPHhWotz0z+kcqZaqIQIiIAIikAUEZKmTBRepJBWRUWNGauPSsGHD6AWAMF4McDSM9Q1WMChzEF5OsFq58MILE5QQvBQ9+eSTzr/N+eef7+LyxQsNHTD8S/DSw7m8sNA544XltNNOc6PK5PHSSy+5Fbp40UGxk4ngy4KXI15iBg4c6BQzKJY4378khelgTcPL3FVXXeWmbfjRa8qOH54rr7zSvXChHKlWrZphocQLF8LLInF4kUMx1apVK2fFxEsVEvrQOPbYY93LFgoyHLWiAOMFjBH1c8891x3zo/P//ve/nXPjdAo3l0maL5RwTNmTiIAIJBLg/0e7hh+eo446KrKOmT9/vl177bWu7UKxyv8+E+nbt6/98MMPTiGE5Q9KFCxk+E0mKNVpm0455RSn4KFNRfHL8SFDhtgxxxzjTmO6LW0B07j8yyvKdhTgtCco1RHaPZaRZ/Wok046KVLi0sZed911Tnl83nnnubj4HaO9wdcPihQEa6BrrrnGHnzwQRc/03q7k4vgK27RVARJKgkREAEREAEREAER2CQEZKmzSbCWjESxrsHhJy8KG+tXx1vqoGThBST+adq0qTPxxyoHKxOW5T3iiCMcaF4GUMiwZO9zzz3nrFTiK2XxEsILDi8aTCngZYTpV0yNuuiii6LyY0mDcgQLGZQl3h8FeWDlwgsOo+ekgaKHUexff/11gw8vJt6ah7jkTx2Z/vTll18aI/a8pKCs8kJ5UOJceumlkR8O0mCkGqsWlElMSWDUGj89vCyhAPICAxQ5LA1PHKxhOAeWf/nLX6LpacSnPrwgolyqXbu2qwsvZVxLXioJ90Ka7733nnPwvCmXXvb56VcEipoA/7dHH33UjaIXddoFSS8/S5377rvPtRkoVUMrNqxZaK+wXMGahv8tbRRWhfG2h+PeTxdKY6Yv0RZhrUPbh9J4/Pjxrh3xChk//YopVBdccEGkbOZ8pnOisMFaEAf2tDv4BGNKJu2gF47RZqBQJk+Ut/CmPBdffLE7z8eljUVh4tPDoggLpTPOOCOhPSMN4lJvfnkGSESgOBOQpU5xvjoqmwiIgAjkNgFZ6uT29c262qH8SDb9iheOULz/nPAYfiAQRpuTCY5SeaFBYeOX88W3DC8koXi/EN4CxoehYPEvSBxDITR48GAfnPCLdQwvJV6oEx9Gv1m6HcshrGqYRoW1kRcUMT5/f4xflC8vvviiezHzfFBwMVVj6dKlLioOWak7yh1GuRHqiuAXIy5hvVF48eKHlRTTIOLCCxsKKRRZocInHk/7IiACBSeAYoVpTB07doyUKmEqe++9t7Ns8f9nFDpM14wL7dnll18eHUY5RLvHh/bihRdecFOlrr/+ehcvVCqTR6hM8onQ9jDViv+/V2ajLMb6kDaQc1A0oZBGaHtQLLHyHwrhZBaJxPeCsok2hfYtLijCEZTnqaasxc/RvgiIgAiIgAiIgAiUNAJS6pS0K17M64tSJ5PpOcleFJYtW+Zqh+VJMvEj0/jY8eJ9Ovh9fr2FDY5C40IYig2ElxmmBhRESJNpDChymFqAz4hQqRMqWsJ0Ganmxccra5iqwVQHjmNZw8scL4YojHgR4mULgQllDhVMYbp+m3MRFELJhPQR0o47bE4WP9UxLAuwRLrtttsSptOliq/jIlASCGDRgqT6/9PW8F/3Sg6UJQVte7DeO+uss5zlywMPPOCmep144okRXj/tKTrwvw1v+ePbHqZIobDxK4qhcEfJhKIaoX1EWY2SJ5MpUyizOIf4caUS7RGKbl+G/xVps/xglYnCKZyuu1kyViYiIAIiIAIiIAIiUEACUuoUEJiiF18CvPQgvCR4S5ywtDj9RVIpfcK4RbHNiwoORLGkYQQ+FMrAVKYPPvggPOxWnEo48L8dpiiQnp/mxkpZvPAwKh++jKEUwx+PF8JQ8OD8NBkTH8+z6927d+Sjx4fpVwREYNMS8MoPVpxLJlj4oXgNLVySxfPHcDyM4pfpmkx1CoXV8VDwxPNC4ZpMsOJDaCOwhkShg5I3b5GFyGqPcqHsZRoVghKZ9mnGjBluP78v3/accMIJBXIEnV+aChMBERABERABERCBkkQgsyV8ShIR1TVjAliOMIqayroj44SKKKJfehennn4qQJg0ToCxWsn0xSg8tzDbKFNwFMqUB5b1jQvTneIj87w0MTocF3xxIP4FjZc8lDShQodwH49thBF9BEfL3nrHHcj7QtGDU1McsZIW15Fl3ZMJx1EqSUQgGwmgNAlXeStudUCxgUIWnzdMk4oLbRdt2i677BIPSrrPfxr/Ys8+++wG/1vaASz44m0PTpq9taNPlP88eSO0PT7ct7U+Hr8+Hts8G2h7aGNG5K2KFRemWtEukv6OO+7ogpO1PayElex4PD3ti4AIiIAIiIAIiEBJJiClTkm++htZd6ZA4WQ4rljYyGQLfTom+r169XIvEqymwnLiCC8xKHqYIoAlSrqpSIUuQOxEphLgzJmpCEw38soaXs5wZoxTUaZOxYXVpvzoOGE4CuXFiJewvfbay0XnRYgRcz5eiMcS56HwYoUPHuIxXQMGCPv33nuvU+hg/YNCB78bKIWwLvJCWZ9//nm3sg1Ls0tEIBsJ8B84+eSTi3XRcWZOW4WvHJb+9oI/m9dff90pffz/34el+sVXDj5ysJS5++673ap+xGWaFysE0jYecMABCaejsCGuV0Dz30cxxGpV+OqinUcxhsIGfzoopREfDwVOKH369HHWOyiWmGZKutSPtm/YsGGGNRFp4YC+QYMGbsVB3z6RDmX8z3/+49oeb2UZpq9tERABERABERABERCBPwiUZVlShGVMG+eNFIar6fwRRd8ikD0EDjvsMLfSCitJMerNSwgvK7xQHHnkkZvd2SarxKDcYVQa58lMe6AsvAhRHlaACQXnzChYWPKXKVr44OHFjBcq/GF4qyiWJCfODTfc4FYFQ1FFvG7durlpFz5NXpr69+9vzzzzjHsRYxUbLyhzUMp5JRcvYYzw33PPPW56BdMpmMrGNI0ePXq4VcX8uYX9pfxYd8V9ZxQ2PZ0nArlCgOcv/0ccqF9xxRXuWcx/E0UHU6bwf1OQ/w3LiON0HSXKwIEDrX79+sbqglgFnX322RtMx+zZs6dNmDDBLrnkEvf/RwFEe8D/1fve2XbbbZ2iGksbVrViGhZWg7SxrDiIHxovtHX//Oc/nWIG5RAfL6yqRRuGYD1J23b77be79gwODBhgscTU1eOOO26LWFnR5oaOpH3Z9SsCIiACIiACIiACxY1AqbzVc9YzkhYXXuKYj0+nLW6mHY+rfRHYWAIoOVjZhY50fj5veNHAvwzKR++HIlnejAKzkhOjzMT1Ph/CuCh+yC++TDdWMqySxXFWlAqFFywUE4wsF0RwcMroNuXnP8XqXXGHwyxlzBSH8847z1nSeMseHDxTFq/Q8fmiHMJ6Bksg0mTJX14C4ciLGy9VoaCgYQUbfGeQVufOnROWJfZxCWfUnZcq2NEOeL8XPo5+RUAECk6A/xVtgZ9GmSwFpiSxjDhtDY7cabtQphRWaCdGjx7tlCe0EShNUKR4QRnMalgomVEKowxHmYOgFE821QpLv0mTJjnli08T5c7MmTNdWxQud0461MfXifrgYyyuoKLetO0wop1EoULbE0+L9CQiUNwIcP8ygDJgwIANFKbFrawqjwiIgAiIQO4RKJU3EhY5yqAjxQstnTyWSo7L4Ycf7jpsdAqTrRoUj6/93CaAIuaNN95wZvy6Hzb+WqPUYVrV3//+941PTCmIgAhEBJi+g5IERaYkkUCo1NGy4YlstCcCmRKQUidTUoonAiIgAiKwKQgkrH7Fizlm0XzwTYIwak+HOJmihzn7WAig5OFTtmxCcpuivEqzGBFAqcMS2u3atZOSrxhdFxVFBEQgkQDWH6w0J6VOIhftiYAIiIAIiIAIiIAIZD+BtFoYzL754OsDnxsIU1q8RU84T54wnK2i4EHZk98SysSViIAIlCwC+Mh44IEHnE8PTasoWddetRWBbCIwduxYN5h11FFHZVOxVVYREAEREAEREIESSCCtUicZE/xs8MHPB84OMTvFksdb9LDyUCjM0/cWPfn5SwnP0bYIlDQCWMfhPyeXBX8i3333XdIl53O53qqbCBRXAqwaeMghhzifXMW1jFuiXAsXLnQ+frZE3spTBERABERABERABApCoFBKnXgGrLCDQ0M+mLezdCyOalH0eIseljD1wjLLWPPwQdmT6y+yvt76FYH8COCcXCICIiACm5OAV+pszjyVlwiIgAiIgAiIgAiIQNERKBKlTrLisLIPq1zwQVg6nVU4UPJ4Rc/QoUOjU1my1St5+NXUjAhNsd1g2dkLL7zQrSBVbAupgomACJR4AgwkFHTFuhIPTQBEQAREQAREQAREQASygsAmU+okqz0WOSyPyscLS6di0cPUra+//tpefPFFF0QHnOVUUfBgAYRFDxZBkuJDgOvhlXbFp1QqiQiIgAgkEuDZI4vQRCbaEwEREAEREAEREAERyA0CCUuaF5cqsVKJt+jxVj2UjeWeUe54/zz169cvLkUuseVgBaypU6cm1L9q1aoWXhuu54oVKxLi7LTTTpGSDguuOXPmJITjs6latWru2Lp162zKlCkJ4azU1rBhw+jYzJkzbdmyZdE+G02bNrUyZcq4Y0uWLHEOvsMIderUMaYeIPiFwtdLKJUqVUpw9o2DcNIJpUmTJtGqb+RPOULBh9Q222wTHaIe1McLFmncz17gAI9QuO+xikKWL1++gZ+HmjVrOmfm/hyuB9fFS/ny5Z1i1O/PnTvXFi1a5HfdL4pT4iErV650Sla387+veB7Tp0+31atXR1HieaCsXbBgQRTOBvWUBV4CEu1sRgL4SJk3b15CjrRTtFdIsrasSpUqCRY+hWnL6tatGymUkrUzBW3LcDY+a9ashHqEbRkBkydPTgjPpC0L25lkbVmtWrWsRo0aUbqFacvCdoZnAjxDibcz06ZNszVr1kRR4u0M15PrGkqYR2HaMtpaWEhEoCAEtKR5QWgprgiIgAiIQFET2KyWOpkWnlWz+Oy3337uFDp1XrmDRc9bb73llABbbbWVs+TxFj1Y9bBSl2TzEUDJMHjw4IQMWSntzDPPjI6xQlr8JeOee+6JFBXjx4+3xx9/PIrPRr9+/WyfffZxx3CuG8+jZcuWdt5550XnvPTSS87SKzqQt3HHHXcY9wjyzTff2H//+1+37b+OP/74aIljFC3xPJo1a2YXX3yxj25DhgyxcePGRfts3HTTTZFiCKXQ/fffnxDOyik4Cvdy6623JihcuGcvu+wyH2xvvvmmjR49Otpn47rrrjNeqBCUKXfddZfb9l+HHXaY9e7d2++6cF5mvPDiOnDgQL9r+LdieedQrrrqqujllRetOIuePXtGq99x3n333ZegfOJ/N2jQoCjJESNGuHyiA3kbl156aYJyKQzTtghsagKff/65PfvsswnZ/PWvf7W2bdu6YygZ4vf9brvtZmeddVZ0zgsvvGCTJk2K9tkI2zKsTeMLBYRtGYrQeB6ZtGW33XabofxBaMseeught+2/jjvuONt///3dLi+X8TxQcF9yySU+ur322mv22WefRfts3HjjjZECGoUN//FQjjzySOvevXt06Pbbb09Q7KK0vfzyy6NwntMff/xxtM/Gtddea36xhO+//9610WGEQw891A4++ODo0J133umUzP4Ayv6rr77a77o2ZuTIkdE+GwMGDIiU8T///PMGLPBddsQRR0Tn0GaHSu54WxZF1IYIiIAIiIAIiIAIFFMCxdJSJxNWdMCZtsXHW/VgGYDlBS/KdDD5sM1oq0QEREAEREAEREAEREAEipqALHWKmqjSEwEREAERKAiBYmmpk0kFMCdv0aKF+/j4KHW8RQ9TULBIQPmDaTrKndCix09n8efqVwREQAREQAREQAREQAREQAREQAREQASyiUDWKnWSQWa+Px+m/3jBR4m36MH8/uWXX3Zz9FHweEseftmXiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEC2EMgppU4y6Dip5NO+ffso2E/Z4hffH/gQwQGjV/J4ix4sfCQiIAIiIAIiIAIiIAIiIAIiIAIiIAIiUBwJ5LxSJxl0pmLx6dy5swvGEa+35uH3yy+/NFbvwRcP8byyh1+/WlKydHVMBERABERABERABERABERABERABERABDYXgRKp1InDxUqHJbb5eGHZWK/owU/PRx995Fb7YWUMFD18vEWPX2HJn6tfERABERABERABERABERABERABERABEdjUBKTUSUG4atWqtuuuu7qPj/LLL79Eih6Wrh06dKitWrXKWDIaJU9o0VO6dGl/mn5FQAREQAREQAREQAREQAREQAREQAREoMgJSKlTAKQ1a9Y0PnvttVd01syZMyNFzyeffGJPP/20C0PJs8MOOzhFD8qeBg0aROdoQwREQARE7n+yKgAAQABJREFUQAREQAREQAREQAREQAREQAQ2loCUOhtJEGUNn3333deltHbt2mhZdaZtvf322zZ79mwXtvPOO0fWPCh9mMolEQEREAEREAEREAEREAEREAEREAEREIHCEJBSpzDU8jmnTJkytuOOO7qPj7Zy5crImgc/PSh6vLRu3TrBoodpXxIREAEREAEREAEREAEREAEREAEREAERSEdASp10hIogHEfKu+yyi/v45BYuXBhZ9EydOtVeffVVH2Tt2rWLpm1h0YMjZ4kIiIAIiIAIiIAIiIAIiIAIiIAIiIAIhASk1AlpbMbtbbbZxvjsvvvuUa5z586NLHqef/756Dgb++23n7PoYcUtfPRsKWEqGZZGKKJWrFhh69at21JFUb5ZTABH4pUqVXIryPXo0cP9ZnF1VPRiSODjjz+29959xzmzp62SiEBhCFSoUMEqVqxoe7Zpa4ccckhhktA5IiACIlBgAu+8845beRdr/9WrVxf4fJ0gAsweoa/NM6xDhw52wAEHCEoOEyiVt3T3+hyuX9ZXDb88fJi2xbLqoXTt2jWy6Klbt24YtEm2hw8fbs8884zt0/RHq1N16SbJQ4mWLAJzllS3r2Y2sLZ7d7Hjjz++ZFVetd1kBAYOHGjrVnxvHXaYusnyUMIli8B382raxJl17Oqrr7Z69eqVrMqrtmkJrF+/3vr3728DBgywRo0apY2vCCKQigCDp1dddZXV23qZtd/hh1TRdFwECkTg85+b2g/zK9iDDz5YoPMUOXsIyFKnmF8rrHL4dOrUyU466SQ36vzjjz9GFj0PPfRQQg169eoVWfRgCVSUgkLn/zqOtU47TSvKZJVWCScwaXYdu/Xd0lLqlPD7oKiqP3nyZFux+Ge789iXiypJpSMCjsCrX7ayz8Z8aIccdrSIiIAIiMAmIYCV6Q61FtnVh761SdJXoiWTQJ89v7abh/WycePGWZs2bUomhByvtZQ6WXaBMQVv1qyZ+1D0v/71r5ZnbeWUPFj0DBkyZIMaHXHEEZFFD2Z4+QkWQQ0bNrSyZZPfGrWqLsvvdIWVYALr15eyX5dXsiUrtzLuk6oVf8uIxi715lr96kuMl/HmzZtndI4iiUAqAqNGjbJaVRamCtZxEbDVa8vazIXVrHzZtVan2jIrU3ptRlR2qjPfHhkzSkqdjGgpkgiIQGEIoNTp2nRmYU7VOSKQL4Gm2/5k77//vpQ6+VLK3sDkb+7ZW58SWXJWzNp1113d5+CDD3YMfvnll2ja1ksvvbQBl2OPPTay6GHOpZe7777blixZYhdffHGkOCLst98ye0H36ei3ZBGYs7i63f3+Pvbjr9Wjiu+9w092WscxVrFc+rng69attd9//z06VxsiUFgCy5cvzzu1VGFP13k5TADF89sTm9uzY1vb2nWlXU0rlV9tf+00xtps/1NGNf9dvi0y4qRIIiAChSOwYqX624Ujp7MyISD/TJlQys44Uupk53VLW+qaNWsaH0zsjjzySBd/1qxZzqLnkUcecb5x4on069fPKXRKlSplN998s7Vt29aOPvpoq169ulMQxeNrXwQgsOL38nbt0AOsy87T7YzOnzgrnWnztrWXv2hptw3raJf2Gp4RKByFo5yUiMDGEFi1atXGnK5zc5jAsG+a24jJTeycAz62nevNz2u7ytm4GQ3tgZHt7Pxuq22XenPS1n7tWi0OkBaSIoiACORLAN9cLVu2NBaKqFKlSkLctWvSD4QlnKAdESgAgTVr1hQgtqJmE4GyzK3D98rWW2/tXt5Dq41sqojKmp5A/fr1jc8+++zjIq9du9Ypa5i29fTTTxvKHoQVrVDsfP755/bll1/a4YcfLsd/joy+khF45YtdbbftZlvfNl9FwS3qz7EmtX+1S57vZV/82ND22O7nKEwbIiACIrC5CaB8fm5sK7umzzCrV32xy75S+VXWvdW3ViHPmvDhUW3spr6v51usvMeiRAREQAQ2msDMmTONz7Bhw6xFixZ24IEHOiUPfW+JCIiACBSGQNkHHngg5XmdO3d2yh6UPlhroPjhU7ly5ZTnKCB7CKDA23HHHd1n//33d/MsUe74h0q5cuXctCuWV2/QoEH2VEwl3awEJuStCHPo7hM3yLNC2dXWquFc+ybPEXImSp2xY8caqz542Xfffd29yT4jC9yboXBPhsszMk/4558TlUdYmuGHCvn+++83WEFu7733tp122smFs3rJE0884bb9V506deyggw7yu/bhhx86a7foQN5G3759bauttnKHcGI+cuTIMNhZy9Fp8/LUU08ZClUvWNT17NnT79ro0aNt6tTEVZtQrDLNEsHi7r333ovis7H77rsnWDk999xzzqm6j0S7HS7HPGbMGOfDyIfzSzjxkHnz5tnbb7/ttv0XVlTk4+WFF14wllr1QvkopxcGDL755hu/635x5L7tttu67V9//dXeeOONhPBddtnF9tprr+jYK6+84nyG+QP4BPOWhxz76quvbPz48T7Y/TKNr1zCEe2IgNnUvNWrqlb8PVLohEz2avyz/fejtrbkt62sWsU/7+kwTnybhQNCM3b6SX76M3E/+eQTmzJlSsJp4X8My0SWLA6ldevWtttuu0WH0v3HPvvsM5s0aVIUn410/zHaotBJZvw/RltGm+aFgZ2vv/7a77pf2kTaRmTRokX22muvuW3/RZtK2+qFcOJ5KV++vB1zzDF+16VPPqHwkssgFMKU8FdffTUMtqZNm7olev3BN99805h27oX+zV/+8he/69oi2qRQ6ONut9127tCKFSvsxRdfDIOtcePG1rFjx+gYbSJtYygnnHBC1Gfi+Ouvv57QR95vv/3cVHfCsCKkbQ4FH4b0v7zQttPGh8J0efpjyPTp0w2/YaG0b98+mi7Ps4VnTCisjtqtW7fo0IgRI+ynnxKnG4bPSnwr8qwLBcvtnXfeOTrEs5JnppfatWtb9+7d/a571vLMDQX/jv79gWc1z+xQ9thjD2vVqlV0KP4fq1GjhvXu3TsKT/asPPTQQ937CpHmzJnjlCbRCXkb6f5j1apVs8MOOyw6hX7Jt99+G+2zEf7HuOe490LBAmfPPfeMDuEC4Y9pwX8c4jlGPtzXMJw4caL7EBq2IVEC2hABERCBDAiU9Uub4Wx34cKFtnjx4ug3/qBOll67du0ixY9X+vhfWf0kI1Z8j/EgR/yKW96yh5dnOhmDBw924foSgZDAurx+3br1f/inCI+zTZ9v3br0I090bEqXLu0+8TT8PuH5CcrI/OIkC/cKTJ9ufuenihN2bDPJIx4nXgbPwueX7Leg5YznQZrxNMJ6JAuPpxGvRyblLIo8eGk588wzk2XnjvFyXbN8ymAFlFAC+NNZm6ItKlfmjylVq9fm38aE6Pj/hP+hovh/hOmzHf+PFTSPTNoS8iloPcJyJMsjDM+kHvEysB9KnANh8bYkHiddGUgjHifkQHhc4nnEw9mPx0mXRzw8fr5PM8wrXs54GpmEx+OE6WdSBuLE802XRrrweHrxcqQLJ/14nHg94+GcE8aJh7MfhhM/LvHwdGnEw3lX8gM9XnkXz0P7IiACIpCOQKk8ZU7ea1dmwqgUoy3+45VA7KPNTiWM8NLRDi1+2Eb547X2qc7V8eJBgJWJUOpc2uv9PL8Dc4tHoVSKYkHgwQ862Mrfy9p5XRNH9latKWcXP9fLjm73te3XdHq+Zb3i5e7Wvmt/69q1a77xFCgCELjnnnuchU78xe6kk05yFhLrF39iAw5OtIIQuZJNYOGKSvb3Zw7Nuy/etaa1/7TogMon0xvbYx/vafeesOGiAiG1b+fUsXs/ONBuGnx/eFjbIuCUTP3797cBAwZourruh7QETj/9dBcHq50OHToY1lYMqCKE9dljorEEtUQEipLAy5/vap/90sO1U0WZrtIqHgTKFqQYaJBr1arlPvHzWFrbC1Y/XvET/mI2Gjfj9edgrouSB2UPZolxJVCqJbb9+foVARHYMgT6thlvl73U3Z7/bHfru9f4vHWH1tnyVRXs7uH7Ws2qK6zDjjO2TMGUa84SQPnHswSlDqOcFStWtIsuushNE2Xai0QE4gS2qbTCDt/jG7tn+D72924f2fbbLnBRfvi1hj316e5uBaz4OdoXAREQgU1BgKlqvPcwVStu6bMp8lOaIiACuU+gQEqdTHHgW4FPo0aNUp6C1Q/zSbH2CS1+FixY4OYMowyaP39+wvnMffa+fbylD4ogjrEf9yCfcLJ2REAENgmBGpWX28BD33NLmr/21Z9z7lnS/LyuY6xMaa0Ws0nAl5BE8b2Dv413333XKW7wyUNnGIfuCL4cUOh4n0MlBIuqWQgCh+/+tW2V5xR54JCu0ZLmlSv8bv/XcWxGfr8KkaVOEQEREIENCIS+4TYI1AEREAERKASBTaLUyaQcWP3QOfdOM1Ods2zZMmf1g+InVALh/wXFD8exDEJI0/vz8VY/cSUQ+5qzmoq2jotA4QjUzVtN5prD3rJfl1eyJSu3strVllmVCr8VLjGdJQJ5BJjyOXToUPfLAAFOZjFVR/BJgJNsfH2dc845atMdFX2lI1Cq1Hrr0WqSHbjLFJu5sJqVL7vW6lRbKsVzOnAKFwEREAEREAERKNYEtphSJ1MqWN/wYYWAVMLKODh49koeP+WLYyh/vEKIlQcQRnRD5U+ybY36pqKt4yKQnAAvTDWrLHef5DFSH817R5eIwAYEaPf79euXVPnfp0+faGWzDU7UARHIh0C5Mmuscc0/pl/lE01BIiACIiACIiACIpAVBIq9UicTivjbycTqhyUFveInVAL98MMPbmlcjvFBsOYJrXzi2376V0my+ilbeq099FG7TC6J4ohAgQj89nuZAsVX5NwhwPSqjz/+2H1Y5tgvm968eXPjk0r8UvWpwnEIKBEBERABERCBbCJQqfwaGzWtsftkU7lV1uwgUKbikuwoqEpZYAI5odTJtNastMWHJbpTCX4asOzx1j6hEuinn36Kwn7//XeXBFZEyaZ6hUqgXLD6oe5r1pWxfZvMSIVOx0Wg0ARe/qKl4WdLUnIIoMy59957jbYFHzlMr8pPiZMpGZz5fzy9gU1avnempyieCGREoPTaFVaj0pqM4iqSCIiACBSGwOq1pdXXLgw4nZMRgY9+Sj3zJaMEFKnYEihRSp1MrgJe6DOx+lmxYoVT8IQWPyiAeEFhVRasf+LSpEkT59AZJRBKH2/twy8rfqUbeY6ntyX2tcTilqCe+3mi1ClJVm+5f0WT13DlypW21VZbuUD842CV87e//S3p9KrkKaQ/WqNGDfu9wna2oPFF6SMrhggUgEC55ZNtu/WvFeAMRRUBERCBwhFQf7tw3HRWagJYMPs+WOpYCslWAlLqFPLK8ULCJxOrn1Dx47dR/uAINJm0atUqYepXqARC+SMRgeJGYPXasvbs2N3t8x/q2ZLfKlqtqsutW4updsDO3xW3oqo8m5kAbd3o0aPtiy++cEocplghdCywzpGIgAiIgAiIgAiIgAiIgAgUnoCUOoVnl/bMTK1+GL2OT/nC6ufnn3+2119/PWU+bdq0STr1CyVQ+fLlU56XX8Brr71mXbp00fLA+UFSWAKBdetL27VDD7SVq8vaQS2nWt3qS23avBr24riWNndJZTuu3RcJ8bVTMgjQrt1yyy3OenG33XZzCpx99tmnZFRetRQBERABERABERABERCBzURASp3NBDq/bBix5lO/fv2U0davX590uheWP++9917K83xA7969E6Z8eesfH87v2rVrDaUOn4MOOsh69uzpfBCFcbQtAnECwybuZMwBH3TEm9HSwLs3+tk6N59u/3yhh+3b9AfbroZWmolzy8V9/OQwfRWhTTvwwAOdnxx/LBfrrDqJgAiIgAiIQEEI3HbbbdaiRQvbd9993Qq/BTlXcUVABEQgGQEpdZJRKYbHSuWt+YyvCD5xOeWUU6JD3uoHZQ/WP366V34WP9HJwcb7779vfLp27Wo9evQIQrQpAokExsxo5KZalSm9LiGgZpVltvt2s23s9w2l1Ekgk1s7TK9699137csvv3QOj88666yogrLMiVBoQwREQAREQAQcgUmTJhmfl19+2XbddVfr3LmztWzZ0ujrS0RABESgMASk1CkMtWJ8Tiqrn+OOOy4qNVY/TO/yih+UP88884wL54FCuF+J6M033zQ+jChIRCAZgUUrKlqViquSBVm1rX63RSv/cIybNEJw8NNPP3VTdfyhjh07WtOmTd0u9+MTTzzhg9wv/qywKPOCYgEFQyjHH398NBVx2rRp9sEHH4TB1r59e9tll13cMe77Rx55JCG8bt26zmLNH0TROWPGDL/rfvERg38thDDihLLXXnu5Tps/9uijjxqr7HmpWbNmgm+ZDz/80KZOneqD3e+RRx7pnKmzw7TMYcOGJYTvscce0VLgBDz55JPmV+hjH8u8Pn36sOmEJcTjPr0OO+yw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EIAABCAAgc5HAKVOhmf21VdfhZU5d999txswYIA77LDDXM+ePTP4bI6TcgqdL7/8MqRbO2BJAfWd73zHzTvvvM1JFLFAAAIQgAAEIAABCEAAAhCAAAQgUCgBlDpV8D744INu3LhxbqGFFnLHHXecW3PNNav4aO7tq666Ktj10Zbk+hzM5KGHHnK/+93vws/jjz/e9e7d225xhAAEIAABCEAAAhCAAAQgAAEIQKALEECpU+YhvvHGG+FTq6eeesrtvvvubvvtty/jsuMu//73v3f333+/O/30091yyy0XEqJ0n3nmmeF8r732ctttt13HJZCYIQABCEAAAhCAAAQgAAEIQAACECiMAEqdFLS33HKLu+2229wmm2zizj77bLfYYouluOrYS6bQGTVqlFt22WVDYm699VanP8m5557bkukOieMfBCAAAQhAAAIQgAAEIAABCEAAAnUTQKkTIZwxY0awQaMtvo866ijXt2/f6G7rnF5xxRXugQceCCtyll56affYY4+50aNHhwQeeeSRbr311mudxJISCEAAAhCAAAQgAAEIQAACEIAABAohgFLHY33vvffCp1aPPPKI23XXXcNfIbQbEGis0JlrrrmC3RzZz9l5553DZ2INiIIgIAABCEAAAhCAAAQgAAEIQAACEOgEBLq9Uueuu+4KCp0+ffq4M844wy2zzDIt+9guv/xyJ8PN+iTs8ccfdzfccENIa2xTp2UTT8IgAAEIQAACEIAABCAAAQhAAAIQaCiBbqvUkQFk7Wr10UcfuYMPPjjYz2ko2QYHpp2stCJn2LBhTjtdSYYOHeo233zzBsdEcBCAAAQgAAEIQAACEIAABCAAAQh0BgLdTqkzc+bMYDdnypQpYWeowYMHux49WhvDpZde6vRp2Kabbuouu+wyN3DgQLfHHns4fX6FQAACEIAABCAAAQhAAAIQgAAEINA9CbS2NqPBz+S+++4Ln1qtuOKK7pRTTnE6trqYQkfp1EqdESNGuFVXXbXVk036IAABCEAAAhCAAAQgAAEIQAACECiYQLdQ6rzwwgthdc4bb7zh9txzTzdgwICCsTYm+AsuuMDpMzHJPvvs47797W83JmBCgQAEIAABCEAAAhCAAAQgAAEIQKDTE+jSSp0vvvgi2M2555573FZbbeUOP/xw17Nnz5Z/aG1tbW7UqFHu7bffduuvv77bd9993UILLdTy6SaBEIAABCAAAQhAAAIQgAAEIAABCDSPQJdV6miXqJtvvtktvPDC7vjjj3e9e/duHtU6Ypo+fbq7+OKLQwgYQq4DJF4hAAEIQAACEIAABCAAAQhAAAJdnECXU+q8/vrrQZnz9NNPOxlBHjRoUKd4hO+++26w9zNt2rSQ3vPOOy8opDpF4kkkBCAAAQhAAAIQgAAEIAABCEAAAk0n0KWUOtqifPz48W6zzTZzZ511lltsscWaDrSWCO+66y530003lT6xQqFTC0X8QAACEIAABCAAAQhAAAIQgAAEuheBLqHU+fOf/xxWucwxxxzuqKOOcn379u0UT/Gvf/1rWFX0yiuvuF69eoU0n3rqqSXlTqfIBImEAAQgAAEIQAACEIAABCAAAQhAoEMIdGqljj5Zkt2cRx991O22225ul1126RCIeSOdOXNmSPeUKVPcdttt5xZccEGna8OHD3cLLLBA3uBwDwEIQAACEIAABCAAAQhAAAIQgEA3JDB7Z82zPlkaOXKk+/rrr92ZZ57ZaRQ6kydPdieccIKTQuqUU04JO1x9/PHHKHQ6a0Ek3RCAAAQgAAEIQAACEIAABCAAgQ4i0OlW6tgnS5988on7wQ9+4DbeeOMOQpcv2hdffDGsznnmmWfc/vvv7wYMGOB+/etfOyl0jjnmmE6x1Xq+HOMaAhCAAAQgAAEIQAACEIAABCAAgSIJdBqlzkcffRTs5kydOjV8srTHHns42dBpddFKIn0iNmHCBNe/f3936KGHuvnmm89ddNFF7rPPPnM//OEPw+9WzwfpgwAEIAABCEAAAhCAAAQgAAEIQKC1CHQKpc6kSZPcNddc49Zaay138sknu5VWWqm1KJZJzSOPPBIUUbKZc+yxx4b0f/PNN0Gh88UXX4QVOvPOO28Z31yGAAQgAAEIQAACEIAABCAAAQhAAALlCbS0UueFF14ISpHnnnvOHULjJOsAAEAASURBVHDAAWGlS/mstM6dt956K6T7L3/5i9tzzz3d9ttvHxL31VdfudGjRzsd9cnVPPPM0zqJJiUQgAAEIAABCEAAAhCAAAQgAAEIdCoCLanU+fLLL4NSZOLEiW7rrbcO25R3lhUt48ePd+PGjXMbbbSR++lPf+oWX3zxUCCkyNEnV//617+CUWQUOp2qnpBYCEAAAhCAAAQgAAEIQAACEIBAyxFoOaXOAw884K644gq3yiqrhF2i1lhjjZaDlpagJ554IiiipLw5/PDD3frrr19ypk+ttEKnra0trNCZa665Svc4gQAEIAABCEAAAhCAAAQgAAEIQAACtRBoGaXOa6+9FgwKSzmy9957u0GDBtWSn6b7+eCDD8LKHCmjdtxxRycDzrFIoaNdrmabbbawQgeFTkyHcwhAAAIQgAAEIAABCEAAAhCAAARqJdASSh3tDnX77be7zTbbzP385z93iyyySK35aao/fR42duxYp9VEp556qlthhRXaxS+FzoUXXuh69Ojhjj76aDfnnHO2u88PCEAAAhCAAAQgAAEIQAACEIAABCBQK4EOVepMnz7dXXzxxW655ZYLq1j69OlTaz6a6k+Gm6WIevfdd92+++7rtthii1ni13blWqGjlTlHHXVUUOzM4ogLEIAABCAAAQhAAAIQgAAEIAABCECgRgIdotSRMkQrXKZNm+Z23313t/POO9eY/OZ608obpfvee+9122yzTdkdrKTQ0QodGUPWCp055pijuQklNghAAAIQgAAEIAABCEAAAhCAAAS6PIGmK3XuuOOOoBjp16+fO+uss9xSSy3VKSA/+OCDbsyYMW6JJZZwJ554olt99dVT0/3JJ5+EXa569uwZVujMPvvsqe64CAEIQAACEIAABCAAAQhAAAIQgAAE6iHQNKWODCBrS2/JIYccErb8rifhzfJrBpyfffZZN3jwYLftttuWjfrjjz8On1xJoaMVOjKOjEAAAhCAAAQgAAEIQAACEIAABCAAgSIIFK7U+eijj8LKnKlTp7rtt98+7A7VWVavjBs3zo0fP95tuumm7uyzz65owHnmzJlBabXAAgsE+0BFPCzChAAEIAABCEAAAhCAAAQgAAEIQAACRqBQpY5sz1x77bVu7bXXdiNHjnS9evWyeFv6OGPGjKCIki0cGTnu27dvxfRKcSWjyAsttFBwX9ExNyEAAQhAAAIQgAAEIAABCEAAAhCAQAMIFKLUef75590vfvGLkLwDDzzQbbnllg1IavFB/OMf/wi7Wj3yyCNu1113DX/VYv3www+DQmfhhRdGoVMNFvchAAEIQAACEIAABCAAAQhAAAIQaBiBhip1Pv/886AUsd2hZINm3nnnbVhiiwxowoQJYXWOtlU/44wz3DLLLFM1un/+859BobPYYou5I444oqp7HEAAAhCAAAQgAAEIQAACEIAABCAAgUYRaJhSRzZzrrzyypCuSrtDNSrhjQrn6aefDsoc2cQ56KCDgv2cLGF/8MEHQaGj3bAOP/zwLF5wAwEIQAACEIAABCAAAQhAAAIQgAAEGkagbqXOq6++6s4555yQoCFDhriBAwc2LHFFBqStx2+++WY3efJkN2jQoLCz1Zxzzpkpyvfee8+NHj3aLbnkku6www7L5AdHEIAABCAAAQhAAAIQgAAEIAABCECgkQRqVuq0tbUFpcgdd9zhNt98c7f77rtX3B2qkYmuN6wpU6aE1TnLLrusO+mkk9zKK6+cOUgpdGQUeemll3aHHnpoZn84hAAEIAABCEAAAhCAAAQgAAEIQAACjSRQk1Jn2rRp7pJLLgnpGD58uJMdms4gL730ktM25TrK3s8222yTK9kypCyFjpRBhxxySC6/OIYABCAAAQhAAAIQgAAEIAABCEAAAo0kkEup884777jTTjstxC+lyE477dTItBQW1jfffBNWFd11111uiy22cN///vfdggsumCu+d999Nyh0ll9+efeDH/wgl18cQwACEIAABCAAAQhAAAIQgAAEIACBRhPIrNTRZ1Zjx44N8Z999tnBnkyjE1NEeI8++mhId8+ePd0xxxzj1llnndzRSKFz4YUXuhVXXNENGzYst388QAACEIAABCAAAQhAAAIQgAAEIACBRhOoqtR54okn3EUXXRTilQ2ZDTfcsNFpKCQ8rSqSEurPf/6z22OPPdyOO+5YUzwKR59cye7OwQcfXFMYeIIABCAAAQhAAAIQgAAEIAABCEAAAo0mUFap889//tONGDEixLfDDjsExchss83W6PgLCc9WFW2wwQZhZ65vfetbNcXz9ttvB4XWqquuikKnJoJ4ggAEIAABCEAAAhCAAAQgAAEIQKAoAqlKnYkTJ7rrrrsuxDly5EjXq1evouJvaLhPPvlksJ3z2WefhZ2p6llV9NZbbwWFzmqrrYZCp6FPicAgAAEIQAACEIAABCAAAQhAAAIQaASBdkqd5557zp1//vkh3IMOOigYFW5EJEWH8eGHHwZlztSpU932228fVhXNPvvsNUf75ptvhk+u1lhjDScOCAQgAAEIQAACEIAABCAAAQhAAAIQaDUCQanz+eefByPCljjZ0Jl77rntZ0sfJ02aFGznrLLKKu6UU04JxozrSfAbb7wRFDq9e/dGoVMPSPxCAAIQgAAEIAABCEAAAhCAAAQgUCiBHlrdcuWVV4ZITjzxRLf66qsXGmGjAv/b3/4WVufoM6m9997b9e/fv+6gX3/99aDQWXvttd0BBxxQd3gEAAEIQAACEIAABCAAAQhAAAIQgAAEiiLQQwqdIUOGuIEDBxYVR0PD/fLLL4My55577nFbbbWVO/LII918881XdxyvvfZaUOj06dPHfe9736s7PAKAAAQgAAEIQAACEIAABCAAAQhAAAJFEujxi1/8wi200EJFxtGwsB966KHwqdXCCy/sjj/+eKdPpBohr776alDo9O3b1+2///6NCJIwIAABCEAAAhCAAAQgAAEIQAACEIBAoQR6dAaFjuzc3Hzzze6xxx5ze+21l9tuu+0aBuWVV14Ju1ytv/76br/99mtYuAQEAQhAAAIQgAAEIAABCEAAAhCAAASKJNBu96siI6o17FtvvdXpb+ONN3bnnnuuW2yxxWoNahZ/L730khs9erTbYIMN3L777jvLfS5AAAIQgAAEIAABCEAAAhCAAAQgAIFWJdCySh2tyhk7dqxra2tzRxxxhOvXr19DGb788svhk6uNNtrI7bPPPg0Nm8AgAAEIQAACEIAABCAAAQhAAAIQgEDRBFpOqfPee++5cePGOdnP2Xnnnd3uu+/ecAZaoXPhhRe6TTfdNBiJbngEBAgBCEAAAhCAAAQgAAEIQAACEIAABAom0FJKnbvvvtvdcMMNbt1113Wnn366W2655Rqe/RdeeCGs0Nlss83cd7/73YaHT4AQgAAEIAABCEAAAhCAAAQgAAEIQKAZBFpCqfPss8+GT61efPFFN3ToULf55psXkncpdLRCZ8stt3R77713IXEQKAQgAAEIQAACEIAABCAAAQhAAAIQaAaBDlXqfPbZZ2FXq0mTJrmBAwe64447zs0999yF5Pv5558PK3QGDBjg9txzz0LiIFAIQAACEIAABCAAAQhAAAIQgAAEINAsAh2m1Jk6daq78sor3WqrreZGjBjhVl111cLy/Nxzz4Vty7faaisUOoVRJmAIQAACEIAABCAAAQhAAAIQgAAEmkmg6UqdV155JRhCfvLJJ4ORYq3QKVL0addFF13kttlmGxQ6RYImbAhAAAIQgAAEIAABCEAAAhCAAASaSqBpSh1tTX7zzTe7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KJgASp2CARM8BCBQmcCbb75Z2QF3uwWBf/zjH+7FF1/sFnklkxCAAAQ6O4H333/fff755509G01P/7/+9S/3xBNPwK7p5IkQAl2bAEqdrv18yR0EWpbAhx9+6Pbdd1/Xu3fvlk0jCWsOgZdfftktscQSbpVVVnEXXXRRcyIlFghAAAIQyE2gra3NnXXWWW6xxRZzzz//fG7/3d3DUUcd5dZdd13Xq1cvN3PmzO6Og/xDAAINIoBSp0EgCQYCEMhHYNiwYW78+PHukksuyecR112OwLvvvlvK0xVXXFE65wQCEIAABFqLwP/8z/+4UaNGuZNPPtmtscYarZW4TpCa1157LaTy73//u7v//vs7QYpJIgQg0BkIFKbUefbZZ92BBx6Y6++qq65yX375pZttttnc8ssv3xn4kUYIQKAGAmofbrrpJnfBBRe4ffbZp10I48aNCwNGPstqh6WmH+ecc05oT2NFyYwZM9xJJ53kpk+fXlOYRXjaaKON3G9/+1u3wAILuI8//riIKEphpjEp3SxzorKoSczNN99cxgWXG0GglmfTiHhrDeOpp54K9WunnXbKHMR9990X/EipjRRDgD4kO9eBAweG8phnxY1W6RxwwAHupz/9qZtrrrmyR4bLQEDjnr333jucf/bZZ4VRqXU+deONN7ozzjjDvf3224WljYBrJ3Dbbbe54447rjS/1qd8HSmdrd/uSFZFx92jqAg++OADJyVNHpl//vlLDZ0+zUAgAIH6CGiZ9E9+8hN3zTXXuL/+9a/1BdZA388991wITRPlRRdd1A0ePDj8fuedd0rn+l6/nk9xtPpD4X/xxRfusssua2DqO09QX3/9dUisGJh873vfc5qMjh071km5Vqs0mu+QIUPc8ccf77beeutak5TJ3zfffBPcxUyqeTz77LPd//7v/wZneruqT8WaIc2qv41+ltXYjBkzxp155pnu2muvdWuuuWbJeS3PpuS5A070fCR5ypLlsWjlZQfgaGqU5cpQI/uQpmaogyKzsisFQBZRv6w2UOP7VVdd1Z1++ulZvOEmIiBuG2ywgbvhhhvc+uuvH91p7Kls90jyzKdeffXV0jxMbdT555/f2ERVCK1cna7gJfetZvWpuROW0YNehu61117tXGvs1KdPn3bXmvnD+jRrS5oZN3G1J1DYSp2NN97YvfHGG7P8rb766iEF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&quot;&gt;
&lt;p&gt;In scavenging we actually do these three steps — marking, evacuating, and pointer-updating — all interleaved, rather than in distinct phases.&lt;/p&gt;
&lt;p&gt;在scavenging中，其实我们做了三个步骤 - 标记、清理、更新指针 - 所有都可以交错执行，而不是按确定的步骤执行。&lt;/p&gt;
&lt;h2 id=&quot;orinoco&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#orinoco&quot; aria-label=&quot;orinoco permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Orinoco&lt;/h2&gt;
&lt;p&gt;Most of these algorithms and optimizations are common in garbage collection literature and can be found in many garbage collected languages. But state-of-the-art garbage collection has come a long way. One important metric for measuring the time spent in garbage collection is the amount of time that the main thread spends paused while GC is performed. For traditional ‘stop-the-world’ garbage collectors, this time can really add up, and this time spent doing GC directly detracts from the user experience in the form of janky pages and poor rendering and latency.&lt;/p&gt;
&lt;p&gt;大部分这些算法和优化在垃圾回收的技术历史中都非常常见，并可以在很多垃圾回收语言中得到印证。但最先进的（state-of-the-art）垃圾回收还有一段很长的路要走。衡量垃圾回收耗费时长的一项很重要的指标就是，当GC执行时主线程暂停的时长。对传统的”stop-the-world”垃圾回收器来说，这段时间相当致命。在GC执行时，停顿的页面、糟糕的渲染以及应用延迟等问题，会摧毁用户体验。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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AQQQQAABBEgQ+A4ggAACCCCAAAIIIIBARIAEIULBCgIIIIAAAggggAACCJAg8B1AAAEEEEAAAQQQQACBiAAJQoSCFQQQQAABBBBAAAEEECBB4DuAAAIIIIAAAggggAACEQEShAgFKwgggAACCCCAAAIIIECCwHcAAQQQQAABBBBAAAEEIgIkCBEKVhBAAAEEEEAAAQQQQIAEge8AAggggAACCCCAAAIIRARIECIUrCCAAAIIIIAAAggggAAJAt8BBBBAAAEEEEAAAQQQiAiQIEQoWEEAAQQQQAABBBBAAAESBL4DCCCAAAIIIIAAAgggEBEgQYhQsIIAAggggAACCCCAAAIkCHwHEEAAAQQQQAABBBBAICJAghChYAUBBBBAAAEEEEAAAQRIEPgOIIAAAggggAACCCCAQESABCFCwQoCCCCAAAIIIIAAAgiQIPAdQAABBBBAAAEEEEAAgYgACUKEghUEEEAAAQQQQAABBBAgQeA7gAACCCCAAAIIIIAAAhEBEoQIBSsIIIAAAggggAACCCBAgsB3AAEEEEAAAQQQQAABBCICJAgRClYQQAABBBBAAAEEEECABIHvAAIIIIAAAggggAACCEQESBAiFKwggAACCCCAAAIIIIAACQLfAQQQQAABBBBAAAEEEIgIkCBEKFhBAAEEEEAAAQQQQAABEgS+AwgggAACCCCAAAIIIBARIEGIULCCAAIIIIAAAggggAACJAh8BxBAAIGACpSVlcmHH34oJ0+eDKgAzUYAAQQQiCdAghBPhfcQQACBAAh85zvfkcLCQunQoYMcOXIkAC2miQgggAACyQiQICSjxDYIIICADwW2bdtmtmrPnj2ycOFCH7aQJiGAAAIIpCJAgpCKGvtkReD555+X6667TubPn5+V+p2utLi4WP71r3/Jt7/9bbPd119/vRQVFTkdRoX6PvnkE/ntb38rU6dOlXbt2kmrVq3ksssuk//93/+VVatWVdg22RclJSXyf//3f3LvvfdmvX3JxmzHdnqwrt/vG264IalTfv7whz+Y27/++uuRcI4ePSp33nmnDBs2zOwb7Z8RI0bI3XffLcePH49sF16577775IorrjBfnjhxIvy2r571v6OcnBzz++qrhjncGP1uquP7778fqfmhhx4y39PvIgsCCPhMIMSCgEcEfvKTn4SM//xCDz74oEciTi/M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&quot;&gt;
&lt;p&gt;Orinoco is the codename of the GC project to make use of the latest and greatest parallel, incremental and concurrent techniques for garbage collection, in order to free the main thread. There are some terms here that have a specific meaning in the GC context, and it’s worth defining them in detail.&lt;/p&gt;
&lt;p&gt;Orinoco是一个项目的代号，这个项目使用了最新以及最棒的并行、增量、并发垃圾回收技术，争取将主线程从垃圾回收这件事情上解放出来。在GC这个上下文中，上述的一些名词都有特殊的含义，并值得详细解释下。&lt;/p&gt;
&lt;h3 id=&quot;parallel&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#parallel&quot; aria-label=&quot;parallel permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Parallel&lt;/h3&gt;
&lt;p&gt;Parallel is where the main thread and helper threads do a roughly equal amount of work at the same time. This is still a ‘stop-the-world’ approach, but the total pause time is now divided by the number of threads participating (plus some overhead for synchronization). This is the easiest of the three techniques. The JavaScript heap is paused as there is no JavaScript running, so each helper thread just needs to make sure it synchronizes access to any objects that another helper might also want to access.&lt;/p&gt;
&lt;p&gt;并行（Parallel）指的是主线程以及辅助线程在相同的时间内处理接近量的GC工作。这仍旧是一个”stop-the-world”解决方案，但暂停的总时长被协同进行GC的辅助线程分了出去（需要加上一些同步所需的额外开销）。这是三种技术中最早得到实装的。JavaScript堆内存在GC中是暂停的，因此没有任何JavaScript代码在运行。每个辅助线程只需要确保同步访问对象的状态，以保证自己访问的对象不会被其他辅助线程处理。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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gYD07dtXzjrrLOnVq1fk2zxHAAEEEEAAAQQQQAABBBDwuQDDtXx+gWmefwQ+//xzsV5b0QIea2UwGJQZM2bIyJEjZezYsf5pOC1BAAEEEEAAAQQQQAABBBCIS4CePHExsREClQvY8Lubb7455obvv/++fP/998771tPGetzEKpHDriZMmCBPPvmkE+S4+3Tq1MnpDbZq1SrZsGGD+7JYjyLbtlGjRrL//vuHXucBAggggAACCCCAAAIIIICAvwUIefx9fWldDQrUrl1b+vXrF/OMEydODL1nAUxF24Y21Ac2D5IN0bKeOlaaN28ul156adj+y5Ytk3fffVfGjx8f2u7RRx8VuzVs2NDZj/9DAAEEEEAAAQQQQAABBBDwtwDDtfx9fWmdDwRsku3i4mKnJRbw3HnnnWEBj73RoUMHscmazznnnFCLCwsLGbYV0uABAggggAACCCCAAAIIIOB/AUIe/19jWpjlAja0q2nTpk4rLr/8cmnSpEnMFp1wwgnSoEGD0PvTpk0LPeYBAggggAACCCCAAAIIIICAvwUYruXv61uudevXr3cm7l26dKnYHDIWGHTr1k1atmxZbtuqfMHOt3jxYlmzZo3TK8WW/O7fv7+z9Hey5ykqKnJW+7Lj2vLlFoRYO3r37i220lSyxZa5nzRpkjPPTY8ePeSQQw5JqZ7J1sPd7+STTxYLb2w+nz59+rgvR723dvfs2VN++ukn5/1169ZF3Y4XEUAAAQQQQAABBBBAoOYFbCqGunXrVvvfXzXfMs6YKQKEPJlyJaqxHjYRr83V8t5774nN3RJZatWqJYMHD5ZTTz3VCXwi34/n+ebNm53hQrZt/fr15ZlnnhFbBtxWhLJJg+fNm1fuMHbeww47TC644IKw3iflNox4wdpgbbHjWtATWWzS4uOOO06GDx8uNk9OtHLdddfJkiVLnLdGjBghJ554osyZM8eZsNhr9O233zphmB0rncXaccABB8RVBZvvxy0FBQXuQ+4RQAABBBBAAAEEEEAgAwT++Mc/yqBBg+TQQw91vlDOgCpRBR8JEPL46GJGa4oFFg8++KAzeW+09+21kpIS+e6775yeIueee64ce+yxsTaN+3ULeO69916ZNWtWzH3svF988YWz7PeVV14p3bt3j7mtvWHbv/rqq/L2229XuN3q1avlueeec0Kga665Rho3blzh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5rgPa/T++++/j/t8FlxMnz49tL23/tY7xbsM++zZs0Pb5doDm4l/5MiRsnLlSqfptnqZ9egh4Mm1TwLtRQABBBBAAAEEEMhWAX53z9Yrlz31JuTJnmsVd01tpSq3WCCwYMEC92ml97aylfWYSbW88847od4mlR3rv//9b2j5b9vWW38LeKw7o1u+/vpr92Gl96tWrQoFIpVunOEb2NCs2267TdwVwyzgsedMypbhF47qIYAAAggggAACCCCAAAI1KEDIU4PYNXUqm5ndOwHv448/Hpqgt6I6WK+fe++9V6699lqxpblTKTt37pRHHnlEbFWrior14HnvvfdCm7Rs2VJ69+4dem4PbLyqWyzk+fHHH92nMe9tyNhf//pXpy0vvvhiXO2PebA0v2GTT996661iyy1aMSMLeOyeggACCCCAAAIIIIAAAggggIArwJw8roTP7s877zwZNWqU06rFixfL3XffLX/6059izmczdepUefjhh53trffP22+/HdaDJhmeuXPnOvPF2HmjBRJjx46VZ555JqwXz7HHHiveyZbtvAcddJBYzyCbt8fCG6vnFVdcIYMGDYpaLVtq3QKm+fPnO+9biGRBUdeuXaNun8kvWkhmgY6tpuWW/v37y7hx49ynld4fd9xxkp+fX+l2bIAAAggggAACCCCAAAIIIJDdAoQ82X39YtbeJlsePny4fPLJJ842NpfN9ddfL7/4xS/EQgKbFNmWFF+6dKl8+OGH4p1Dx1axGjFiRMxjV/aGhTQHHHCAfPPNN7Jo0SLnvLbC17777uvMr2MraY0fP15mzJgRdqju3bs7dQ57UZ9YfSzUsfrbyl2FhYVy3333ycEHH+zMSG+9lmyFKTuuDTezQGjr1q2hwwwdOjQrAx5rgE2c7Q147DULxxIpw4YNI+RJBIxtEUAAAQQQQAABBBBAAIEsFSDkydILF0+1zz//fGczN+ixYT+vvvqqc4u1vy3hd/nll4t38uNY28Z63XrbnHvuuc5cQKtXrxbrWTNmzBjnFmsfC51uuukmqVevXtRN2rdvLzYL/UMPPSQ2UbMVG7pV2Rw9Np/PhRdeGPWYvIgAAggggAACCCCAAAIIIICAnwQIefx0NSPaYpMWW8DRt29fmTBhgtiQLOsJE61Yj5GePXvK7373O7EVrVItNszonnvukX//+9/y5ZdfOkFPtGPa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&quot;&gt;
&lt;h3 id=&quot;incremental&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#incremental&quot; aria-label=&quot;incremental permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Incremental&lt;/h3&gt;
&lt;p&gt;Incremental is where the main thread does a small amount of work intermittently. We don’t do an entire GC in an incremental pause, just a small slice of the total work required for the GC. This is more difficult, because JavaScript executes between each incremental work segment, meaning that the state of the heap has changed, which might invalidate previous work that was done incrementally. As you can see from the diagram, this does not reduce the amount of time spent on the main thread (in fact, it usually increases it slightly), it just spreads it out over time. This is still a good technique for solving one of our original problems: main thread latency. By allowing JavaScript to run intermittently, but also continue garbage collection tasks, the application can still respond to user input and make progress on animation.&lt;/p&gt;
&lt;p&gt;增量（Incremental）指的是主线程间歇性地处理一小部分GC工作。引擎不会在一次增量GC暂停中处理整个GC流程工作，而仅只会处理GC需要做的工作中的一小部分。这非常困难，因为JavaScript在每次增量GC段之间仍旧在运行，这意味着堆内存的状态一直在改变，会导致之前做的增量GC工作无效。从图上可见，这不会减少主线程的GC工作时长（事实上，通常这更会稍稍增加），而是将工作散布到更长的时间段内。这对解决我们一开始的问题：主线程延迟问题来说仍旧是一个好用的技术。在保持主线程间歇性运作的同时，仍旧持续处理垃圾回收任务，应用程序得以继续响应用户的输入和处理动画等。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABH8AAAF1CAYAAABxiEZDAAAKC2lDQ1BJQ0MgUHJvZmlsZQAASImFlgdUVNcWhs+90xtthqH33jsMIL036VVUhgGG7jBUsSESVCCiiEhTAhiqgtFQJBZEFAtBQAELmkGCgPIMFkBF5V0giUneW+/ts/Y639p3n3/2nDtrzQ8AyZ3J4cTDAgAkJKZwfZxsZYOCQ2RxkwACRGSRgDSTlcyx8fJyB0j8sf89FkeRbiTuaa1q/efz/xmCEZHJLAAgL4QZLA43BeEDCPulp3BWeRxhGhcZCuH5VWavMYxe5fB1Fl3r8fOxQ1gTADyZyeSyASAykLpsGouN6BCDENZNjIhJRHhV35IVzYxA+CbCmlHxqRkIv1vtSUjYhtRJigirhv9Fk/03/fA/9ZlM9p+cEJ/K+v17rd4IOTLR3xfZxZGUBFFAG8SDVJABZAEHcME2pBKDVCKRu//v5xhr5+yQTg7YjpyIAWwQDVKQ845/0fJdU0oB6YCJ9EQiFXdk2a2+x3XJtw/WVCE6/muNQwfA1B4AVO3XWjgyZwcyhxjha02xHgB+5O7as1ip3LT12urVAwzy6+AHNCAGpIECUAVaQB8YA3NgDRyAK/AEfiAYbAEsZN4EZKp0sBPsBbkgHxwGx0A5qAK1oAGcAedAB7gIroIb4A4YBCPgMeCBKfASzINFsAxBEA6iQFRIDJKBlCANSB9iQJaQA+QO+UDBUBjEhhKhVGgntA/Kh4qgcqgaaoR+gC5AV6Fb0BD0EJqAZqE30EcYBZNhGiwFK8M6MAO2gd1gP3gzzIaT4Ew4Bz4El8I18Gm4Hb4K34FHYB78El5AARQJRUfJobRQDJQdyhMVgopCcVG7UXmoElQNqgXVhepD3UPxUHOoD2gsmoqWRWuhzdHOaH80C52E3o0uQJejG9Dt6F70PfQEeh79BUPBSGI0MGYYF0wQho1Jx+RiSjB1mDbMdcwIZgqziMVi6VgVrAnWGRuMjcXuwBZgT2Bbsd3YIewkdgGHw4nhNHAWOE8cE5eCy8WV4U7jruCGcVO493gSXgavj3fEh+AT8dn4EnwT/jJ+GD+NXyYIEJQIZgRPQgRhO6GQcIrQRbhLmCIsEwWJKkQLoh8xlriXWEpsIV4njhPfkkgkeZIpyZsUQ8oilZLOkm6SJkgfyEJkdbIdOZScSj5Erid3kx+S31IoFGWKNSWEkkI5RGmkXKM8pbzno/Jp87nwRfDt4avga+cb5nvFT+BX4rfh38KfyV/Cf57/Lv+cAEFAWcBOgCmwW6BC4ILAmMCCIFVQT9BTMEGwQLBJ8JbgjBBOSFnIQShCKEeoVuia0CQVRVWg2lFZ1H3UU9Tr1CkalqZCc6HF0vJpZ2gDtHlhIWFD4QDhDOEK4UvCPDqKrkx3ocfTC+nn6KP0jyJSIjYikSIHRVpEhkWWRCVErUUjRfNEW0VHRD+KyYo5iMWJHRHrEHsijhZXF/cWTxc/KX5dfE6CJmEuwZLIkzgn8UgSllSX9JHcIVkr2S+5ICUt5STFkSqTuiY1J02XtpaOlS6Wviw9K0OVsZSJkSmWuSLzQlZY1kY2XrZUtld2Xk5SzlkuVa5abkBuWV5F3l8+W75V/okCUYGhEKVQrNCjMK8oo+ihuFOxWfGREkGJoRStdFypT2lJWUU5UHm/cofyjIqoiotKpkqzyrgqRdVKNUm1RvW+GlaNoRandkJtUB1WN1KPVq9Qv6sBaxhrxGic0BjSxGiaaiZq1miOaZG1bLTStJq1JrTp2u7a2dod2q90FHVCdI7o9Ol80TXSjdc9pftYT0jPVS9br0vvjb66Pku/Qv++AcXA0WCPQafBa0MNw0jDk4YPjKhGHkb7jXqMPhubGHONW4xnTRRNwkwqTcYYNIYXo4Bx0xRjamu6x/Si6QczY7MUs3Nmv5lrmceZN5nPbFDZELnh1IZJC3kLpkW1Bc9S1jLM8jtLnpWcFdOqxuqZtYJ1hHWd9bSNmk2szWmbV7a6tlzbNtslOzO7XXbd9ih7J/s8+wEHIQd/h3KHp47yjmzHZsd5JyOnHU7dzhhnN+cjzmMuUi4sl0aXeVcT112uvW5kN1+3crdn7uruXPcuD9jD1eOox/hGpY2JGzs8gaeL51HPJ14qXkleP3ljvb28K7yf++j57PTp86X6bvVt8l30s/Ur9Hvsr+qf6t8TwB8QGtAYsBRoH1gUyAvSCdoVdCdYPDgmuDMEFxIQUheysMlh07FNU6FGobmho5tVNmdsvrVFfEv8lktb+bcyt54Pw4QFhjWFfWJ6MmuYC+Eu4ZXh8yw71nHWywjriOKI2UiLyKLI6SiLqKKoGbYF+yh7NtoquiR6LsYupjzmdaxzbFXsUpxnXH3cSnxgfGsCPiEs4UKiUGJcYu826W0Z24Y4GpxcDi/JLOlY0jzXjVuXDCVvTu5MoSF/nv2pqqnfpE6kWaZVpL1PD0g/nyGYkZjRv119+8Ht05mOmd/vQO9g7ejZKbdz786JXTa7qndDu8N39+xR2JOzZyrLKathL3Fv3N6fs3Wzi7Lf7Qvc15UjlZOVM/mN0zfNuXy53Nyx/eb7qw6gD8QcGDhocLDs4Je8iLzb+br5JfmfClgFt7/V+7b025VDUYcGCo0LTx7GHk48PHrE6khDkWBRZtHkUY+j7cWyxXnF745tPXarxLCk6jjxeOpxXql7aWeZYtnhsk/l0eUjFbYVrZWSlQcrl05EnBg+aX2ypUqqKr/q43cx3z2odqpur1GuKanF1qbVPj8VcKrve8b3jXXidfl1n+sT63kNPg29jSaNjU2STYXNcHNq8+zp0NODZ+zPdLZotVS30lvzz4KzqWdf/BD2w+g5t3M95xnnW35U+rGyjdqW1w61b2+f74ju4HUGdw5dcL3Q02Xe1faT9k/1F+UuVlwSvlR4mXg55/LKlcwrC92c7rmr7KuTPVt7Hl8Luna/17t34Lrb9Zs3HG9c67Ppu3LT4ubFW2a3Ltxm3O64Y3ynvd+ov+1no5/bBowH2u+a3O0cNB3sGtowdHnYavjqPft7N+673L8zsnFkaNR/9MFY6BjvQcSDmYfxD18/Snu0/DhrHDOe90TgSclTyac1v6j90soz5l2asJ/of+b77PEka/Llr8m/fprKeU55XjItM904oz9zcdZxdvDFphdTLzkvl+dy/yX4r8pXqq9+/M36t/75oPmp19zXK28K3oq9rX9n+K5nwWvh6WLC4vJS3nux9w0fGB/6PgZ+nF5O/4T7VPpZ7XPXF7cv4ysJKyscJpe5ZgVQSMJRUQC8QXwCJRgA6iDihTate67f/Qz0F2fzB4Pm6q8c7Lruy9bCGIDabsT+ZQHgjuxlyK6MJL81AF5I+lkD2MDgz/w9kqMM9Nc/g9SBWJOSlZW3gQDg1AD4PLaystyxsvK5Dhn2EQDdi/93tn/wuh9cDYHTAFhP2zt7u4+512WBf8S/AdwKvhejnMT0AAABnmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMTUxPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjM3MzwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgpkyREBAABAAElEQVR4AeydB5gcxbW2z0hCWUI5owAogggWQuQggrHBRGMwYMARAw74YrjXxoF7uRhjX36SjcnBmGADJuecEYgkQEIBSSChnFBOaP7z9W7P9szO7M7Mzu5OeOt5ZqdTVVe9XT3b9fU5p2JxT0aCAAQgAAEIQAACEIAABCAAAQhAAAIQKEsCLcqyVTQKAhCAAAQgAAEIQAACEIAABCAAAQhAICCA+ENHgAAEIAABCEAAAhCAAAQgAAEIQAACZUwA8aeMLy5NgwAEIAABCEAAAhCAAAQgAAEIQAACiD/0AQhAAAIQgAAEIAABCEAAAhCAAAQgUMYEEH/K+OLSNAhAAAIQgAAEIAABCEAAAhCAAAQggPhDH4AABCAAAQhAAAIQgAAEIAABCEAAAmVMAPGnjC8uTYMABCAAAQhAAAIQgAAEIAABCEAAAog/9AEIQAACEIAABCAAAQhAAAIQgAAEIFDGBBB/yvji0jQIQAACEIAABCAAAQhAAAIQgAAEIID4Qx+AAAQgAAEIQAACEIAABCAAAQhAAAJlTADxp4wvLk2DAAQgAAEIQAACEIAABCAAAQhAAAKIP/QBCEAAAhCAAAQgAAEIQAACEIAABCBQxgQQf8r44tI0CEAAAhCAAAQgAAEIQAACEIAABCCA+EMfgAAEIAABCEAAAhCAAAQgAAEIQAACZUwA8aeMLy5NgwAEIAABCEAAAhCAAAQgAAEIQAACiD/0AQhAAAIQgAAEIAABCEAAAhCAAAQgUMYEEH/K+OLSNAhAAAIQgAAEIAABCEAAAhCAAAQggPhDH4AABCAAAQhAAAIQgAAEIAABCEAAAmVMAPGnjC8uTYMABCAAAQhAAAIQgAAEIAABCEAAAog/9AEIQAACEIAABCAAAQhAAAIQgAAEIFDGBBB/yvji0jQIQAACEIAABCAAAQhAAAIQgAAEIID4Qx+AAAQgAAEIQAACEIAABCAAAQhAAAJlTADxp4wvLk2DAAQgAAEIQAACEIAABCAAAQhAAAKIP/QBCEAAAhCAAAQgAAEIQAACEIAABCBQxgQQf8r44tI0CEAAAhCAAAQgAAEIQAACEIAABCCA+EMfgAAEIAABCEAAAhCAAAQgAAEIQAACZUwA8aeMLy5NgwAEIAABCEAAAhCAAAQgAAEIQAACiD/0AQhAAAIQgAAEIAABCEAAAhCAAAQgUMYEEH/K+OLSNAhAAAIQgAAEIAABCEAAAhCAAAQggPhDH4AABCAAAQhAAAIQgAAEIAABCEAAAmVMAPGnjC8uTYMABCAAAQhAAAIQgAAEIAABCEAAAog/9AEIQAACEIAABCAAAQhAAAIQgAAEIFDGBBB/yvji0jQIQAACEIAABCAAAQhAAAIQgAAEIID4Qx+AAAQgAAEIQAACEIAABCAAAQhAAAJlTADxp4wvLk2DAAQgAAEIQAACEIAABCAAAQhAAAKIP/QBCEAAAhCAAAQgAAEIQAACEIAABCBQxgQQf8r44tI0CEAAAhCAAAQgAAEIQAACEIAABCCA+EMfgAAEIAABCEAAAhCAAAQgAAEIQAACZUwA8aeMLy5NgwAEIAABCEAAAhCAAAQgAAEIQAACiD/0AQhAAAIQgAAEIAABCEAAAhCAAAQgUMYEEH/K+OLSNAhAAAIQgAAEIAABCEAAAhCAAAQggPhDH4AABCAAAQhAAAIQgAAEIAABCEAAAmVMAPGnjC8uTYMABCAAAQhAAAIQgAAEIAABCEAAAog/9AEIQAACEIAABCAAAQhAAAIQgAAEIFDGBBB/yvji0jQIQAACEIAABCAAAQhAAAIQgAAEIID4Qx+AAAQgAAEIQAACEIAABCAAAQhAAAJlTADxp4wvLk2DAAQgAAEIQAACEIAABCAAAQhAAAKIP/QBCEAAAhCAAAQgAAEIQAACEIAABCBQxgQQf8r44tI0CEAAAhCAAAQgAAEIQAACEIAABCCA+EMfgAAEIAABCEAAAhCAAAQgAAEIQAACZUygVRm3rdGatnz5cps8eXJQfrdu3WzkyJF5nWvLli02a9YsmzdvnnXu3Nm2335769ChQ15l5Zvp7bfftnXr1pnqMnbsWGvXrl2+RVVUvk2bNtknn3xiS5cutXg83qC2x2Ix22mnnaxTp051lrN27VpT31u9enVwvdq0aWNdunQJPi1aoOPWCY+dEIAABCAAAQhAAAIQgAAEKpgA4k8eF//hhx+2J554IsipAfuVV15pbdu2zbmk2bNn25/+9CdbtWpVkPeb3/ymHXvssTmXk28GiQmXXXZZIvv69evt0EMPTayzkJnAxIkT7ZprrrEvv/wy80E57Dn++OPtmGOOSZtDYs97771nEyZMMPUZCU4SjCT4DBs2zPr3728HHnigDRo0KNiWthA2QgACEIAABCAAAQhAAAIQgEDFEkD8yePSd+zYMZFL4k++VhcSWyTAhCm6HG5rzG9Z/ISpVatWgaAQrvNdN4GNGzcWTPjRmVq3bp32hHPmzLE777zT3n///aT9sjaS8DRlypTg89prrwXCocQ7XUsSBCAAAQhAAAIQgAAEIAABCEAgJMAoMSTBNwRyILDddtsFbnKLFi2yrbbaKimnRBlZ56xcuTKxXccMHDgwrcAmy69evXoljg0XJOzIukhl1ZckHP7jH/+whQsX2qmnnmotW7asLwv7IQABCEAAAhCAAAQgAAEIQKBCCCD+VMiFppmFJTBgwAD7xS9+kbFQCT8//vGPg/2yDDvttNNs/PjxGY9P3fHpp5/aX//6V1u2bFmwS25effv2tX322ce6du0axP1RvCjFbNqwYUMi+9NPPx0ISV//+tfTCk2JA1mAAAQgAAEIQAACEIAABCAAgYohgPhTMZeahjYlgai1juJB5eKKJZeyxx9/PCH8yCXssMMOs6OPPrpWbClZ+sgt7K233ko074EHHrD999/fou6JiZ0sQAACEIAABCAAAQhAAAIQgEDFEWCKoIq75DS42AnIokcfJVkNKQj4iSeeWEv40f7evXvb2Wefbdtss41Wg7RmzRp74403wlW+IQABCEAAAhCAAAQgAAEIQKDCCSD+lEkH0NTjmzdvbrbW6PyyWCmlpKDJqnehZuwqVNv79etno0aNCqZ+Hzx4cODqVVfZsgw64ogjkg6ZN29ekjtY0k5WIAABCEAAAhCAAAQgAAEIQKCiCOD2VaKXW8KFgvwq4LCsRJYvXx7EeFFcmB122ME6d+5csJZJHAmnFo8WKrFJs1Hp/EuWLAmO0exn22+/vSkgsvLkm9Q+TXE+f/58U/wbtU9BkyWGDB8+3Nq3b59V0enqvmXLlqDOL774YlC+WA0dOtT222+/rMvN6uR5HiSGihGk6d81I1y3bt3qLWnEiBFBkOdQyJL1j2Zza9OmTb15OQACEIAABCAAAQhAAAIQgEBjEfjoo4+CMWpjlU+52RFA/MmOU1Ed9dJLL9ljjz1msu6QkCGhRLM76VvrijGz00472ZFHHmlDhgxpUN3POeecQNhRuZpG/KSTTgpEJwUWVj0UkDgqDIVii6xXJGBIiMolyRJH8W6eeeYZW7FiRdAe5Q+FJNWjQ4cOtvfee9vhhx9uPXr0yFj8ueeeawsWLAj2i4cCNCv/bbfdZq+++mrCUkplv/7660Gg5K985SsZy2vqHRK4shW5dM0ljoXij0QfhJ+mvmKcDwIQgAAEIAABCEAAAhBIJXDdddcFYxWN4fRR6ApS0xNA/Gl65nmfUVOCX3/99cEMT2Ehigkj4Ueihj5KsviYMGGCTZo0KRBIjjrqqLyn/t56660D6yKVq6DFzz//vD344IOBMKNtYZLwFAoPWp47d65dfPHF9tWvfjUQjFKnQw/zRb9lRfS3v/0tsPRRGUpqnz4qO9wmi6Ann3wyEJ/OPPNM22233aLFJJa7dOkSWPZog8SRd9991+6//3777LPPEsdoQeWG4lnSjhJakVAWdbuTtVC7du1KqAVUFQIQgAAEIAABCEAAAhAoVwLy6Lj33nuDj17MSwTaa6+98h6nliunxmwX4k8D6UZFiVyLkgVLtunzzz+3yy67LGHJogC/ms5bsWEU80X1mD59eiCKTJ06NRA0JAJJ7JAocMIJJySsZ7I9p44LLW60LPFE7kSaxlxJYtC4ceNs9OjRgZIrwUdTj0fFFYk0EmvOOuuspLKCAiJ/Jk6caDfffHMgKkns2Xnnne2QQw6xQYMGBT8Ims78gw8+sIcffjghRql9l19+uf3sZz8L6hEpLliUoBMmWUk9+uijibrJokYuchK3Fi9eXPLxcWTJFIp/arP4kSAAAQhAAAIQgAAEIAABCBQbARkp6HPrrbcGApCEIIWxIDUuAcSfBvL94osvAlFi2LBhOZUkMWPmzJkJa5m6MuvYa6+9NiH8SCmV4JHqEiQhZsyYMfbUU0/ZP/7xj6BIiUJyoVKcnF133bWu09S7T2ptmHRznnLKKUEMHok1SjqXAg+///77dtNNNwVCkbZLmOjVq1cQw0brqUkxg3Tjy3pFgo2mNdcMV6mWKwcddFAQ/Fgi0csvvxwUI6sduXEpzlD37t1Ti06sy6pISRZIKlvxfVS+6iyBS7F1chHjEgUXwYK46RqHScJg//79w1W+IQABCEAAAhCAAAQgAAEIFB0Bvcx/9tlng4/GMKFbWF3juqJrRAlVCPGngRdLosHVV18dzMwUiiDZFKlgybKIySZJPPnkk0+CQ/v06WM///nPawkjYTmyxpGrlcp+4IEHgs0KDC0LIMXfkZVQQ9PYsWPte9/7XmA1Ey1Lwo0ElT322CPYd80119jSpUuDQ3T+XXbZJQisHM0j8Ub1VOwgpd133z2t8BPmURybM844wyS6SS1WkvjxxBNPBO5lUUulME/4rbzf/e53A+En3BZ+pwpp4fZi/5Z4JeFM1zhM3/jGNwpyncPy+M6NgCzgFEOKBAEIQAACEIAABCAAAQhY0lglykNjwXD8ppf1d999d/CR0ULoFhY9nuWGEUD8aRi/ILeCFIfiRQGKSypCZct1Kkzf+c53Mgo/4TESYeQSNm3aNJs8eXKwWQNSuU3JMqghScG5NAuV3KXqSiNHjgxEmksvvTRh3SS3KwlX4Q2u/DNmzAjc1bSsODWqd6rFj/ZFk0S2s88+2375y1+a4iApKRaRYht17NgxemjSsiyj9txzz6Rtpb6i+EtvvvlmohmKfyTxjdS8BCR2kiAAAQhAAAIQgAAEIACBzASi48LoUQo3oo9ecisukIQgzc5MahiBKn+dhpVB7kYkoGnOQ5clxaiRy1c2SZYs+++/f+JQWSjpBmpokuvVgAEDsipGlkb77LNP4ljFAwotgcKNst6R5Y6ShIuBAweGuzJ+SyHWdOj77rtvQkiS5YuEpExJFlESRbIJPJ2pjGLbLtFHQdPC1LNnz8AiS20lQQACEIAABCAAAQhAAAIQKAUC6UQgxX6VR4NmsEb4KcxVZJTYQI7qqHJV0tTmubh9KTjv7Nmz6xVkQtcmVVNWN1OmTAkC+8ptTCJIuqQ6SQCIxujRcaGIlC5PNtvkcpZLIGHVQ5Y8L774YlC8XJTkvhadnv3jjz9OnFqxjWSpJI7RmasSB1QvaL9m70ploLLkWpYuacp7XaNySeoXmvktTIpXdM4555hmOCM1LwGJtLfffnvzVoKzQwACEIAABCAAAQhAoEgI/OIXv7AlS5Yk1Sbq8hWOa2XAIEsffQgAnYSrICuIPw3E2LlzZ/v2t78dBDTOtSi5Yb333nsZRRwFwJLlT5h0rD75Jln/SDDJ1zJEVjkKxJVLUqBnuWKF8Y3UHrlfKUngWb58eaI4iUShUJTYmMPCwoULg/Okc/2SS5nqUg5Jwo/iKYVxfiSEKQaTBC5S8xOIzjLX/LWhBhCAAAQgAAEIQAACECg+AlFrH73AD927otuLr9alXSPEnwZeP6mT+VpbKLaNrFhkEZMuSRzRFO+FShJgVGa+4k8+Udc1EFZ8oFD8kdgj0ULc9J2p7fm0WeeITnceLUMCSTkkWTddd911tnLlyqA5apfiQBHnpxyuLm2AAAQgAAEIQAACEIBAZRDQ7MSh4FMuL+mL/coh/jTwCjVEmazLtUnVUrDn0LojrKZmrMonKdaNpkPPV/jROfOZKUwmfFFBRoGxQ8FHVkipKd/2yQJLlkmZgkXn4pKXWqdiWZ85c6ZpmvvQWkptPfnkk+2AAw5IxD4qlrpSDwhAAAIQgAAEIAABCEAAAlECGutpAh4FcFZ8WFLTEkD8aVreOZ1NVjOykAkDIm+77bZ21lln1RKEsilU4ocEknwEnLD8VCEq3F7fd1h/HSfxKXSLSRWiFKBa09RLLIoKRvWVH5YrC6NyCugcbbdiJd1www2mWduU1C9OPPFEGz9+fPQwliEAAQhAAAIQgAAEIAABCBQVAcWuPe644wJLn3IdrxUV8AyVQfzJAKYYNkuo0Y0yb968oDoKiNycQYtVD1mddO3aNWs8X3zxhSnWUJg0U1h4w0vACIUg7Zc4pZhC0W1hvkr+njVrViD8fPbZZwEGBXc+4YQT7OCDD65kLLQdAhCAAAQgAAEIQAACECgBAhdccEEJ1LL8q8hU70V8jTXIj059vnjx4rysfgrVRM00lmsMonfeeScpoLXaE4o/Erck+IRJbk35WheFZZTbtwQfuXqFwo8Es29961sIP+V2oWkPBCAAAQhAAAIQgAAEIACBRiSA+NOIcAtRdNQXUjGC3nrrrZyKVWDgMDhwThnTHCxXrJdffrnOadij2TRb2aOPPprYpPhIijsUTdEZqqZOnZrzdPSyilFspHJMEtok/MjlS0nCjyx+DjnkkHJsLm2CAAQgAAEIQAACEIAABCAAgUYigPjTSGALVazi/CiWTZgeeOCBrMUXCSOaGUqfjz76KCyiQd8Sf1577bV6y1BQ53vvvddkrRSm4cOHW48ePcLV4HvXXXcNRA2tKAC0yk4XCDopU/WKpr3/85//bNdff70tXbo03SElu23+/Pl2yy232LRp04I2hBY/Bx10UMm2iYpDAAIQgAAEIAABCEAAAhCAQPMQQPxpHu5Zn1WD/iOPPDJx/MKFC+3OO++s19pFws/f//53k0Cij4SEbEWVxMkyLNx+++02YcKEJHeu6KGK8fPwww/bk08+Gd0cBHNOjeczatQoGzp0aOK45557zl544YU6Az5LWPrwww/txhtvDIJhv/rqq3bbbbcVrH2JyjTTwpIlS+ymm26yyZMnJ2ogC7CRI0famjVrTMKQrIIyfRYsWBAcl8jMAgQgAAEIQAACEIAABCAAAQhUNAECPpfA5VdgX8XbmThxYlDbp59+2lavXm0nnXSSabq8cOp0zeglVysdJ3crTasepsGDBzdomneVo1g9cv3SOa699lqTEKVp+rRddZC4pNg0r7zyir355ptJ4pDcvcaOHRtWJ/GtOp922ml2+eWXJ1y+5OokSx65N6l9mi5eH7mNSVh65JFH7MUXXzQFwA7TmDFjGty+sKzm/paYFRV+VJ/3338/ELyynQVNgtp//Md/WNu2bZu7OZwfAhCAAAQgAAEIQAACEIAABJqZAOJPHhdAQkSYQuElXM/lW2KGPvUliSua4v2qq64KrHh0frlHvfHGGzZo0KDALUz1kMWIPqkxcBRX5/TTT691mui5o22qdWD1BlnpSKyZNGlSILz885//tMcff9w6duwYiFESpNLx6Natm/3gBz8I8qYru0+fPnbOOefYFVdckRCAHnzwQXvsscdssItWCnwt0UeCkNqXWleJY/vuu2+toqMc0tWrVoZG2pDrudNZaCneUy5pxowZwTVB/MmFGsdCAAIQgAAEIAABCEAAAhAoTwKIP3lc16j1RVRgyLWoVq1aWc+ePQM3HuWVyJEpaRB/9tln2x133BEEXZagoHrIvStdkrCjPLK2kfCTTgTQ+XWcxBSV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VLdsT5n7yLpsUZRWwzRV+cEHH9wgAachLZaLlqacj7px1VeeZiuLBrWOWh7JEklBqcNYSTIBRA2ujyj7IQABCEAAAhCAAAQgAAEIFDeB//3f/y3uClZI7eqOvFQhEEqlmYqzEybFyMnV6ibMW4jvSZMmBQGjcynro48+SgrMLOulMKltUSumaPyf8Bi+IQABCEAAAhCAAAQgAAEIQAACEMidAOJP7syaLcfIkSMT5541a1YwnXliQxMvyELnySefzPqsOv65555LWPYoo9y6wjR06NAkK6LJkydbPB4Pd/MNAQhAAAIQgAAEIAABCEAAAhCAQJ4EEH/yBNcc2Xbcccek6dVTxZS66iTx5cYbb7R77703aVatuvLUt+/ZZ5+1p556qr7Dgv333XefaTr3MHXv3t0GDBgQrgbT1e+6666JdVkJyboo2/T222/bDTfcYG+99Va2WTgOAhCAAAQgAAEIQAACEIAABCBQEQQQf0roMvfr1y8IkhVW+bXXXstKfFGA57vuustefvlle/DBB+3yyy8viACkcv/1r3/ZSy+9FFap1resd5544gl7+umngwDR4QEHHnigdenSJVwNvnffffdEADDFE7rnnntM7m31pZkzZ9rf//53e+GFF+xvf/ubPfbYY/VlYT8EIAABCEAAAhCAAAQgAAEIQKBiCCD+lNilVpT0wYMHJ2otUefuu++2L774IrEtuqAp1K+77jp75plnApcrCTYK0ty+ffvoYXkvS6S59dZbgzrMmzcvqRwFeL722muDfZqBK0yaZWzfffe11Bm+Bg0aZEcccUR4mEnU+ctf/mIffPBBYlt0QbONydLnqquussWLFyfcxPr06RM9jGUIQAACEIAABCAAAQhAAAIQgEBFE2C2rxK7/D179rRTTz01EEWWLVsWWNM89NBDNmHCBFNMILlSSdiR2PL555/be++9F8ywFcbP6dSpk51++ukNFn+GDRtma9asCc6h6dtVB1nedO3a1Vq3bh3MBCZBSseE5xZqzeh1xhlnmNqRLh166KFBfR9//PFg94wZMwJLJQleOqfcxSQaqex33nnH5syZYxs3bkwUpRnQRo8enVhnAQIQgAAEIAABCEAAAhCAAAQgUOkEEH8a2AM2bNiQKKFdu3a1rFkSO+tZiMViwexdsmZRkoVOpjRixAj70Y9+ZHfccUcgfui4hQsX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mRh/XgIsYr2cht3//u//5vI64YQTpom+KnHe+ta35uflZS972apcf31e9NJLL833yrusi/AMv+51r6te9apXVX/84x+7RJn7MGvlWWwWxGo/m/PyXmpymfb3hnY/03KYJt7HPvax6oADDqjOPvvsaaIbRwISWEECV1jBtE1aAnNP4MQTT6x22GGHoXxe97rXrU466aT89773va961KMeVb397W/PHeqhgKvwIzrndNhD2o7FueXYXnzxxTmZLgP55bjepDTmLT+T8vvhD3+4QhlSykMf+tDqlre8ZXloyf5gMMhKySOOOKI69dRTh87/9a9/zb+j7IdOrqcfv/zlLyvu4ytf+Up9xfLZ4b5f/OIXVx/60Ida75VyRGmE8ijkale7WvXjH/84/x199NHVC17wguojH/lI9c///M8RZOJ2HLeJkWcIsGj1ctpb3XvvvavTTjstl8ssCuHzzjsvDw6ow29729umzU6nePG8zEsb1inTUwai/iO//e1vO6XwyU9+snrKU56Sw/793/999eAHP7hTvLZARx11VPX85z+/ev/731/d/OY3bwuybMfG1Z+18iw2YS7Xs9lMt/w9rn2N52w130tlXmfdj/ZiQ7mfWXk044963n/1q19Ve+65Zw5+wQUXZOVyM66/JSCB1SOg5c/qsffKq0wAi5/73ve+ORf//d//XX33u9+t/vSnP1W8uOg8vvGNb8znGJxihaBIYBoCH/jAB3I0rMvOOeecis4QX6YnyWWXXVY997nPrX72s59NCrrez6OgQWmK4udWt7pVtpD73e9+l58dOsqf/vSnq9vc5jbVD37wg+o+97lP9etf/3oojzxfO+20U1b8oPCB0S9+8YuKNLhvnkUGoTyj9773vas+SoZ55jYEYUF//Mu//EvO+Y477jjTHVCmb3jDG6o//OEPM6Vj5NkIlEqam93sZjMlxnuSDyehBJgpsQmRrT9LAS3Xs7k05cuP2L5ezmKt74163q997WtX22yzTcaDFb0iAQnMFwGVP/NVHuZmPRI45phjqp///OfVHnvskS0seEmtW7cu5+AqV7lK9W//9m/VO9/5zvwbk3hFAtMQ+NSnPpWjYeVyvetdr9p8883rejZNevMQ57/+67+yYgYFzf/8z/9Ud7nLXSqUOMgVr3jFrNz68pe/XN3+9rfPz9jLX/7yoWxHp3H77bfP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&quot;&gt;
&lt;h3 id=&quot;concurrent&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#concurrent&quot; aria-label=&quot;concurrent permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Concurrent&lt;/h3&gt;
&lt;p&gt;Concurrent is when the main thread executes JavaScript constantly, and helper threads do GC work totally in the background. This is the most difficult of the three techniques: anything on the JavaScript heap can change at any time, invalidating work we have done previously. On top of that, there are now read/write races to worry about as helper threads and the main thread simultaneously read or modify the same objects. The advantage here is that the main thread is totally free to execute JavaScript — although there is minor overhead due to some synchronization with helper threads.&lt;/p&gt;
&lt;p&gt;并发（Concurrent）是指当主线程在不停歇地运行JavaScript的同时，辅助线程在后台处理垃圾回收工作。这是三个技术中最难实现的一个：JavaScript堆内存可能在任何时间点发生任何改动，使得垃圾回收器之前做的工作失效。此外，还有读写竞争的问题需要考虑，因为辅助线程和主线程可能同时在读取或修改同一个对象。优势则是主线程完全从垃圾回收工作中解放出来，得以全身心处理JavaScript执行工作 - 虽然和辅助线程之间同步状态会有小小的额外开销。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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8LVvfvObTJSckXeLRiGAAAIIIIAAAggggAACmStAsNMB92bcuHGmyXH98uCDD0aWt/a3NfWsQODXv/61XXbZZfbEE0+kZRiX5sq55ZZbEuo5tGLFCrv77rujzqugKjj8Sj1Pxo4dG7kEBTRTp06NvG/pxeuvv25XXnml/fKXv7R58+a1tHvoPleQd91115nmKVKR17e//W2bMGFC1DC90F0YDUYAAQQQQAABBBBAAAEEEGh3AYKddic3rzfLwQcfHDmz5lm58847W+yFo6E7f/zjH72lxTdu3GhPP/20LVu2LFJPa14sX77c/vd//zdqQuTY+hQqXXPNNablx/3Sq1cvb/Zy/73/fNBBB9nw4cP9t/b888/bjBkzml35Sz11Zs6caXfddZcXMqnXjkKvjpyDKHIBaXqhUOeqq66y1atXR2o85JBDTL2cdL36XHMeNffQJMvJrqAWORkvEEAAAQQQQAABBBBAAAEEskqAVbE66HaeeeaZtmHDBnvnnXe8H+kKNDRkSbOCawUpzVGjSZYVaih0eeWVV7xgxB+epB/2o0ePtsGDB7f6CtRjRGGNzvOrX/3KzjnnHBszZozXq2j79u1eu+bMmWOvvfaaVVZWRs6n9n35y1+OGoblf6g6L7zwQvvDH/5gCqFUpkyZYuqNc/jhh3s9evxePlVVVaaVoZ599ll7++23vaXUtb+uUaFHNi11/v7770d66ugaVV544QV74403TMOxghNrf/Zp4/9VTx/12DrggAMaf8gWBBBAAAEEEEAAAQQQQACBnBIg2Omg260Jhi+44AK74447IuGOemv885//tMcee8wb2uQHLlo5S+FHsJeGgpezzjrLiouLW3UFWo78iCOOsIULF3o9RtatW2c33XSTN8Gzhott27bNO3fsnD4KIE488UTv2KbCiEGDBtkvfvELu/rqq70QS+3XeRTi/Otf/7JOnTp5QYauTeeJPccJJ5xgkyZNatX1ZdrButbY5eXlogBNj0SLH/Aluj/7IYAAAggggAACCCCAAAIIZKcAwY67r1pqTQGHfnArpFCgkmrRD3e/KKxormglKfVqefTRR+2ZZ57xeueoh46Oa+pYtU2rJqmnjN/jJXgOXYuG9fjHaxWupoIXHadrVq+YY445xh544AGbP3++N2mxehPFK+o9oyFWJ510kmmuINXfXFG4o15A//jH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Dz7w7nePHj2sX79+3vWpp1VrisK96dOne3MtFRcX29ChQ2306NG2zz77tFit7vf7779v69evj+wr9+HDh9vIkSNT6nm1adMmmz9/vi1btsy0/Lvum65R3yU9hgwZ4rUxcsIkX6xcudJz1HdEpbCw0GvvHnvs4X1nkqyO3RFAAAEEEEAAAQQQQACBlAX0e16/88aMGZPS76eUT5ylB4Yq2NGKUaNGjbIFCxZ4t+PFF19MKtjRD/F33303civ3339/U507duyIbGvphb6At99+uxcqKWBqrowfP94uuOAC69KlS5O73X333fbUU09FPr/jjjsa/dBW8PT44497+2jI1tVXX+29Xr58uf397383PccrCpq+/e1v20EHHRTv44zcpsBBRT2y7rrrLtu6dWvcdipE0aTNw4YNi/u5Nt52220WXP3s3nvv9f5PY+bMmTZlypSonlvz5s2zd955x6688som61OApuP871+8HWWusHDixIlRQwfj7attCq/0HVDgqNfNlX333de+853v2G677dbcblGfKShSm5csWRK13X9TUFBgRx99tJ1xxhnWrVs3L/DxP+MZAQQQQAABBBBAAAEEEGgLAf0G/8Mf/uB1jtC0K/pNkszvnLZoU5jrDM1QLAUqKppo2C/qNbFu3Tr/bYvPmjQ5GMb4dfl1t1SBzvXLX/7SFAwE62nquNmzZ9tvf/tb27x5c1O7pLxd13LFFVc0Geqo4o0bN9p1111nCi3CUDp16mQKGh566CG78cYbmwx1dC3qyfO73/3OFi9enNSlzZkzx2666aaoUCeRCnTcz3/+82ZDHdUj82nTptnPfvYzr43N1V1RUWH//d//bc8880yLoY7qUSip75MCpkSK5pL61a9+1WSoozoUJum7dOmll3qWXbt2TaRq9kEAAQQQQAABBBBAAAEEWi2g30+PPvqoXXLJJd5vHf2GSabjRasbkCUVhCbY8W/uuHHjonpCBIdWNXdPFMQE99UwF78nSyJz7Ki3z69//WtbtWpVo9OoLq3Qtffee5smQg4W/Qi/9tprE/rhHjyuudf6Ia6ePYm0W9f9l7/8JWrYUHN1d+Rn6jGi4VEPPvhgQsGZrv+aa65JODjTPfzrX/+aUN1Bh9dff93+9Kc/meZ58ouGbZ1++uneQ71ztFR9sCjMUwLdVPCooWAKaRYtWhQ8zHutcMX/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EpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspGvQGXgAQkIAEJSEACEpCABCQgAQlIYOwEVOyMPQb1vwQkIAEJSEACEpCABCQgAQlIQAIrS0DFzspG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&quot;&gt;
&lt;h2 id=&quot;state-of-gc-in-v8&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#state-of-gc-in-v8&quot; aria-label=&quot;state of gc in v8 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;State of GC in V8&lt;/h2&gt;
&lt;h3 id=&quot;scavenging&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#scavenging&quot; aria-label=&quot;scavenging permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Scavenging&lt;/h3&gt;
&lt;p&gt;Today, V8 uses parallel scavenging to distribute work across helper threads during the young generation GC. Each thread receives a number of pointers, which it follows, eagerly evacuating any live objects into To-Space. The scavenging tasks have to synchronize via atomic read/write/compare-and-swap operations when trying to evacuate an object; another scavenging task may have found the same object via a different path and also try to move it. Whichever helper moved the object successfully then goes back and updates the pointer. It leaves a forwarding pointer so that other workers which reach the object can update other pointers as they find them. For fast synchronization-free allocation of surviving objects, the scavenging tasks use thread-local allocation buffers.&lt;/p&gt;
&lt;p&gt;如今，V8使用并行scavenging将新生代的垃圾回收工作分发给辅助线程执行。每个辅助线程会收到一些指针，需要它们处理，快速地将存活对象拷贝到To-Space。当清理一个而对象的时候，scavenging任务必须通过原子性的 读/写/比对清理（compare-and-swap）操作来同步状态；其他的scavenging任务可能会通过不同的路径定位到同一个对象，并也想处理它。无论哪个辅助线程成功完成了对这个对象的操作都会返回并更新对应的指针。一个forwarding指针会被保留下来，其他辅助线程可以根据它们找到这个对象的指针进行对应的更新。对无需同步状态的存活对象进行的内存分配，scavenging任务使用线程本地的内存buffer来处理。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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lh566CGbNGlS2qF6+5555ploqFW9nb6h1aVmzJhhmoxZc/aMHDkyGtL14IMPpi4lrtWvih1Lll2ubU2UrPpr9n2COuVSpRwEEEAAAQQQQAABBBBAAIFKFyCwU+l3qAn107AnTVKswM7dd99tq1atqj3riSeeiJYdvPfee2v3FfugoUyXXXZZNJdOyKO5aq6++upobpxPfOIT0W4Fd770pS+ZVtG66qqrorl24vnVc0ZzWMTrEY63xPstt9xiTz75ZLS04gEHHBAFohSMir/UNhICCCCAAAIIIIAAAggggAAC1SbAUKwquaP//u//blpi8Pbbb4+CKsOGDbM1a9ZEwZdtt93WNFt9YykERS688MJoyJWGeGkFLA3B+upXv2pDhw6tLUKTEp944onRRMXnnHOOafWLHj16RPk1l88pp5xScqLm2oLK8OHpp5+OSpk1a5ZdeumlqSVefvnl1r1799Rj7EQAAQQQQAABBBBAAAEEEEAgqwIEdirozml8qib13GGHHUrWSssHfvjhh/XyKPjy7W9/29544w3TMuNz5syJ5tvREuh77713vdWoNDeOrhNfilSFKRD0k5/8xF544YUoQLNo0aJoBacxY8bYZpttVu962tCwJ/UW0hCot956y7p06WJ77bVXNBt+PIii/WeeeWYU+GlQSBN2DBo0KKqvrpWWtLx6Y72DNLk0CQEEEEAAAQQQQAABBBBAAIFqE8gtW7YsX22Noj3NE9DEyOeff34UqFEvHBICCCCAAAIIIIAAAggggAACCGRDgDl2snGfqCUCCCCAAAIIIIAAAggggAACCCDQQIDATgMSdiCAAAIIIIAAAggggAACCCCAAALZECCwk4371KK17Nq1q+2000625ZZbtuh1KBwBBBBAAAEEEEAAAQQQQAABBMorwBw75fWkNAQQQAABBBBAAAEEEEAAAQQQQKDVBOix02rUXAgBBBBAAAEEEEAAAQQQQAABBBAorwCBnfJ6UhoCCCCAAAIIIIAAAggggAACCCDQagIEdlqNmgshgAACCCCAAAIIIIAAAggggAAC5RUgsFNeT0pDAAEEEEAAAQQQQAABBBBAAAEEWk2AwE6rUXMhBBBAAAEEEEAAAQQQQAABBBBAoLwCBHbK60lpCCCAAAIIIIAAAggggAACCCCAQKsJENhpNWouhAACCCCAAAIIIIAAAggg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0e7DDz/cunXrlsxSb/utt96y1157Ldp38MEHW58+feodb8rG888/bwsWLLBx48ZZ586dm3JKyTzPPfeczZkzp2QeHdx7771t6623tieffDK6/tFHH22dOmX3q/XKK6/Y22+/bQcddJBtttlmjbafDAgggAACCCCAAAIIIIAAAgi0lUB2n77bSqyJ11VQZ+LEiVHuvn372tixY0ueeeedd9qrr74a5dlzzz2bHdhZu3at/fGPf7T169dbv379bL/99it5vaYcfPbZZ+3FF19sNOugQYNqAztTpkwxBbKyHNh5+eWX7dFHH7U99tiDwE6jd58MCCCAAAIIIIAAAggggAACbSlAYKcV9BUkKBXYWbJkSW1vnY2tjnrobLXVVjZ37lwbPHjwxhZT77zjjjsu6v0Tdt57771R8OnEE0+0/v37h93RdWs3+IAAAggggAACCCCAAAIIIIAAAq0mQGCnhamHDh1qM2fOjAIuW2yxRerVFPjJ5/OmvLNnz07N05Sd5513XlOyNTmPAkXxpKFWSttss03UQyd+jM8IIIAAAggggAACCCCAAAIIIND6AgR2Wth8//33j4I1//rXv+yEE05ocDUFdB5++OFoyM/OO+9cNLCjuW6WLl1qOZ/0UwGXXr16NSirsR06/6WXXrINGzbYkCFDbPjw4Y2dstHH1S4Ny5oxY0Y0v5AcevbsWbQ89VpS3VavXm2HHXaYdehQN6+3ypo3b56tW7cu6o0UP5YsUOW8//770W4NgSsWTFMGlfvGG29EgbfNN9/cdt1110bnQkpej20EEEAAAQQQQAABBNqzwJtvvmk77LBDeyag7Qi0uQCBnRa+BeqFo+DCE088YePHj7eOHTvWu+Lrr79uCkYce+yx0Xu9g76xbNky+9Of/mSTJk2qPaTAhoIfRxxxRL25eH7zm9/Y5MmT7fLLL7fu3bvbAw88YH/7299MQ6cUGLnvvvtMc/GEpLl8vvnNb5Z1PhwFnubPn28TJkywWbNmhUuZhnGdfvrptcPEFMD57ne/awcccIBtu+22dsstt9iaNWui/Jo8umvXrlEg56677ooCXx9++GF0TJNQ67i84hNEa26hm2++2RRA0+eQNE+OhpQpkBVP6kX1hz/8Iapr2N+jRw/79Kc/bV26dAm7eEcAAQQQQAABBBBAAIESAmeffXb0vHPooYfamDFjSv5h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/tXZrMjhip1iIwLjS4CPKT/96U9DG1p2QML4hlC+i4AIiIAIiMDwEZg0Z86cxvBFSzESAREQAREQgTwBZjtefvnl7tBDD81b0FMREIGOCTCrmAMeTj311KYPWx0LlEMREAEREAEREIG2BEZOq2jrRBZEQAREQAREYHAJMIvA9u0a3Fgo5CLQnwRsxi4zYWVEQAREQAREQATGhoAUO2PDWb6IgAiIgAj0CQEUOxp09kliKBhDR8CWX0l5OnRJqwiJgAiIgAj0MQEpdvo4cRQ0ERABERCB7hPQjJ3uM5VEETACptiR8tSI6CoCIiACIiACvSegPXZ6z1g+iIAIiIAI9BGBBx98MJywt8Yaa/RRqBQUERgOAszUmT17dtg8eaGFFhqOSCkWIiACIiACItDnBKTY6fMEUvBEQAREQAREQAREQAREQAREQAREQAREoIyAlmKVkdFzERABERABERABERABERABERABERABEehzAlLs9HkCKXgiIAIiIALdJfDII4+4v/3tb90VKmkiIAIFgeuvv949/vjjxW/diIAIiIAIiIAI9JaAFDu95SvpIiACIiACfUbgpptuckceeWSfhUrBEYHhIXDAAQe4u+++e3gipJiIgAiIgAiIQJ8TkGKnzxNIwRMBERABEeguAZ2K1V2ekiYCKQHKmE7FSqnotwiIgAiIgAj0joAUO71jK8kiIAIiIAJ9SGDy5MmOk3tkREAEekNAip3ecJVUERABERABESgjIMVOGRk9FwEREAERGEoCUuwMZbIqUn1EgDKmGTt9lCAKigiIgAiIwNATkGJn6JNYERQBERABEYgJLL/88m7HHXeMH+leBESgiwR22WUXt8wyy3RRokSJgAiIgAiIgAi0IjBpzpw5jVYW9E4EREAEREAEREAEREAEREAEREAEREAERKA/CWjGTn+mi0IlAiIgAiIgAiIgAiIgAiIgAiIgAiIgAm0JSLHTFpEsiIAIiIAIiIAIiIAIiIAIiIAIiIAIiEB/EpBipz/TRaESAREQARHoEYF///vfbs8999TJWD3iK7Ei8IUvfMFdccUVAiECIiACIiACIjBGBKTYGSPQ8kYEREAERKA/CDz55JPu/vvv16k9/ZEcCsUAEnj66adbhvree+917ey0FKCXIiACIiACIiACtQhIsVMLlyyLgAiIgAgMOgGOYsboOOZBT0mFf7wI3H777W7WrFnu+uuvzwaBMjZv3rzsOz0UAREQAREQARHoPoEFuy9SEkVABERABESgfwmYYkcDz/5NI4Ws/wn86le/cpdccombOnWq22qrrdxmm23mll122RDwBRZYQIrT/k9ChVAEREAERGCICEixM0SJqaiIgAiIgAi0J8CgE3PSSSe5hRdeuL0D2RABEWgi8PDDD7tGoxGesWfVGWec4X7wgx+49dZbLyh5pNhpwqUfIiACIiACItBzAlLs9ByxPBABERABEegnAswqmD59ehiYPvHEE/0UNIVFBAaCAPtUYVDuTJo0qQgzz/k7/PDD3SKLLFI8140IiIAIiIAIiEBvCUyaM2fO/E8uvfVH0kVABERABERABERABIaAwC233OI++clPBqXOlClTwiydzTff3K244opDEDtFQQREQAREQAQGj4Bm7AxeminEIiACIiACIiACIjCuBKZNm+Ze97rXuQ022GBcwyHPRUAEREAEREAEnNOMHeUCERABERABERABERCBygTmzp3rFltsscr2ZVEEREAEREAERKC3BHTceW/5SroIiIAIiIAIiIAIDBUBKXWGKjkVGREQAREQgSEgIMXOECSioiACIiACIiACIiACIiACIiACIiACIjAxCUixMzHTXbEWAREQAREQAREQAREQAREQAREQAREYAgJS7AxBIioKIiACIiACIiACIiACIiACIiACIiACE5OAFDsTM90VaxEQAREQAREQAREQAREQAREQAREQgSEgIMXOECSioiACIiACIiACIiACIiACIiACIiACIjAxCUixMzHTXbEWAREQAREQAREQAREQAREQAREQAREYAgJS7AxBIioKIiACIiACIiACIiACIiACIiACIiACE5OAFDsTM90VaxEQAREQAREQAREQAREQAREQAREQgSEgIMXOECSioiACIiACIiACIiACIiACIiACIiACIjAxCUixMzHTXbEWAREQAREQAREQAREQAREQAREQAREYAgJS7AxBIioKIiACIiACIiACIiACIiACIiACIiACE5PAghMz2oq1CIiACIiACIjAWBM4+uij3bx587Lezpgxw62zzjrZd3ooAiIgAiIgAiIgAiJQTkCKnXI2eiMCIiACIiACItAlAnPmzHGzZ88ulfaa17ym9J1eiIAIiIAIiIAIiIAIlBOQYqecjd6IgAiIgAiIgAh0icB9990XJO2yyy5u+vTpXZIqMSIgAiIgAiIgAiIgAlLsKA+IgAiIgAiIgAj0nMB///vf4MfUqVO74tddd93lnnzySbfyyiu7hRZaqJD51FNPudtuu80tvPDCDr8WW2yx4l18wwyie+65xy266KJuhRVWcAsuqC5RzEf3IiACIiACIiACg0NAvZjBSSuFVAREQAREQAQGloDN2Fl22WU7isNZZ53lzj//fPfpT386XP/yl78EOQsssIBbf/313Z577unuvfdeN2vWLPfggw8Wfrz2ta91u+66a5Py58wzz3QXXXSRazQahYzVVlvN7bHHHu4FL3hB4VY3IiACIiACIiACIjAIBKTYGYRUUhhFQAREQAREYMAJ2IwdZsigpGHGDTNqVl99dfeKV7zCoaCpYk466SS3zDLLuI997GMOmRdffLG7+uqr3eTJk911113n1lprLffe977X3X333e7CCy90l112mUOZtPXWWwfxv//978Nz/GZZGLN+rrrqKvfnP//ZHXXUUe7ggw92iyyySJWgyI4IiIAIiIAIiIAI9AUBKXb6IhkUCBEQAREQAREYTAKPPPKIe+ihh9wqq6zSMgLM2EF58/nPf97NnTs32EURg1ljjTXcfvvt1zSrJrzI/FtiiSXcvvvu6yZNmuRe8pKXuHXXXdfNnDnTXXnllW699dZzH/zgB4MrFDy8P/DAA90VV1xRKHZ++9vfhvcf+tCHgmKJHxtuuKH705/+FE7sipd1BYv6JwIiIAIiIAIiIAJ9TkCKnT5PIAVPBERABERABPqVwLnnnuvOO++8oBBZddVV3U477eTWXHPNENxLL73UnXbaaWFpFPvdsI/NLbfcEpQvLI1iVswdd9zhTj311PD8Zz/7WXDfLq5bbbVVUOqYvaWXXjrIvvPOOx3vYrP88ss73v/nP/8pHrPUij14fvGLXwT/llxyyfBu4403LuzoRgREQAREQAREQAQGiYAUO4OUWgqrCIiACIiACPQJgWuvvdadc845bueddy6WM7GUabnllnNLLbWUu/XWW90GG2wQNjEmyG9/+9vdjBkzwjtm22CYqbP//vu7Aw44wLFEascddwxLqsLLkn8oiFIzZcoUh2Kn7F285w7Kp3/84x/u8ssvD8uv1llnnbAB8yabbOKe97znpaL1WwREQAREQAREQAT6noAUO32fRAqgCIiACIiACPQfAfbKQUlis2S23XbbsG8OChNm4my66aZhD5s45ChgUsOpVSyF+vWvfx02PW6nXGEvnTJTZZ+e5z73uUGRxP477KtzzTXXhD16zj777LBcC+WSKZ7K/NFzERABERABERABEegnAlLs9FNqKCwiIAIiIAIiMCAE1l57bcdfbFZaaaUwgyd+xv28efPcTTfdFDYxzp06tfjii6dOevqbfXp22GGH8Pfwww+7Sy65JMwY+uUvf+lQ/Gy55ZY99V/CRUAEREAEREAERKCbBMo/e3XTF8kSAREQAREQARGYsATY4+ZrX/taOI0qB4EZPizfYj+cXptHH33UzZ49u/CGWUTM0uGELAwKKBkREAEREAEREAERGCQCUuwMUmoprCIgAiIgAiIwgATYxJjZPZxIdf7557unn346xIKZPBdddJG74YYb3Pbbb992f53RRr3RaLhDDjnEHXvssWG5WCzv9ttvDz9z+/TE9nQvAiIgAiIgAiIgAv1GQEux+i1FFB4REAEREAERGEIC7373u92RRx7pzjrrrHAiFZss33PPPUHJs91227nNN9+857Fm7xzCweyhww8/PJzgtfrqq7t//etfYb8dlolts802PQ+HPBABERABERABERCBbhJYYObMmQd1U6BkiYAIiIAIiIAIiEBKgE2Sp02bFvbbYXbMAw884J7//Oe7PfbYw2222Wap9RG/Ucpgf6211ipO2ootsb8PR63nNlB+4QtfGNxhHxmchPXEE08EhQ5Lr1gCxule/HEMu4wIiIAIiIAIiIAIDBKBSXPmzGkMUoAVVhEQAREQAREQAREQAREQAREQAREQAREQgfkEtMeOcoIIiIAIiIAIiIAIiIAIiIAIiIAIiIAIDCgBKXYGNOEUbBEQAREQAREQAREQAREQAREQAREQARGQYkd5QAREQAREQAREQAREQAREQAREQAREQAQGlIAUOwOacAq2CIiACIiACIiACIiACIiACIiACIiACEixozwgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAgNKQIqdAU04BVsEREAEREAEREAEREAEREAEREAEREAEpNhRHhABERABERABERABERABERABERABERCBASUgxc6AJpyCLQIiIAIiIAIiIAIiIAIiIAIiIAIiIAJS7CgPiIAIiIAIiIAIiIAIiIAIiIAIiIAIiMCAEpBiZ0ATTsEWAREQAREQAREQAREQAREQAREQAREQASl2lAdEQAREQAREQAREQAREQAREQAREQAREYEAJSLEzoAmnYIuACIiACIiACIiACIiACIiACIiACIiAFDvKAyIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwoASk2BnQhFOwRUAEREAEREAEREAEREAEREAEREAERECKHeUBERABERABERABERABERABERABERABERhQAlLsDGjCKdgiIAIiIAIiIAIiIAIiIAIiIAIiIAIiIMWO8oAIiIAIiIAIiIAIiIAIiIAIiIAIiIAIDCgBKXYGNOEUbBEQAREQAREQAREQAREQAREQAREQARGQYkd5QAREQAREQAREQAREQAREQAREQAREQAQGlIAUOwOacAq2CIiACIiACIiACIiACIiACIiACIiACEixozwgAiIgAiIgAiIgAiIgAiIgAiIgAiIgAgNKQIqdAU04BVsEREAEREAEREAEREAEREAEREAEREAEpNhRHhABERABERABERABERABERABERABERCBASUgxc6AJpyCLQIiIAIiIAIiIAIiIAIiIAIiIAIiIAILTp4s3Y6ygQiIgAiIgAiIgAiIgAiIgAiIgAiIgAgMIoFJDW8GMeAKswiIgAiIgAiIgAiIgAiIgAiIgAiIgAhMdAKarjPRc4DiLwIiIAIiIAIiIAIiIAIiIAIiIAIiMLAEpNgZ2KRTwEVABERABERABERABERABERABERABCY6ASl2JnoOUPxFQAREQAREQAREQAREQAREQAREQAQGloAUOwObdAq4CIiACIiACIiACIiACIiACIiACIjARCcgxc5EzwGKvwiIgAiIgAiIgAiIgAiIgAiIgAiIwMASkGJnYJNOARcBERABERABERABERABERABERABEZjoBKTYmeg5QPEXAREQAREQAREQAREQAREQAREQAREYWJlS8CEAACxwSURBVAJS7Axs0ingIiACIiACIiACIiACIiACIiACIiACE52AFDslOeC6665zu+++e/Zvr732cp/+9Kfdueee6x599NESCePz+IQTTnCTJk1yRx55ZBGA3LPiZcWbG2+8McidMWNGRRey1i0CP/vZz9yBBx7o7r777m6J7LmcL33pSyG/nHzyyYVf4x2PnP9veMMbQjhvvvnmIpy6EYE6BHL5qo77iWJXZW2ipLRzU6dODfXqvHnzKkX6qaeecrNmzXJHH320e+KJJyq5KbNU1+8yObnnTz75ZIjXyiuvnHvdlWf0O+nDXXHFFV2RN95Chq3c5/o24824W/53M26//vWvQz7eY489uhW8gZDTzbqskwgPG/fHH3+853VuJ5z72c2C/Ry48QzbP//5T/f973+/ZRCOOOIIt9JKK7mf/OQnbuONN25pd6xeWkfq6aefLrzMPSteVrxpNBrB5mg7XRW9k7VnCPz73/92b3nLW8KvBx54IHR+BwGO5T/LL92Kx7XXXhuUXG9605scCtaqpsz/xx57LIiw8FaVV9feT3/6U/eFL3zBnXbaaW7ttdeu61z2+5RAWb7q0+COa7DGqqyNayTleSAwd+7cESToQxxyyCHuRz/6kbvhhhua3p933nnuIx/5SHhGn2rnnXduel/nR87vOu5b2f2///u/8Prhhx9uZW1U76zNZIA4KKZV2g5bube+gqXToKRRlXB2Ereyvo2VFUv/Kv4Pg51u1mWteJT1hYeNu409e1nntuI8iO80Y6dNqm277bbuX//6V9Pf9ddfH5Q5G2ywgbvrrrvc9ttv7yZa5dUGm153icDznvc8t/rqqwdpL3/5y7skdezFdCse559/vvv5z3/urANSNSbd8r+qf6m9Y4891v31r391pmRN3+v3YBIY73w1mNQU6olIgAHH5z73OXfnnXeOiH6s7F5rrbVGvNeD/ibQKm37O+QK3WgJqG/TTHCs6rJO+8LNodWvYSSgGTttUnXxxRd3K6ywQpMtfr/0pS91TDFlsH3rrbe6X/7yl26HHXZosqcfIjBaAgsuuKC76aab3H/+8x+34oorjlbcuLkf73iMt//jBl4e95SA8lVP8Ur4BCGAMufBBx90fJ1deumlJ0isFU0REIFhI6C6bNhSdPDiI8XOKNLsOc95TlDmfOUrX3G33HJLkyS+zp999tnutttuc6zLXnPNNd1rXvMaN3369CZ7TNv773//6972tre5e+65x5155pnuqquucswGYh8fM1Xlmf2qVzpT7BWEn9yjqNpkk03ctGnTqoootUcn7Ve/+pW76KKLAofFFlsscNhll13cGmusMcIdaymZjcEUw3/84x9hmRscmJa98MILj7BfhcnFF18cZlW98pWvDMq4VAjxZgYWWnbijWE2CEyuvvrq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&quot;&gt;
&lt;h3 id=&quot;major-gc&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#major-gc&quot; aria-label=&quot;major gc permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Major GC&lt;/h3&gt;
&lt;p&gt;Major GC in V8 starts with concurrent marking. As the heap approaches a dynamically computed limit, concurrent marking tasks are started. The helpers are each given a number of pointers to follow, and they mark each object they find as they follow all references from discovered objects. Concurrent marking happens entirely in the background while JavaScript is executing on the main thread. &lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2025255&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Write barriers&lt;/a&gt; are used to keep track of new references between objects that JavaScript creates while the helpers are marking concurrently.&lt;/p&gt;
&lt;p&gt;V8中的Major GC开始使用并发标记。当堆内存达到了一个动态运算上限（dynamically computed limit），并发标记任务就开始了。每个辅助线程都会获得一些指针来处理，然后它们会顺着已发现对象的指针将找到的每个对象进行标记。并发标记完全发生在后台辅助线程上，而主线程仍旧会继续处理程序的运行。&lt;a href=&quot;https://dl.acm.org/citation.cfm?id=2025255&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Write barriers&lt;/a&gt;用来追踪那些在辅助线程并发标记对象时主线程创建出来的新对象之间的引用。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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vAdvc7noc66uXI2ly1O+B0J+tbC5xeaHt6nP+i75UeFz/7nve7p/y6z2h7pPdfF1aUnTnP/a96sg8yf+WOTbqbVPY2PqqG3PMR7o0WO29uPH2MUPc6P8qmjGwbT9sAwBBBBAAIFqFyDIU+1XAMePAAKZFFAXjE2auNHL5IFzUAhUoYBa5wxonQZ6Jeupi1jfErbSOEDrR4Gg0lrh9Pf99A/HGJ5L2C9ZEUAAAQQQqBYBBl6uljPNcSKAAAIIIIAAAggggAACCCCAQKYFCPJk+vRycAgggAACCCCAAAIIIIAAAgggUC0CdNeqljPNcSKAAAIIIIAAAhUgMNy7mi7yeoYZuiqgylQRAQQQQACBshEgyFM2p4KKIIAAAggggAACCHw9ZTp1VBBAAAEEEECgeQIEeZrn1C65lixZYpMnT7b+/fvbgAEDiu5z0qRJtmLFCttkk02K5mlsxZw5c2zmzJk2ZMgQW2uttRrLukbWLViwwD799NMm96266xhICCCAAAIIIIAAAggggAACCCBgRpCnjK4CBXiuvPJKO+CAA+yYY44pWrMbb7zRpk+fbtdee23RPI2teOWVV+yuu+6y0047zXbYYYfGsq6RdWPHjrXrr7++yX1vv/32dvrpp0f5Jk6caK+++qp98MEHUYBo+PDhtvnmm9vBBx9snTpxmTeJSQYEEEAAAQQQQAABBBBAAIGKF+Dut+JPYfYOYIsttrBzzjmn9sAmTJhg99xzj+288862yy671C4PrZA++eQTu+KKK2z16tU2cuRI22+//Wzu3Ln24IMP2vjx4+3ss8+2zp07127HCwQQQAABBBBAAAEEEEAAAQSyKECQJ4tntcKPScGbTTfdtPYoli9fHr1WF7b48pDh7rvvjrqv/fjHP67XhW399de3W2+91Z5++mnbd999Q3aeEUAAAQQQQAABBBBAAAEEEMikAEGejJ1WtWBR65V58+aZuiwpKNKxY8dGj3LZsmWmcX4URNF4QOo29uabb1rXrl1t4403jh7FClAA5r333ou6SA0aNMg222wz6969e73samGjblR9+vSxddZZx15//XVT65tu3bpFrW5yuVy9/KW+Of7446P6J8co2muvvezee++1t956iyBPqajkRwABBBBAAAEEEECgGQIaakEt8UkIIFAeAgR5yuM8fOFaKNhyyy232AsvvGD5fL62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t6M82267bclBnhUrVtif//xnW7VqlfXr18922mmnRvfXnJWvvPKKvfHGG01mHTRoUG2QZ/z48aagViUHed5880175plnbJtttiHI0+TZJwMCCCCAAAIIIIAAAggggEC5CBDkaYczoYBBY0GeefPm1bbiaWl11HJnyJAhNn36dBs8eHBLi6m33RFHHBG1CgoLH3nkkSgQdeKJJ1r//v3D4mi/tW94gQACCCCAAAIIIIAAAggggAACa0SAIE8bsw8fPtwmTZoUBV/WWWed1L0pCJTP5015p0yZkpqnOQsvvPDC5mRrdh4FjeJJ3bGU1l9//ajlTnwdrxFAAAEEEEAAAQQQQAABBBBAYM0KEORpY/9Ro0ZFgZsnn3zSjjvuuAZ7U3DnqaeeiroFbb755kWDPBobZ/78+ZbL5aKWM7169WpQVlMLtP2YMWNs9erVNmzYMBsxYkRTm7R4vY5LXbcmTJgQjUckh549exYtT62ZVLdly5bZfvvtZx061I0JrrJmzJhhK1eujFopxdclC1Q5n332WbRY3eSKBdaUQeV++OGHURCub9++ttVWWzU5dlJyf7xHAAEEEEAAAQQQQKCaBT766CPbeOONq5mAY0egrAQI8rTx6VDrHAUann/+eTvmmGOsY8eO9fY4duxYU2Di8MMPj57rrfQ3CxYssBtuuMHefffd2lUKcigQcsABB9Qbu+eqq66ycePG2dVXX23du3e3xx57zG677TZT9yoFSR599FHT2D0haeyfU089tVXHz1EQaubMmXbjjTfa5MmTw65MXb3OOuus2q5kCub84Ac/sJ133tk22GADu+uuu2z58uVRfg083bVr1yio8+CDD0ZBsIULF0brNIC11ssrPri0xiK68847TcE0vQ5J4+qo25mCWvGk1lV/+tOforqG5T169LCjjz7aunTpEhbxjAACCCCAAAIIIIAAAo0InHvu/2/vPMBkKao2XJccBCRnuEiOSpCcLkGQIBmRpASRJIgElQySFeT3knMOIkFAcs4XJUhQcgZB4ZIkh/nrLThza2q7e7pnZ3Znd7/zPLs93V3xrerqqtOnqn4Vxjsrr7yyW2aZZQo/shYEo1siIAJtIiAlT5tA5gWDUoVdmi655BL34IMP9lgQ+a677grWOazZc8UVVzQEg+XKEUccEZQ/66+/vpttttnc6NGjHQsiozRhgeCD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e//992tDNvfKuAiIgAiIwJAjgBXkvffe6w477LAeeUcBdPTRR7tTTjmlxz1dEAERaE4Aa2M2hzj//PMbPnI19ykXIiACIiACIiAC7SDQ09yiHaEqDBEQAREQARHoUgJYF9g6X12aRCVLBAYsAbPkxUJWIgIiIAIiIAIi0PcEpOTpe+aKUQREQAREoB8JoOTRALQfC0BRD2oCNkVLitRBXczKnAiIgAiIQBcTkJKniwtHSRMBERABEWg/AVnytJ+pQhQBI2BKHilSjYiOIiACIiACItC3BLS7Vt/yVmwiIAIiIAL9TGDRRRd1w/0uexIREIH2E2CziUMOOcSx2YJEBERABERABESg7wlIydP3zBWjCIiACIhAPxJg10H+JCIgAu0ngCXPAgss0P6AFaIIiIAIiIAIiEApApquVQqTHImACIiACIiACIiACIiACIiACIiACIhAdxOQkqe7y0epEwEREAERaDOB9957zz311FNtDlXBiYAIGIHHHnvMffzxx3aqowiIgAiIgAiIQB8SkJKnD2ErKhEQAREQgf4n8MQTT7ijjjqq/xOiFIjAICWw7777utdee22Q5k7ZEgEREAEREIHuJiAlT3eXj1InAiIgAiLQZgLaXavNQBWcCCQEeMa0u1YCRaciIAIiIAIi0EcEpOTpI9CKRgREQAREoDsIjDXWWO6LL77ojsQoFSIwCAlIyTMIC1VZEgEREAERGDAEpOQZMEWlhIqACIiACLSDgJQ87aCoMEQgnwDPmCx58vnojgiIgAiIgAh0koCUPJ2kq7BFQAREQAS6jsD000/v1l9//a5LlxIkAoOFwMYbb+ymmGKKwZId5UMEREAEREAEBhSBcQZUapVYERABERABEeglgWmmmcZtsMEGvQxF3kVABPIISImaR0bXRUAEREAERKDzBGTJ03nGikEEREAEREAEREAEREAEREAEREAEREAEOk5ASp6OI1YEIiACIiACIiACIiACIiACIiACIiACItB5AlLydJ6xYhABERABEegiAm+88YbbZptttMNWF5WJkjK4CBx00EFu1KhRgytTyo0IiIAIiIAIDBACUvIMkIJSMkVABERABNpD4NNPP3VvvfWWdv9pD06FMgQJfP7554W5fv31110zN4UB6KYIiIAIiIAIiEDLBKTkaRmdPIqACIiACAxEAmzvjGiL54FYekpzNxB44YUX3MiRI91jjz2WmRyesS+++CLzni6KgAiIgAiIgAh0loB21+osX4UuAiIgAiLQZQRMyaNBaJcVjJIzoAjccsst7uabb3bTTjutW3XVVd3yyy/v2LkOGXvssaVEHVClqcSKgAiIgAgMJgJS8gym0lReREAEREAEmhJgAIqceeaZbrzxxmtw/95774XzU089teG6TkRABMYQePfdd12tVgsXWOPqkksuceedd55bcMEFg8JHSp4xrPRLBERABERABPqagJQ8fU1c8YmACIiACPQrAawNVllllTBI/eSTTxrS8tlnn4Xz9HqDI52IwBAnwLpWCIqeYcOG1Wlwnb8jjjjCjT/++PXr+iECIiACIiACItB3BIa9//77X32K6bs4FZMIiIAIiIAIdCWBJ5980h199NHulFNO6cr0KVEi0A0EnnnmGbfnnnsGBc9kk00WrHdWWGEFN+OMM3ZD8pQGERABERABERjSBGTJM6SLX5kXAREQAREQAREQgeoEll12WTdixAi3yCKLVPcsHyIgAiIgAiIgAh0jICVPx9AqYBEQAREQAREQAREYfASw2Nl9990HX8aUIxEQAREQAREYBAS0hfogKERlQQREQAREQAREQAT6isCEE07YV1EpHhEQAREQAREQgYoEpOSpCEzORUAEREAEREAEREAEREAEREAEREAERKAbCUjJ042lojSJgAiIgAiIgAiIgAiIgAiIgAiIgAiIQEUCUvJUBCbnIiACIiACIiACIiACIiACIiACIiACItCNBKTk6cZSUZpEQAREQAREQAREQAREQAREQAREQAREoCIBKXkqApNzERABERABERABERABERABERABERABEehGAlLydGOpKE0iIAIiIAIiIAIiIAIiIAIiIAIiIAIiUJGAlDwVgcm5CIiACIiACIiACIiACIiACIiACIiACHQjASl5urFUlCYREAEREAEREAEREAEREAEREAEREAERqEhASp6KwORcBERABERABERABERABERABERABERABLqRgJQ83VgqSpMIiIAIiIAIiIAIiIAIiIAIiIAIiIAIVCQgJU9FYHIuAiIgAiIgAiIgAiIgAiIgAiIgAiIgAt1IYJxuTJTSJAIiIAIiIAIiMDgIvPDCC+7RRx91a6+9dmaG3n//fffEE0+40aNHuymnnNLNO++8buKJJ850q4siIAIiIAIiIAIiIALFBKTkKeajuyIgAiIgAiIgAi0SuOmmm9yll17qvvjiC7fWWmu5YcOGNYR03XXXuauvvtp9+umn9esTTDCB22ijjdxyyy1Xv6YfIiACIiACIiACIiAC5QhIyVOOk1yJgAiIgAiIgAiUJPDhhx+6U0891T3++OO5Ps4++2x39913uznmmMOtt956buaZZ3ZY/VxxxRXu3HPPdeOMM45baqmlcv3rhgiIgAiIgAiIgAiIQE8CWpOnJxNdEQEREAEREAERaJEAVjuHHnpoUPCMGDHCzTTTTD1Ceu6554KCZ+qpp3a77rqrm3POOR0WPPPMM4/bY4893GyzzRYUPa+//noPv3kXarWae/bZZ91LL73kvvzyywZnTAl78skn3csvv+w+++yzhnvxyX/+85/g7o033nCEJxEBERABERABERCBgUZAljwDrcSUXhEQAREQARHoYgJjjz12sMxhXR3W1znssMN6pPb6668P1zbZZBM3/vjjN9zHgoepXSNHjnR//etf3TbbbNNwPz45+uij3SuvvOIOOeQQ93//93/BEoj7hLnyyiu7dddd140aNSoojGxK2Ljjjus23HBDhwLKhHsnn3xyWDvIro033nhuwQUXdD/+8Y+DAsqu6ygCIiACIiACIiAC3UxASp5uLh2lTQREQAREQAQGIIHFFlssN9VY+jCNCyXQAgsskOluvvnmcyhjHnnkkWBRk67lE3sivBNPPNHNPvvsbv311w+WPCiHrrnmGvfBBx+4O+64w62++urBSggLItYBuvDCC90ss8wS/BAW5ywOPf/887vVVlvNYclz//33uwceeMB99NFH7he/+EUcpX6LgAiIgAiIgAiIQNcSkJKna4tGCRMBERABERCB7iKAxQuWM0ynKlK8FKX67bffDgsto5TJCwNroBlnnDFY5rz33ntusskmyw3y448/DgqbjTfeOLhhyhfTwFD83H777W6dddZxa665ZriHZdGkk04aLHvuu+++oORBSXTPPfe4SSaZxO28886OuAljhRVWCAqh4cOH58atGyIgAiIgAiIgAiLQbQS0Jk+3lYjSIwIiIAIiIAJdSODhhx8O6+UcccQRbu+99w7ToFCQIC+++KLbbrvtwno2zZLO+jgIa/AUyTe+8Y1w+3//+1+Rs3Bv1VVXbXCDRQ7C1K/0nlkPsf4OglJn8sknd6Tr5ptvblizxyyAgkP9EwEREAEREAEREIEBQECWPAOgkJREERABERABEehPAm+99VbYLWvxxRd3WLY89NBD7owzznB//vOf3bTTTuv+/e9/uymnnDLslNUsnUzDQj7//PNCp3aftXGKBGURSppY8MN1FEWpfyx5kE8++aTu5ac//ak79thjQ35uvfVWN/fcc7tZZ53VLbHEEm6iiSaqu9MPERABERABERABEeh2AlLydHsJKX0iIAIiIAIi0M8EULhg1bLKKqu4CSecMExleuedd8K6NaxlwzboTJfCKqaZfPOb3wxOUBwViVn8FE3Vwn9RnEX34riZOrbvvvuGdXzYhYvpW/xdeumlbosttgjKnti9fouACIiACIiACIhAtxKQkqdbS0bpEgEREAEREIEuIYC1ztprr92QGpQ13/ve98Jfw40mJ1jXTD/99O61115zTMWyaVmxt3fffde9+uqrwZomtcSJ3bXzN3ncaqutQpBYJt1www1BiYXF0jTTTBPWIWpnfApLBERABERABERABDpBQGvydIKqwhQBERABERABEcglsOSSS4Z7d955Z6aba6+9Nlwv2qUr02OLF//73/+GBaXNO0ootk5fdtllw+5eTz31lN3SUQREQAREQAREQAS6mkBbLHmuv/76sPVoXk4x8WahQ3a6wKx7t912c3POOWee815dv+uuuxw7ZmyzzTZhjv4tt9ziLrroIrfBBhuEbVF7FfgA83zllVc6OqZ77LFHbsrZlWSfffYJW9UefPDBPdYuyPWoGyKQQYD1OW688Ua39dZbD9rpDXfffbe79957wxd/1iCRiIAIVCeABdCDDz7o2OqctW/YMt2E9X5YFwdLoZVWWskud+zItLP999/fTTHFFO7Xv/512GWLyFhUmgWlkRlmmCEc9U8EREAEREAEREAEup1AW5Q8mDWjTGBO/lhj5RsHse0q8/pHjx7dMV8oN8YAAEAASURBVC58jSMtbPOKvPzyy+Fou2iEkyHyD1P4Zl8f6dxiLk+5wayvzOL7sghQOrBw5jLLLNORaB944IEw7WCttdbK3Q64IxF3YaBMr6jVau7NN9/sl9ShRH7hhReCQrdTdZm88Vx99tln/ZJHRSoCg4EAa+Xssssu7rDDDgsLHvPhh23Zn3/+eff0008HhcvPf/7z8AGi0/lFmbTuuuuG9XfY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REAEREAEREAERGBIEpCSZ0gWuzItAiIgAiIgAiIgAiIgAiIgAiIgAiIw2AiMNdgypPyIgAiIgAiIgAiIgAiIgAiIgAiIgAiIwFAkICXPUCx15VkEREAEREAEREAEREAEREAEREAERGDQEZCSZ9AVqTIkAiIgAiIgAiIgAiIgAiIgAiIgAiIwFAlIyTMUS115FgEREAEREAEREAEREAEREAEREAERGHQEpOQZdEWqDImACIiACIiACIiACIiACIiACIiACAxFAlLyDMVSV55FQAREQAREQAREQAREQAREQAREQAQGHQEpeQZdkSpDIiACIiACIiACIiACIiACIiACIiACQ5GAlDxDsdSVZxEQAREQAREQAREQAREQAREQAREQgUFHYJyxxpKeZ9CVqjIkAiIgAiIgAiIgAiIgAiIgAiIgAiIw5AgMq3kZcrlWhkVABERABERABERABERABERABERABERgkBGQGc8gK1BlRwREQAREQAREQAREQAREQAREQAREYGgSkJJnaJa7ci0CIiACIiACIiACIiACIiACIiACIjDICEjJM8gKVNkRAREQAREQAREQAREQAREQAREQAREYmgSk5Bma5a5ci4AIiIAIiIAIiIAIiIAIiIAIiIAIDDICUvIMsgJVdkRABERABERABERABERABERABERABIYmASl5hma5K9ciIAIiIAIiIAIiIAIiIAIiIAIiIAKDjICUPIOsQJUdERABERABERABERABERABERABERCBoUlASp6hWe7KtQiIgAiIgAiIgAiIgAiIgAiIgAiIwCAjMKSVPLVazW255ZaV/n7zm9+EKvC9733PDRs2zD355JODrEoUZ+e1115zBxxwgLviiiuKHfbR3c8++8ydddZZbqeddnKLLrqom3TSSd23v/1tt+GGG4brn3/+edOUXH311e7Xv/61W3nllYP/2Wef3f3gBz9wxx9/vPvoo4+a+pcDERCB3hOo0qby3I8cOdL94Q9/cJ988knvIx8kIRxyyCHhvUSbKGlO4KGHHgpt/wMPPNDc8RB3MRTq1rTTThueny+++KJe2vQR6euNGjWqfq3qj3aEUTVOuc8m8Prrr7sDDzzQXXbZZdkOhuhV+r/U86effrprCKh9bn9RdLqc1Tdrf5n1JsRxeuN5MPg999xzK2XjW9/6ljv88MPdhx9+GPyVUSJUiqDLHf/2t791J510Ukjlf/7zHzf11FP3W4r//e9/ux/+8IfuzjvvrKdhmmmmcY888kj4u/TSS0NZ/fnPf3YLLrhg3Y39oAxRDsUDokkmmcQ999xz4e+qq65yBx98sLv88svd0ksvbd50FIGuIEAn9aCDDnIXXXSRm3feebsiTb1JRJU29a9//avbZZddQnQzzTST22ijjXoT9aDxa+8jKb7KFenmm2/u/vnPf4Y2fqh9sClHaIyroVC3sj7q2LPE4KVVaUcYrcY9FP3xAffQQw91F154oXv88ccbEBx11FHh4wAXX331VTfDDDM03B+qJ1ZHP/30065B0K72uag+dE1m+ygh7SjnIp7qm/VRQZaMZkhb8qC1RlFBQx//bbPNNgHfkUce2XAdN/fcc09JtIPTGdYyCMquySefvN8yiSLmO9/5TlDwLLTQQu7222937733nnvjjTfCl/3rr7/eLbLIIu6pp55ya6yxhnvrrbca0sqAcqmllgoKHhQ7f/rTn0JZE8aXX37pHn744TBwpH6svvrqQ85iqwGWTrqSAJZmKDTjr85dmdAOJCpWas0999wdiEFBDgUCyyyzTMjm4osvPhSyqzyKwJAgQB9uv/32cy+//HKP/NIvRPg4MOWUU/a4rwvdQ6Bd7XNRfeie3A6clBTxVN+su8pxyFvyZFmiTDXVVKGUUGJIy99YYbfddlv3/e9/32ExM844/Vd9mDaHAoYv+FjiTDTRRPWEjjfeeI6pH7wgRowY4f72t7+53/3ud+6II46ou7EB8nzzzeeuueYaN+uss9bvofxjytfFF18cOgFYLu2zzz4OiyCJCIhA/xNAsfP22287vij1p7K5/0koBb0hcMopp7i9997bDR8+vDfByK8IiMAAIYB1yEorreTo59NXlHQvAbXP3Vs2eSlT3yyPTP9c779Rev/ktyOxYlVy7bXXBisf5nQvscQSbuONNw7zW9MIn3nmGXfDDTc41gDgBYM1yoorruiqfI1+8MEHwxf85ZdfPlidMG3jH//4RwiLl5dZ22CGTrr+/ve/u9lmm82tt9567rvf/W6apGAJcPPNN7tbbrklfPmYYIIJ3FxzzeXWWmstN//88ze4f/PNN92NN94YOsWkO5X77rvP3X333SE9k002mVt44YWDJUyqLLM8EAbu/vKXv4S0wo8pYVzLE+LA8gZBWRMr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E7s8qI79VR6DCmKXZ6bZF/ouT76S1yKB2JKnxSDkrQQBLFh4R+RZLZUIYsA6sem58XvTMmMzSuifxVaXdl/HMQTG8RVIIgJNCaBVveeee+o7ArEYnkQEREAEBjIBP60mLHru56UH6za+TnrT82BJ4Oe9B+swvlby1UwiAlkE+NKIlR5fFKlPLArJTpksEsliz346brgf77a01VZbORYoZ+cpb4KfFayuiYAIiIAIiMCQJMAOw2wMwSLeWAliGcosCz+d1NlC02wA0SkL3cECXUqewVKSHc4Hq8GzbR1muewg4ueldjhGBS8CIiACnSXAVp1+PnjoNLArlO0MZbEyLdV2j7NrOopATGD88cd33pon7KDJLiD8xcKULL+IcMM0HjqpbGttO+TF7vVbBERABERABIYyAZQ87LTo15mt78gb82BXUHZvkxQT0Jo8xXx092sCrHPAeiasXUGnViICIiACg4UAW4izzgBfifjNOgUMzv2uIYMli4M+Hw899FD44rfYYot1dD2hIpCkwS8QG7Z7xbqHtYD4INLptb+K0tRf97qhPPor70MlXtbM8AsrhzUz/PS8oZLtIZ9P1nphW++pppoqrMEz5IF0CADrvfnNYcJaX/G6Mx2KriuDxYrHb2gR1t1kfTYsrXnHs/6ZpDkBKXmaM5ILERABERABERABERABERABERABERABEeh6AmN1fQqVQBEQAREQAREQAREQAREQAREQAREQAREQgaYEpORpikgOREAEREAEREAEREAEREAEREAEREAERKD7CUjJ0/1lpBSKgAiIgAiIgAiIgAiIgAiIgAiIgAiIQFMCUvI0RSQHIiACIiACIiACIiACIiACIiACIiACItD9BKTk6f4yUgpFQAREQAREQAREQAREQAREQAREQAREoCkBKXmaIpIDERABERABERABERABERABERABERABEeh+AlLydH8ZKYUiIAIiIAIiIAIiIAIiIAIiIAIiIAIi0JSAlDxNEcmBCIiACIiACIiACIiACIiACIiACIiACHQ/gf8Hf+hDwaj+EV0AAAAASUVORK5CYII=&quot;&gt;
&lt;p&gt;When the concurrent marking is finished, or we reach the dynamic allocation limit, the main thread performs a quick marking finalization step. The main thread pause begins during this phase. This represents the total pause time of the major GC. The main thread scans the roots once again, to ensure that all live objects are marked, and then along with a number of helpers, starts parallel compaction and pointer updating. Not all pages in old-space are eligible for compaction — those that aren’t will be swept using the free-lists mentioned earlier. The main thread starts concurrent sweeping tasks during the pause. These run concurrently to the parallel compaction tasks and to the main thread itself — they can continue even when JavaScript is running on the main thread.&lt;/p&gt;
&lt;p&gt;当并发标记完成，或当引擎达到了动态分配上限，主线程会执行一个快速标记完成步骤（a quick marking finalization step）。主线程会在这一步中暂停。这代表了major GC所有的暂停时长。主线程会再次扫描根节点，来保证所有的存活对象都被标记了，然后协同一系列的辅助线程，开始并行清理和指针更新工作。不是所有的老生代内存页都适合压缩（compaction） - 那些不适合压缩的会使用free-list来进行清理，我们之前提到过这点。主线程在暂停中开始并发清理任务。这些工作会并发发生在并行压缩任务上以及发生在主线程自身上 - 即便主线程上的JavaScript正在运行这些工作也可以继续。&lt;/p&gt;
&lt;h2 id=&quot;idle-time-gc&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#idle-time-gc&quot; aria-label=&quot;idle time gc permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Idle-time GC&lt;/h2&gt;
&lt;p&gt;Users of JavaScript don’t have direct access to the garbage collector; it is totally implementation-defined. V8 does however provide a mechanism for the embedder to trigger garbage collection, even if the JavaScript program itself can’t. The GC can post ‘Idle Tasks’ which are optional work that would eventually be triggered anyway. Embedders like Chrome might have some notion of free or idle time. For example in Chrome, at 60 frames per second, the browser has approximately 16.6 ms to render each frame of an animation. If the animation work is completed early, Chrome can choose to run some of these idle tasks that the GC has created in the spare time before the next frame.&lt;/p&gt;
&lt;p&gt;JavaScript的用户不可以直接操作垃圾回收器；它是完全实现定义的（implementation-defined）。V8确实提供了一个机制让嵌入者触发垃圾回收行为，即便JavaScript程序自身并不可以。垃圾回收器可以发布可选的工作”Idle Tasks”，并最终被触发。V8的嵌入者，比如说Chrome可能对GC触发或闲置有时机规划。比如说Chrome，以每秒60帧状态运作，浏览器有大约16.6毫秒来渲染一个动画的每一帧。如果动画工作提前结束了，Chrome可以选择在下一帧渲染之前来运行一部分GC创建出来的闲置工作（idle tasks）。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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NS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4xMTQ5PC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjcwODwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgre2K6IAABAAElEQVR4AezdCZwUxd3/8cLlRs6AHIII4sEtoiABEUURUCEqSy4fNSYxHkk0f4ORmCjGaA4TjdEY9UnMqUkQlegih6iIElREhCAIIvchh1wiAReXv99+Um1NMzM7Mzuz29P9qdcLprunu7rqXbO7M7+po9bBT5IhIYAAAggggAACCCCAAAIIIIAAAghESuCwSNWGyiCAAAIIIIAAAggggAACCCCAAAIIeAIEfXghIIAAAggggAACCCCAAAIIIIAAAhEUIOgTwUalSggggAACCCCAAAIIIIAAAggggABBH14DCCCAAAIIIIAAAggggAACCCCAQAQFCPpEsFGpEgIIIIAAAggggAACCCCAAAIIIEDQh9cAAggggAACCCCAAAIIIIAAAgggEEEBgj4RbFSqhAACCCCAAAIIIIAAAggggAACCBD04TWAAAIIIIAAAggggAACCCCAAAIIRFCAoE8EG5UqIYAAAggggAACCCCAAAIIIIAAAgR9eA0ggAACCCCAAAIIIIAAAggggAACERQg6BPBRqVKCCCAAAIIIIAAAggggAACCCCAAEEfXgMIIIAAAggggAACCCCAAAIIIIBABAUI+kSwUakSAggggAACCCCAAAIIIIAAAgggQNCH1wACCCCAAAIIIIAAAggggAACCCAQQQGCPhFsVKqEAAIIIIAAAggggAACCCCAAAIIEPThNYAAAggggAACCCCAAAIIIIAAAghEUICgTwQblSohgAACCCCAAAIIIIAAAggggAACBH14DSCAAAIIIIAAAggggAACCCCAAAIRFCDoE8FGpUoIIIAAAggggAACCCCAAAIIIIAAQR9eAwgggAACCCCAAAIIIIAAAggggEAEBQj6RLBRqRICCCCAAAIIIIAAAggggAACCCBA0IfXAAIIIIAAAggggAACCCCAAAIIIBBBAYI+EWxUqoQAAggggAACCCCAAAIIIIAAAggQ9OE1gAACCCCAAAIIIIAAAggggAACCERQgKBPBBuVKiGAAAIIIIAAAggggAACCCCAAAIEfXgNIIAAAggggAACCCCAAAIIIIAAAhEUIOgTwUalSggggAACCCCAAAIIIIAAAggggABBH14DCCCAAAIIIIAAAggggAACCCCAQAQFCPpEsFGpEgIIIIAAAggggAACCCCAAAIIIEDQh9cAAggggAACCCCAAAIIIIAAAgggEEEBgj4RbFSqhAACCCCAAAIIIIAAAggggAACCBD04TWAAAIIIIAAAggggAACCCCAAAIIRFCAoE8EG5UqIYAAAggggAACCCCAAAIIIIAAAgR9eA0ggAACCCCAAAIIIIAAAggggAACERQg6BPBRqVKCCCAAAIIIIAAAggggAACCCCAAEEfXgMIIIAAAggggAACCCCAAAIIIIBABAUI+kSwUakSAggggAACCCCAAAIIIIAAAgggQNCH1wACCCCAAAIIIIAAAggggAACCCAQQQGCPhFsVKqEAAIIIIAAAggggAACCCCAAAII1IYAAQQQQAABBBBAoPoF9uzZY95++22zdu1ac/DgQXPYYYeZRo0amcaNG5tmzZqZLl26mDp16lRLwf7zn/+Y5cuXm5UrV5qKigr/nnXr1jXt2rUz3bp1Mw0aNPCPs4EAAggggAACxSFA0Kc42olSIoAAAgggUC0CW7duNQ888IB/rxNPPNGcf/75/n4+N+bPn2+eeeYZP8tRo0aZ3r17+/va2LBhg3n44Yf9Y/379zfDhg3z94ttY/PmzWb69OnmrbfeMuvWrUtbfAVcevXqZU455RRz6qmn5j0AtGvXLjN16lSzePFis3r16oRgT7BgJSUlXllOO+00069fPy9AFTyHfQQQQAABBBAInwBBn/C1CSVCAAEEEECgxgT2799vli5d6t//iCOO8LfzvbFjx46Eew0ePPiQW+zduzfhnI4dOx5yTjEcUE+av//97+b55583H3/8cUZF/uijj8zrr7/u/dO1paWl5vTTTze1atXK6PpUJ+n+Tz75pCkrKzO6RyZJ1yxYsMD717ZtW3PxxRebPn36ZHIp5yCAAAIIIIBADQoQ9KlBfG6NAAIIIIAAAtEXUE+a3/72t0ZBrlyTrn3ooYfM7NmzzfXXX+8NA8slr23btpm7777brFq1KpfLvWs2bdpk7rzzTq/30VVXXZX3Hkg5F4wLEUAAAQQQQOAQAYI+h5BwAAEEEEAAAQQQyI/AnDlzzP333+/N2RPMsV69ekbD504++WTTvHlzb3iVhly9//775p133jGLFi0y5eXlCZdpDqCbbrrJ/OAHPzAtW7ZMeK6yHQV8JkyYYLZv355wquYNssPI+vbt6weUNM+QhtcpQPTGG2+Y1157LaEer7zyihfI+v73v0/gJ0GUHQQQQAABBMIjQNAnPG1BSRBAAAEEEEAgQgLqlfPggw8mBEo0WbPmxBk0aJDp2bNn2mCJhl5p3qN//vOf3mTPlmbLli1GwaTRo0fbQ5U+KtATDPgceeSR3nxNmidJAahg0jCy9u3be/80l4+G/d1zzz1m9+7d/qnLli3zhqydc845/jE2EEAAAQQQQCA8AgR9wtMWlAQBBBBAAAEEIiKgIV0ajqXeMjYdf/zx5oorrjCaEyeTpImcBwwY4E3k/Ic//MG88MIL3mVnnXVWVgGfffv2mTvuuMPv4aNgzhe+8AVz3nnnZTU/UNeuXc1Pf/pTc9ddd5kVK1Z4ZVHA6Oyzz86kOpyDAAIIIIAAAjUgQNCnBtC5JQIIIIAAAghEV0CTT//6179OWA1r4MCB5sorrzRaBSvbVLt2bfP1r3/dCxapl8/ll1+eVRaaBHrjxo3+NVdffbVReXJJWkpew7kU/NHS8t/61rdYySsXSK5BAAEEEECgmgQI+lQTNLdBAAEEEEAAgXgIKMiyZ88ev7Ldu3c3mvBYQ7uqktQzJ9u0Zs0a8+yzz/qXnX/++TkHfGwm9evXN+PHjzcKRlW1TjZPHhFAAAEEEECgMAIEfQrjSq4IIIAAAgjEVkDLvq9du9afhLhBgwZGS63XRIBAw6vUO0Zz2tihVpq/RnPVJJvHpqqNpvlu7DAs5aUhWvkI+ORarsmTJ/v17tChgxk7dmyuWSVcVwi7hBuwgwACCCCAAAJ5ESDokxdGMkEAAQQQQACBf//736asrMxoPhsbYLEqWiFKc9qMGDHC9OnTxztcyCDQBx98YBTweOmllxJ63djy6N49evQwmqD41FNPzWnYlc3LfZw+fbr5+OOP/UPqWdOiRQt/vzo3FOjSils2XXbZZXmrp82TRwQQQAABBBAItwBBn3C3D6VDAAEEEEAg9ALq3fLwww8nBBiChdbS4woG6d8JJ5xgvvvd73pzwgTPq+q+gk3PPfec0RArza2TKlVUVHhLomtZ9IkTJ5pvfvOb5thjj011esbHtWKXTerloyBXTaV//etffvCtU6dORhMxkxBAAAEEEEAgXgJVG1weL6vY1HbBggXeUrB6g07Kn4A+FM2YMSNh2d385U5OCCCAQM0IbNq0yXzve99LG/AJluztt982t956a96HVymQc99993kBqHQBn2B5tm7dan784x+bd955J/hUVvuaP+f999/3r+nbt69p2LChv1/dG24vH/VoIiGAAAIIIIBA/ATo6VPgNr/nnnuMPuzbpG/aLr74Yrsbqke9Qf7FL35h9GZcSRM/3nTTTUZd8klVE3jxxReNltv96KOPvK711113ndGHARICmQosX77c/OMf//BPP/PMM6s8GaufGRsI5CiguXu0FPiuXbsScujVq5e3jLeGT2nuF32JsHTpUm+o1Zw5c7xz161b5/WwSbiwijuPPfaYmTt3rp+LhnBplSpNgKz5bJT0t27JkiVm5syZXk8fe7LKeOedd5qf/exnpnnz5vZwVo/Lli1LOP/EE09M2K/OHQ0xe/fdd/1bduvWzd9mAwEEEEAAAQTiI0DQp4BtrW/8Xn311YQ7KKAyevTognRpT7hRDjvq3m4DPrpcHzKfeeYZr7w5ZMcl/xXYuXOneeihh/wu9nojfu+993pBoFq1auGEQEYCmp9EH5pt0odqEgI1LfDXv/41oWeLviS44oorDglI6rhes/qnIVR//OMfvaKvXLkyb1VYtWqVeeqpp/z8unTpYq655hrTunVr/5g21PPm5JNP9v498sgjZsqUKf7zWnFLfwu/8Y1v+Mey2Vi9enXC6Zq8uqaSymLnVdLfGhv0qqnycF8EEEAAAQQQqBkBgj4FdNfkkcGkN2Dq9ZHLsqvBvPK9v23btkOydLupH/JkTA8oMKYhBEpatrZz585pJdwVY+yJ6vHzn//8p0a7/duy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KMkIAQQQQAABBBBAAAEEEEAAAQQQKI8AQZ/yrAtKggACCCCAAAIIIIAAAggggAACCBQmQNCnMEoySgu8+uqrbt9993WnnnpqelDNz5988okbMGCAW3TRRZNx/vd//zd896Mf/Sj5rqfefPbZZ+43v/mNO+yww9yaa67p5pxzTrfqqqu6XXbZJXw/ffr0hrO+8cYb3XHHHec222yzMP3SSy/ttt9+e3fBBRe4jz/+uOH0ZRlhyy23DO7PP/98WYrUb8uhberb3/52+D3pN/Xkk082bfHEE0+4448/3n31q18N0//+979vetoyjqjf6M9+9jP3k5/8xP3nP/8pYxHbpkz99Td+/fXXu1NOOcVNnjy5T9ZVp7mfccYZ4VihYyeptsC///1v98Mf/tB97WtfC/vi0047rfbIbTZEy3beeeeF5Vp++eVD3We99dYLn8eOHdtwaVT3+/Wvfx3qXmuvvXZS99ptt93cX/7yF1epVBrmUfYROu1335fevV0PeOaZZ8I+buutt+7LxWbeCLQm4HekJAR6ROCpp57SUboyevTopvP/6KOPwjRDhw5Nprn44ovDdz/4wQ+S73rijT8BqGy44YZhXiq3/uaff/6qz8stt1zFn0Rnzv7DDz+s+BPrqvG1HJaX5Tdu3LjM6cv25ZgxY0LZtR5JfSfwhz/8oWob0nbkg0BNFcgHXrtMe+yxxzY1bV+ONGPGjMrpp59eWWmllboU409/+lOyTL/73e+6DOeLaoE333yz8o1vfKNywAEHVA/wn/rjb/yNN95Itp/DDz+8i0lRX9TbhjvN3QfQgqmO1c2m6667rjJq1KiKP5lqdpK2H0/1h7g+sMYaa7T9MmkBHnjggS51pXTd54tf/GLlvffey1zeSZMmhXpibJOue6keqd9uO6dO+933xrqotZ/o7XqAnc9suummvbHYzAOBHhGgpY8/ypAQmDhxoltttdXcvffe63xF1N19993u/fffd1OmTAmtCW677TbnK2juhRdecIr0v/3221VoPljldFVLVzp9Zcf5k1H32muvhTx85d899thjbtddd3X+BMx96UtfcrSeqeLjQx0BbUtKPujpfKXXvfPOO05XDJtJN9xwQxhN2562cU2rFg5lT/rNnHTSSe6VV17pUtQVV1wx+U5XlEn1BbSvueiii9y0adPqj9hPhs4777xuqaWWCkurVpw9leptwz01z3bKVy1f1Qrx888/b6did7us/qQx1B984Mc98sgjYV981113dTu/skyoY8y6664b6ja77767e/zxx0OdSfUn/f3yl790PoDjVIdSK1X9LuIkl1VWWcU9+OCDoY4lk3fffTfUvdSa4+abbw7fa/h2223nVNci9R+BWvsJ6gH9ZxtgSYsTIOhTnCU5tbHA9773vVBp0cnx/fff777whS+E4I0WafDgweEk+5577nH+apPTbWtnn3121dLagcm3TAi33iifhRdeOIyj29V0cnHttde6r3/96+6DDz5wJ5xwQtX0fECglsAtt9wSBumWwwUWWMDNPffcbuaZZ641etX31qx+//33d0suuWSYdtZZZ60ap90+KNAzderUcNKkAC0JgTwCM800k3vuuefCfvzAAw/MMynjItBtgb///e9h2h133NGtvvrqYV+sC0TtnBSAsd+Q6kTXXHNNuGimOpOSlu+ggw4KF9H0XrdVKvgTp+9+97uhTvSVr3wlXHTbaKON3FxzzRVG0W91q622cnfeeWcS+Ln00kvjyXnfTwWoB/TTFc9ityQwU0tTMzEC3RTQ1T31U/KPf/zD/etf/3K+2avzzX/dggsumCvHCRMmuNtvv909/PDDITij1jobb7yxy9MCwDdNDi1zNGMFb2abbbbMMsw+++zupz/9aSjrVVdd5f7nf/4n3OOrE1B/K0qYRtMvvvjimdMr+KP7+X0TeOebrIaKTqNKn64I6mqoglC6QvbHP/4xXEnTcvpmpqHfIc1M9xsrOPDQQw+Fk3tVLBWgSie5/+1vfwuVKLWimGWWWZyuPG677bZu5ZVXTo9e87OCCb5JtlOlbK+99goOGlkWWq8qh94r2LXOOuu4DTbYoEte6o9F/cvoCp5aRc0333zhit+ee+4ZKsRdJsj4Qn1yaP3ryr2M0knrVid4W2yxhRsxYkQY7NtMhuW/44473EsvveQUBJGBKp3LLLNMOotcy9Rl4owvVCZ/i19Yj6rc6gRArb8sSKhJtC7VykxJQUIlWclbSevXKsbhi+jfo48+GvLWV1p2JRlZfmqRpu1O362wwgph/n/961/DtqVxv/nNb4aKu97nWZ/dGV/TxEktmW699dbkarCWXa3nlNTPl/rJUrrppptCHw977713+Kzt+oorrgjLtcMOO4Rl0TY6aNCgsO3JV17q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&quot;&gt;
&lt;p&gt;For more details, refer to &lt;a href=&quot;https://queue.acm.org/detail.cfm?id=2977741&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;our in-depth publication on idle-time GC&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;如需要了解更多细节，请查看&lt;a href=&quot;https://queue.acm.org/detail.cfm?id=2977741&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;our in-depth publication on idle-time GC&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&quot;takeaways&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#takeaways&quot; aria-label=&quot;takeaways permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Takeaways&lt;/h2&gt;
&lt;p&gt;The garbage collector in V8 has come a long way since its inception. Adding parallel, incremental and concurrent techniques to the existing GC was a multi-year effort, but has paid off, moving a lot of work to background tasks. It has drastically improved pause times, latency, and page load, making animation, scrolling, and user interaction much smoother. The &lt;a href=&quot;https://v8.dev/blog/orinoco-parallel-scavenger&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;parallel Scavenger&lt;/a&gt; has reduced the main thread young generation garbage collection total time by about 20%–50%, depending on the workload. &lt;a href=&quot;https://v8.dev/blog/free-garbage-collection&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Idle-time GC&lt;/a&gt; can reduce Gmail’s JavaScript heap memory by 45% when it is idle. &lt;a href=&quot;https://v8.dev/blog/jank-busters&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Concurrent marking and sweeping&lt;/a&gt; has reduced pause times in heavy WebGL games by up to 50%.&lt;/p&gt;
&lt;p&gt;V8的垃圾回收器从起始到现在已经走了很长一段路。添加并行、增量、并发技术到现存的垃圾回收器中是一件持续多年的艰苦工作，但得到了回报，许多垃圾回收工作已经移交到了后台线程。这大大优化了 暂停时长、延迟、页面加载 等性能指标，并使得诸如 动画、滚动以及用户界面 更加流畅。&lt;a href=&quot;https://v8.dev/blog/orinoco-parallel-scavenger&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Parallel Scavenger&lt;/a&gt;将主线程新生代的垃圾回收总时长减少了20%-50%，根据不同的工作负载。&lt;a href=&quot;https://v8.dev/blog/free-garbage-collection&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Idle-time GC&lt;/a&gt;可以在闲置状态减少Gmail的JavaScript堆内存量45%。&lt;a href=&quot;https://v8.dev/blog/jank-busters&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Concurrent marking and sweeping&lt;/a&gt;已经减少了重度WebGL游戏的垃圾回收暂停时长50%。&lt;/p&gt;
&lt;p&gt;But the work here is not finished. Reducing garbage collection pause times is still important for giving users the best experience on the web, and we are looking into even more advanced techniques. On top of that, Blink (the renderer in Chrome) also has a garbage collector (called Oilpan), and we are doing work to improve &lt;a href=&quot;https://dl.acm.org/citation.cfm?doid=3288538.3276521&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;cooperation&lt;/a&gt; between the two collectors and to port some of the new techniques from Orinoco to Oilpan.&lt;/p&gt;
&lt;p&gt;但工作仍旧未完成。减少垃圾回收暂停时长对给予用户最佳WEB体验至关重要，我们已经开始涉足更先进的技术。除此之外，Blink（Chrome浏览器的渲染引擎）也有一个自己的垃圾回收器（代号Olipan），我们正在努力提升两个垃圾回收器之间的&lt;a href=&quot;https://dl.acm.org/citation.cfm?doid=3288538.3276521&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;协作&lt;/a&gt;，并将部分新技术也应用到Olipan上。&lt;/p&gt;
&lt;p&gt;Most developers don’t need to think about the GC when developing JavaScript programs, but understanding some of the internals can help you to think about memory usage and helpful programming patterns. For example, with the generational structure of the V8 heap, short-lived objects are actually very cheap from the garbage collector’s perspective, as we only pay for objects that survive the collection. These sorts of patterns work well for many garbage-collected languages, not just JavaScript.&lt;/p&gt;
&lt;p&gt;大部分开发者不需在研发JavaScript应用的时候考虑垃圾回收问题，但理解里面的原理机制能帮助程序员思考内存使用以及编程范式问题。举例来说，因为V8引擎堆内存有分代设计，短期存活的对象对垃圾回收器来说非常廉价，因为只需要处理存活的对象。像这样的原则对很多垃圾回收语言都通用，不仅仅只是JavaScript。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;EOF&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[V8 Blog | Speeding up spread elements 2018-12-04]]></title><link>https://xenojoshua.com/posts/2019/02/spread-elements</link><guid isPermaLink="false">https://xenojoshua.com/posts/2019/02/spread-elements</guid><pubDate>Tue, 19 Feb 2019 02:01:22 GMT</pubDate><content:encoded>&lt;div class=&quot;table-of-contents&quot;&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#1-%E5%8E%9F%E6%96%87&quot;&gt;1. 原文&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#2-%E6%91%98%E8%A6%81%E7%BF%BB%E8%AF%91&quot;&gt;2. 摘要翻译&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#spread-elements&quot;&gt;Spread elements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#why-is-or-were-spread-elements-slow&quot;&gt;Why is (or were!) spread elements slow?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#tread-carefully-down-that-fast-path&quot;&gt;Tread carefully down that fast path&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#own-symboliterator-property&quot;&gt;Own &lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt; property&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#modified-arrayiteratorprototype&quot;&gt;Modified &lt;code class=&quot;language-text&quot;&gt;%ArrayIteratorPrototype%&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dealing-with-holey-arrays&quot;&gt;Dealing with holey arrays&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#spreading-strings-sets-and-maps&quot;&gt;Spreading strings, sets, and maps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#improving-arrayfrom-performance&quot;&gt;Improving &lt;code class=&quot;language-text&quot;&gt;Array.from&lt;/code&gt; performance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;h1 id=&quot;1-原文&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#1-%E5%8E%9F%E6%96%87&quot; aria-label=&quot;1 原文 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;1. 原文&lt;/h1&gt;
&lt;p&gt;&lt;a href=&quot;https://v8.dev/blog/spread-elements&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Speeding up spread elements&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;本文大量提到了&lt;code class=&quot;language-text&quot;&gt;array literals&lt;/code&gt;这个概念，请参考MDN的解释：&lt;a href=&quot;https://developer.mozilla.org/bm/docs/Web/JavaScript/Guide/Grammar_and_types#Array_literals&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;MDN &gt;&gt; Grammar and types &gt;&gt; Literals &gt;&gt; Array literals&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&quot;2-摘要翻译&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#2-%E6%91%98%E8%A6%81%E7%BF%BB%E8%AF%91&quot; aria-label=&quot;2 摘要翻译 permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;2. 摘要翻译&lt;/h1&gt;
&lt;p&gt;During his three-months internship on the V8 team, Hai Dang worked on improving the performance of &lt;code class=&quot;language-text&quot;&gt;[...array]&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;[...string]&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;[...set]&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;[...map.keys()]&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;[...map.values()]&lt;/code&gt; (when the spread elements are at the start of the array literal). He even made &lt;code class=&quot;language-text&quot;&gt;Array.from(iterable)&lt;/code&gt; much faster as well. This article explains some of the gory details of his changes, which are included in V8 starting with v7.2.&lt;/p&gt;
&lt;p&gt;在为期三个月的V8团队内部实习中，Hai Dang在努力提升&lt;code class=&quot;language-text&quot;&gt;[...array]&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;[...string]&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;[...set]&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;[...map.keys()]&lt;/code&gt;, 以及 &lt;code class=&quot;language-text&quot;&gt;[...map.values()]&lt;/code&gt;的性能（当扩展元素在数组字面量（array literal）的起始）。他甚至让&lt;code class=&quot;language-text&quot;&gt;Array.from(iterable)&lt;/code&gt;也更快了。这篇文章解释了部分他改动的细节，这部分改动被包含在了V8 v7.2开始的版本中。&lt;/p&gt;
&lt;h2 id=&quot;spread-elements&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#spread-elements&quot; aria-label=&quot;spread elements permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Spread elements&lt;/h2&gt;
&lt;p&gt;Spread elements are components of array literals that have the form &lt;code class=&quot;language-text&quot;&gt;...iterable&lt;/code&gt;. They were introduced in ES2015 as a way to create arrays from iterable objects. For example, the array literal &lt;code class=&quot;language-text&quot;&gt;[1, ...arr, 4, ...b]&lt;/code&gt; creates an array whose first element is &lt;code class=&quot;language-text&quot;&gt;1&lt;/code&gt; followed by the elements of the array &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;, then &lt;code class=&quot;language-text&quot;&gt;4&lt;/code&gt;, and finally the elements of the array &lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;扩展元素是拥有&lt;code class=&quot;language-text&quot;&gt;...iterable&lt;/code&gt;形式的数组字面量（array literals）组件。它们是从ES2015被引入的特性，作为一种从可迭代对象创建数组的方法。举例来说，数组字面量&lt;code class=&quot;language-text&quot;&gt;[1, ...arr, 4, ...b]&lt;/code&gt;创建了一个数组，这个数组的第一个元素是&lt;code class=&quot;language-text&quot;&gt;1&lt;/code&gt;，然后跟着是数组&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;的元素，接着是&lt;code class=&quot;language-text&quot;&gt;4&lt;/code&gt;，最后是数组&lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt;的元素：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;b&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// → [1, 2, 3, 4, 5, 6, 7]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As another example, any string can be spread to create an array of its characters (Unicode code points):&lt;/p&gt;
&lt;p&gt;另一个例子，任何字符串可以用来扩展创建一个含有其字符为内容的数组（Unicode code points）：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; str &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;こんにちは&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;str&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// → [&apos;こ&apos;, &apos;ん&apos;, &apos;に&apos;, &apos;ち&apos;, &apos;は&apos;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Similarly, any set can be spread to create an array of its elements, sorted by insertion order:&lt;/p&gt;
&lt;p&gt;类似的，任何set可以被用来扩展创建含有其元素的数组，按插入顺序进行排序：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;V8&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
s&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;TurboFan&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// → [&apos;V8&apos;, &apos;TurboFan&apos;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In general, the spread elements syntax &lt;code class=&quot;language-text&quot;&gt;...x&lt;/code&gt; in an array literal assumes that &lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt; provides an iterator (accessible through &lt;code class=&quot;language-text&quot;&gt;x[Symbol.iterator]()&lt;/code&gt;). This iterator is then used to obtain the elements to be inserted into the resulting array.&lt;/p&gt;
&lt;p&gt;通常来说，扩展运算语法&lt;code class=&quot;language-text&quot;&gt;...x&lt;/code&gt;会假设&lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt;提供了一个迭代器（通过&lt;code class=&quot;language-text&quot;&gt;x[Symbol.iterator]()&lt;/code&gt;来访问）。这个迭代器被用来获取元素用以插入到新创建的结果数组中。&lt;/p&gt;
&lt;p&gt;The simple use case of spreading an array &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt; into a new array, without adding any further elements before or behind, &lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt;, is considered a concise, idiomatic way to shallow-clone &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt; in ES2015. Unfortunately, in V8, the performance of this idiom lagged far behind its ES5 counterpart. The goal of Hai’s internship was to change that!&lt;/p&gt;
&lt;p&gt;最简单的扩展一个数组&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;到一个新数组，并不在其前后添加任何元素，&lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt;这样的操作，被认为是在ES2015中最简洁、通顺的对&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;进行浅拷贝（shallow-clone）的方法。不幸的是，在V8中，这种写法的性能要远不及ES5中功能类似的其他写法。Hai实习的目标就是改变整个现状！&lt;/p&gt;
&lt;h2 id=&quot;why-is-or-were-spread-elements-slow&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#why-is-or-were-spread-elements-slow&quot; aria-label=&quot;why is or were spread elements slow permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Why is (or were!) spread elements slow?&lt;/h2&gt;
&lt;p&gt;There are many ways to shallow-clone an array &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;. For instance, you can use &lt;code class=&quot;language-text&quot;&gt;arr.slice()&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;arr.concat()&lt;/code&gt;, or &lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt;. Or, you can write your own &lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt; function that employs a standard &lt;code class=&quot;language-text&quot;&gt;for&lt;/code&gt;-loop:&lt;/p&gt;
&lt;p&gt;有很多方法可以浅拷贝一个数组&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;。例如，你可以使用&lt;code class=&quot;language-text&quot;&gt;arr.slice()&lt;/code&gt;或&lt;code class=&quot;language-text&quot;&gt;arr.concat()&lt;/code&gt;，或&lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt;。甚至你可以基于标准的&lt;code class=&quot;language-text&quot;&gt;for&lt;/code&gt;循环来编写你自己的&lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt;函数：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Pre-allocate the correct number of elements, to avoid&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// having to grow the array.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    result&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ideally, all these options would have similar performance characteristics. Unfortunately, if you pick &lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt; in V8, it is (or was) likely to be slower than &lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt;! The reason is that V8 essentially transpiles &lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt; into an iteration like the following:&lt;/p&gt;
&lt;p&gt;理想的情况下，所有这些选项都会有接近的性能。不幸的是，如果你在V8中使用&lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt;，它很有可能会比&lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt;要慢！这是因为本质上来说V8在处理&lt;code class=&quot;language-text&quot;&gt;[...arr]&lt;/code&gt;的时候是进行了一次如下的迭代：&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; iterator &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Symbol&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iterator&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; next &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; iterator&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;next&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; iteratorResult &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;iterator&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;iteratorResult&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;done&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;iteratorResult&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code is generally slower than &lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt; for a few reasons:&lt;/p&gt;
&lt;p&gt;这样的代码通常会比&lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt;要慢，是因为几个原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It needs to create the &lt;code class=&quot;language-text&quot;&gt;iterator&lt;/code&gt; at the beginning by loading and evaluating the &lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt; property.&lt;/li&gt;
&lt;li&gt;It needs to create and query the &lt;code class=&quot;language-text&quot;&gt;iteratorResult&lt;/code&gt; object at every step.&lt;/li&gt;
&lt;li&gt;It grows the &lt;code class=&quot;language-text&quot;&gt;result&lt;/code&gt; array at every step of the iteration by calling push, thus repeatedly reallocating the backing store.&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;它需要在一开始通过读取和评估&lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt;属性，来创建一个&lt;code class=&quot;language-text&quot;&gt;iterator&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;它需要在每一步创建并查询&lt;code class=&quot;language-text&quot;&gt;iteratorResult&lt;/code&gt;对象&lt;/li&gt;
&lt;li&gt;它在迭代的每一步中都需要使用push方法来增长&lt;code class=&quot;language-text&quot;&gt;result&lt;/code&gt;的长度，这导致了内存的再分配&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The reason for using such an implementation is that, as mentioned earlier, spreading can be done not only on arrays but, in fact, on arbitrary iterable objects, and must follow &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;the iteration protocol&lt;/a&gt;. Nevertheless, V8 should be smart enough to recognize if the object being spread is an array such that it can perform the elements extraction at a lower level and thereby:&lt;/p&gt;
&lt;p&gt;会使用这样的实现是因为，这我们之前提到过，扩展运算这个行为可以在很多目标上实施，不仅仅只是数组，事实上，是任何可迭代的对象，当然这些对象必须遵循&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;迭代协议（the iteration protocol）&lt;/a&gt;。尽管如此，V8应该足够聪明，识别扩展对象是不是一个数组，以便在低层级执行元素抽取操作，从而：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;avoid the creation of the iterator object,&lt;/li&gt;
&lt;li&gt;avoid the creation of the iterator result objects, and&lt;/li&gt;
&lt;li&gt;avoid continuously growing and thus reallocating the result array (we know the number of elements in advance).&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;避免创建迭代对象&lt;/li&gt;
&lt;li&gt;避免创建迭代结果对象&lt;/li&gt;
&lt;li&gt;避免持续增长结果数组，避免内存的再分配（我们在一开始就知道目标长度了）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We implemented this simple idea using &lt;a href=&quot;https://v8.dev/blog/csa&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CSA&lt;/a&gt; for fast arrays, i.e. arrays with one of the six most common &lt;a href=&quot;https://v8.dev/blog/elements-kinds&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;elements kinds&lt;/a&gt;. The optimization applies for &lt;a href=&quot;https://v8.dev/blog/real-world-performance&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;the common real-world scenario&lt;/a&gt; where the spread occurs at the start of the array literal, e.g. &lt;code class=&quot;language-text&quot;&gt;[...foo]&lt;/code&gt;. As shown in the graph below, this new fast path yields roughly a 3× performance improvement for spreading an array of length 100,000, making it about 25% faster than the hand-written &lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt; loop.&lt;/p&gt;
&lt;p&gt;对于数组（fast arrays）来说，我们使用&lt;a href=&quot;https://v8.dev/blog/csa&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;CSA&lt;/a&gt;实现了这个简单的做法，举例来说，含有最常见的&lt;a href=&quot;https://v8.dev/blog/elements-kinds&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;elements kinds&lt;/a&gt;的数组。优化是针对&lt;a href=&quot;https://v8.dev/blog/real-world-performance&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;真实场景&lt;/a&gt;进行的，扩展操作最初是从数组字面量开始的，举例来说，&lt;code class=&quot;language-text&quot;&gt;[...foo]&lt;/code&gt;。如下图所示，新的快速修改，对一个长度为100,000的数组产生了大约3x的性能提升，使得它比手写的&lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt;循环实现要快25%左右。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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48jEHTtJzMXb3K3DbXPuQ/68P9yL42gC4uG9QIeDgQgQgc1HIBCy8marqKhIFi9eLHBuiwCv6/37948pacGb383dT09Pl1atWm2gMnO9dfeh9x5Hkz4+dPg4eyUr97HFtdrIwj0PW4Tqx+5D67bR5MWblkvTbV361Y/debd10goI1uUfW+++y4u7B1svbpCG3A/XgIH3fnfs0qm+dek5EnRpY4t0nATr0nTp4RgBW7dfPe2ajhEX5WYgAkSgfggERlb4OMyePVuwltXcuXOtoeMcQq9eveS2226T7bfffrM+APUrsr934YOUmakmYzEQNveDGgNZ3igL3jLwY78RPDxBBBIGgUDICqT02muvyUUXXSRt27aVAw880LboxcI/4DfffCNXXnmlXHfddbbmVcKgz4ISASJABIhAVAgEQlZLliyRu+++W7p27So333yzDBgwwLywg8QKCgrMmS3O33LLLTJlypSoMs5IRIAIEAEikDgI1H9kfDMw+vnnn2X58uVy4YUXmuQEizkEqHiysrJs4cUjjjjCSAvExkAEiAARIAJEwItAIGSF+VXOaa334d59qAdhLbVmjXplZSACRIAIEAEi4EEgELLCvCNYsn355ZeeR6/fxdjVokWLzDXN1ltvvf4C94gAESACRIAIKAKBkBXmWbVp08bGrWBMASkLZseY1AnfaV9//bV5ZR80aJDAswUDESACRIAIEAEvAoEYWEDF9/e//13+9a9/ycknnyy77rqrdOrUyeb9YM7Vhx9+aMYXV111lTdv3CcCRIAIEAEiYAgEQlZ40v777y8dO3aUyZMny6effipvvPGGTeRs3769HHroofK3v/1N+vbty2ohAkSACBABIrARAoGRFTwAYPFFeFzHPjxZwHTdeTFw7oI2yiFPEAEiQASIQMIjEBhZYZzqzTffNFdLRx55pLRoEVnvAfOvVqxYISNHjpRddtnFyCvha4UAEAEiQASIwAYIBGJggSfed999ctlll8nUqVMlPz+/KhMwsJg+fbpcfPHFph6susAdIkAEiAARIAKVCARCVvPmzZOnnnrKjCqwnhWMK1yAC6aXX37ZHNpef/31php017glAkSACBABIgAEAiGrBQsWSF5enowdO7bGNa1AXlANwhM7PVjwxSQCRIAIEIHqCARCVlD1YeJvt27dqj/fjuF2ya0cDF+BDESA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&quot;&gt;
&lt;p&gt;Performance improvement of spreading a fast array&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; While not shown here, the fast path also applies when the spread elements are followed by other components (e.g. &lt;code class=&quot;language-text&quot;&gt;[...arr, 1, 2, 3]&lt;/code&gt;), but not when they are preceded by others (e.g. &lt;code class=&quot;language-text&quot;&gt;[1, 2, 3, ...arr]&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;请注意：&lt;/strong&gt; 虽然并没有在例子中体现出来，这个快速修改对目标扩展元素之后追加其他组件也有效（比如：&lt;code class=&quot;language-text&quot;&gt;[...arr, 1, 2, 3]&lt;/code&gt;），但追加在其他组件之后则不可以（比如：&lt;code class=&quot;language-text&quot;&gt;[1, 2, 3, ...arr]&lt;/code&gt;）。&lt;/p&gt;
&lt;h2 id=&quot;tread-carefully-down-that-fast-path&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#tread-carefully-down-that-fast-path&quot; aria-label=&quot;tread carefully down that fast path permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Tread carefully down that fast path&lt;/h2&gt;
&lt;p&gt;That’s clearly an impressive speedup, but we must be very careful about when it is correct to take this fast path: JavaScript allows the programmer to modify the iteration behavior of objects (even arrays) in various ways. Because spread elements are specified to use the iteration protocol, we need to ensure that such modifications are respected. We do so by avoiding the fast path completely whenever the original iteration machinery has been mutated. For example, this includes situations like the following.&lt;/p&gt;
&lt;p&gt;这无疑是令人印象深刻的优化提速，但我们必须非常仔细，保证这个快速修改必须是正确的：JavaScript允许程序员通过一系列途径改变对象（也包含array）的迭代行为。因为扩展元素被spec指定需要使用迭代协议，我们需要保证前述的一系列改动也一样能够正确工作。我们会检查迭代装置，在经过改动的情况下完全禁止这个快速修正的应用。举例来说，有下面几种情况。&lt;/p&gt;
&lt;h3 id=&quot;own-symboliterator-property&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#own-symboliterator-property&quot; aria-label=&quot;own symboliterator property permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Own &lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt; property&lt;/h3&gt;
&lt;p&gt;Normally, an array &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt; does not have its own &lt;a href=&quot;https://tc39.github.io/ecma262/#sec-symbol.iterator&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Symbol.iterator property&lt;/a&gt;, so when looking up that symbol, it will be found on the array’s prototype. In the example below, the prototype is bypassed by defining the &lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt; property directly on &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt; itself. After this modification, looking up &lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt; on &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt; results in an empty iterator, and thus the spread of &lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt; yields no elements and the array literal evaluates to an empty array.&lt;/p&gt;
&lt;p&gt;通常情况下，一个数组&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;不会有自建的&lt;a href=&quot;https://tc39.github.io/ecma262/#sec-symbol.iterator&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;Symbol.iterator属性&lt;/a&gt;，因此当查找这个symbol，会追溯到数组的prototype上。在下面的例子中，原型上的实现会被略过，因为&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;自己已经直接实现了一个&lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt;属性。经过这个修改，当访问&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;上的&lt;code class=&quot;language-text&quot;&gt;Symbol.iterator&lt;/code&gt;属性时候，会得到一个空的迭代器，导致&lt;code class=&quot;language-text&quot;&gt;arr&lt;/code&gt;的扩散操作得不到任何元素，并且最终的结果数组是一个空数组。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; arr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
arr&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Symbol&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iterator&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// → []&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id=&quot;modified-arrayiteratorprototype&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#modified-arrayiteratorprototype&quot; aria-label=&quot;modified arrayiteratorprototype permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Modified &lt;code class=&quot;language-text&quot;&gt;%ArrayIteratorPrototype%&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;next&lt;/code&gt; method can also be modified directly on &lt;a href=&quot;https://tc39.github.io/ecma262/#sec-%25arrayiteratorprototype%25-object&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;%ArrayIteratorPrototype%&lt;/a&gt;, the prototype of array iterators (which affects all arrays).&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;下一个&lt;/code&gt;例子，程序员可以直接修改&lt;a href=&quot;https://tc39.github.io/ecma262/#sec-%25arrayiteratorprototype%25-object&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;%ArrayIteratorPrototype%&lt;/a&gt;，数组迭代器的原型（这会影响所有的数组）。&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPrototypeOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Symbol&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;iterator&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token literal-property property&quot;&gt;done&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; arr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;arr&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// → []&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id=&quot;dealing-with-holey-arrays&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#dealing-with-holey-arrays&quot; aria-label=&quot;dealing with holey arrays permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Dealing with holey arrays&lt;/h2&gt;
&lt;p&gt;Extra care is also needed when copying arrays with holes, i.e., arrays like &lt;code class=&quot;language-text&quot;&gt;[&apos;a&apos;, , &apos;c&apos;]&lt;/code&gt; that are missing some elements. Spreading such an array, by virtue of adhering to the iteration protocol, does not preserve the holes but instead fills them with the values found in the array’s prototype at the corresponding indices. By default there are no elements in an array’s prototype, which means that any holes are filled with &lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;. For example, &lt;code class=&quot;language-text&quot;&gt;[...[&apos;a&apos;, , &apos;c&apos;]]&lt;/code&gt; evaluates to a new array &lt;code class=&quot;language-text&quot;&gt;[&apos;a&apos;, undefined, &apos;c&apos;]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;拷贝带空洞的数组需要额外的注意，举例来说，像这样的数组，&lt;code class=&quot;language-text&quot;&gt;[&apos;a&apos;, , &apos;c&apos;]&lt;/code&gt;当中缺失了部分元素。扩展这样的数组，根据迭代协议，并不会保留这些空洞，而是将从数组原型链上找到的对应位置的值填入到这些空洞中。默认上，数组原型链上是没有元素的，这导致了这些空洞被&lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;填上。举例来说，&lt;code class=&quot;language-text&quot;&gt;[...[&apos;a&apos;, , &apos;c&apos;]]&lt;/code&gt;最终会是&lt;code class=&quot;language-text&quot;&gt;[&apos;a&apos;, undefined, &apos;c&apos;]&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Our fast path is smart enough to handle holes in this default situation. Instead of blindly copying the input array’s backing store, it watches out for holes and takes care of converting them to &lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt; values. The graph below contains measurements for an input array of length 100,000 containing only (tagged) 600 integers — the rest are holes. It shows that spreading such a holey array is now over 4× faster than using the &lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt; function. (They used to be roughly on par, but this is not shown in the graph).&lt;/p&gt;
&lt;p&gt;我们的快速修正足够聪明，可以处理这些默认情况下的数组空洞。它会很小心地避免将这些空洞转成&lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;值，而不是根据默认行为直接将源数组的值拷贝过去。下图中的数组长度为100,000，但仅包含了600个整型（有标签） - 剩下的全部都是空洞。图表显示了，扩展这样的一个带洞数组现在要比&lt;code class=&quot;language-text&quot;&gt;clone&lt;/code&gt;函数快上超过4x。（它们之前的表现是基本相同的，这在当前的图表上没有得到体现）。&lt;/p&gt;
&lt;p&gt;Note that although &lt;code class=&quot;language-text&quot;&gt;slice&lt;/code&gt; is included in this graph, the comparison with it is unfair because slice has a different semantics for holey arrays: it preserves all the holes, so it has much less work to do.&lt;/p&gt;
&lt;p&gt;请注意，虽然&lt;code class=&quot;language-text&quot;&gt;slice&lt;/code&gt;出现在了这张图表上，但这样的比较是不公平的，因为slice在处理空洞数组上有不同的工作机制：它保留了所有的空洞，因此对它来说，要做的工作会少很多。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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IiACIiACHY5AhxCk9LN66qmn7O2337a5c+e68Ntggw1s1113tf79+/tNnzZtmv3zn/+0efPmZT0Ew4cPt7322st69OhhS5Ysseeff95efvllmzNnjvXt29e2224722abbQyhqiACIiACItDxCCxXydrptSP8/vWvf9k//vEPW3/99e2www7zNfvEL1682K984sSJ9uyzz/p+t27dLC5oozG88MILdsstt9hKK61khxxyiAvkm2++2caOHRuTaC0CIiACItDBCLR7NQpt9MUXX7SDDz7Y9t13X7+9G220kZtwn3zySdtzzz1t0KBBxni4mH1POukk1z5znwM01eeee8422WQTO+KII/zwhhtuaBdeeKEL4I033th69uyZm037IiACIiAC7ZxAu9dIu3fvbjvvvLObYJP3cuWVV7bY1rl06VLDtIumiQb61Vdfuek2mR6T8EcffWQ77bRTJpp2U8r++OOP65mEM4m0IQIiIAIi0K4JtHuNtE+fPnbQQQdlOQtxR5955hkbOnSoa584GaGRYs69+OKLbcqUKZ5+yy23dE12hRVWcEckhCl5kmHVVVe1L7/8MmMiTh7TtgiIgAiIQPsn0O4FKbcw6XFLm+jjjz9u48aNsyOPPNIdhmbPnu2DPk+ePNk1ThyI3nrrLXviiSfcwejoo492j188eFmSIToh4RXcUEDrje2xDaXTMREQARFoDAHeK/iCdIT3C8pONYYOIUgjeDTPRx55xO6//37be++93SxLFxjaNmkrHThwoDsikX7UqFF211132b///W9PizCOSywvruk6w9JQYHaGCRMmNJREx0RABESg0QTwA2FJOkY2upA2kmHdddetypp2GEGKRnj77bd79xU8bhGU8euGdtQddtgh6wYhYImjS8z06dNdyOKMlKt5Lly40B/gXE01q7CwQzeb1VdfPTda+yIgAiLQLAIzZszwHgR6vzQLY7MydwhBiun2+uuvt3feeccOP/xw22233bJMtAzUQB9TvnZoD40hCk0ELsKW9lacklZZZZWYxL744gsbMGBA0a9BBG0U3JnM2hABERCBZhLgvYI2qvdLM0E2I3u799pFY6TP6Pvvv28//OEP7etf/3qWEIUdXrrXXHONt4lGlphq6Ve64oor2uDBgzNffAzsEAUsGurTTz9ta665ZpYAjmVoLQIiIAIi0P4JtHuN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heI+++zj7aOYdrt06VLPHo+2ygPIBLqlpEmeJ3d75syZ/gDnxmtfBESgOggwSTbd0xA4bambGr4dvF9iG2kuTZSB66+/3pUHeiSwz7WiYKCBY7L90Y9+lJut3n418Fl99dXr1asaIjqMIEUg4khAuygdmHEqim2mPIBonaRJBgQoATNGKWmSebUtAiIgAtVAgK4x+Imsueaaduyxx7oljnfbv//9b7vtttvskksusW222cY23bQ6BzuoBobF6tAhBCkPzcsvv2x/+9vfbNCgQf4wrbbaahk2dImhjYG20GTgK693796urcY2iIbSJPPmbvPlV61fU7l11b4IdEQCWKX4YMZrvy21keLvQbNUofcL77pbbrnFHYS4xhh233137+r3m9/8xp588knbf//946G867bKJ+/FtHBk/r4YLXySSheHEL3xxhv9x3H88cf7DyVZJwTpkCFD7IMPPkhG27vvvuteexwvJU1WZu2IgAiIQBUQoIlqxRVXrNf3k48GNNEVVljB33VVUNU2W4Xlnydt9hIarviXX35p9913n395HXbYYT4CyJQpUzwTJlseMBrdcTz617/+5eYN9sn36KOPepcY9tFqi6VpuCY6KgIiIAKVJUCzFn3rcZ7E7wOrG+/B5KALla1h2zx7uxekH3/8sX344YdusjnvvPOy7hLdX84991zXOjFzMKrRxRdf7BrrZ599ZhtssIHttttu3kWGr7piabIK144IiIAIVAkBlAcUhWeffdYtbzgdzZ4925uzcFZSaB6Bdi9I119/ffvtb3+blxJfYrSZEmgXYchAvHq/+uorHwGJPqiYPWIoJU1Mq7UIiIAIVAMB2lBPOukkF6S0/R5++OG2xRZb2OrBA5bxx0877bRqqGabrkO7F6Q4C7GUEhirsth4laWkKeVcSiMCIiAC5SBA09Zdd91lhx56qDsd4e8RA+OHY21TaB6BDuFs1DxEyi0CIiACDROgvbEpoan5OFepeZ944gnvlXD66ae702SsJ/nHjx/v3QFjnNZNIyBB2jRuyiUCIiAC3v/8F7/4hW233Xau9eX2RS+EiHR3332352NsXwY7KDU0Ni8WOfK8+OKLWaeIfUhxQKIfvULTCUiQNp2dcoqACHRwAu+8845PycjQe8yKUqrjDo4+9Gsn35///Gd76623SibZ2LyYdPH1+OlPf+rm3VNPPdU233xzO/nkk23nnXd2fxA8eUv9CCi5oh0ooQRpB7rZulQREIGWJTB06NBMlzmmGMsdr7vQ2UjHSEJ0rWOmKRwbSw2NzbvDDjvYRRddZOutt57de++93k6KYGWKOLRpNFa0UpwsFZpGoN07GzUNi3KJgAiIQHECeP0z2Av9MRGGdKkrJTAYAhrhIYcc4uPdMiBMqSE3LyMO4ZlbKCB4jzvuOJ9XGc0T5yIm5KDuaKEMFUhAqCs0jYAEadO4KZcIiEA7JIBgwQmHQesZFjQ5pF6hy0UrZWlsQHChJTYlJPM2JERj2Qjf5LCoMZ51nIM5GRe3abuNY47HOK3rE5Agrc9EMSIgAh2UADO/XHDBBW7uxIHo4IMPLjirSkdAdNNNN9mbb77pl8pob4wEp1CfgARpfSaKEQER6KAEpk6daggPAmbQb33rWx1akD7wwAM+kEMHfRxKvmwJ0pJRKaEIiEB7JsBwogrZBBCkCsUJyGu3OCOlEAEREAEREIGCBCRIC6LRAREQAREQAREoTkCCtDgjpRABERABERCBggQkSAui0QEREAEREAERKE5AgrQ4I6UQAREQAREQgYIEJEgLotEBERABERABEShOQIK0OCOlEAEREAEREIGCBCRIC6LRAREQAREQAREoTkCCtDgjpRABERABERCBggQkSAui0QEREAEREAERKE5AgrQ4I6UQAREQAREQgYIEJEgLotEBERABERABEShOQIK0OCOlEAEREAEREIGCBCRIC6LRAREQAREQAREoTkCCtDgjpRABERABERCBggQkSAui0QEREAEREAERKE5AgrQ4I6UQAREQAREQgYIEJEgLotEBERABERABEShOQIK0OCOlEAEREAEREIGCBCRIC6LRAREQAREQAREoTqBL8STlS1FXV2dLly71pVOnTtalSxerqakpXwV0JhEQAREQARFoJIGKC9La2lr74IMP7J133rFPP/3U5syZYwsWLLBu3brZgAEDbPjw4bbhhhvaGmus4YK1kden5CIgAiIgAiLQqgQqJkjRPJ955hm78cYb7cMPP7TZs2e7AEUrjQGttGfPnta3b1/bYost7IQTTrD1118/HtZaBERABERABCpOoOyCFAGK4Lzqqqvs2WeftX79+tnIkSNtq622sg022MAGDx7swnPmzJk2depUe/311+2ll16yV1991Q466CDbZ5997LjjjrMRI0YYglZBBERABERABCpJoOyC9O9//7vdeuuttt5669l5551n22yzjQ0bNqxeW+iqq67qXL7+9a/bsmXL7KOPPrLnn3/e/vvf/9ppp51mJ598su2yyy6VZKdzi4AIiIAIiICVXZB+8skndv7559tGG21kvXv3ridA890TNM+1117bl3333ddeeOEFmzRpUr6kihMBERABERCBshIouyA966yzsi4Qx6IlS5ZYnz59ShKq/fv3tz333DOrDO2IgAiIgAiIQKUIVLyR8Y477rBzzz3XZsyYUSkGOq8IiIAIiIAINJlA2TXS3JqOGTPGu7yglSqIgAiIgAiIQFsjUHGNlD6i9B3FQxenIgUREAEREAERaEsEKq6R7r333t615ZxzznEv3FVWWcV69OhRjyH9R9WHtB4WRYiACIiACFSYQMUF6VNPPWUTJkyw+fPn2/jx431Eo86dO9fDosEY6iFRhAiIgAiIQBUQqLgg3WGHHdxjtxgLBmxQEAEREAEREIFqI1BxQfq1r33NWBREQAREQAREoC0SqLggjdAYY5dhAN944w2f/eWYY46xjz/+2IYMGWIrrLBCTKa1CIiACIiACFQVgYp77eKpO27cODvwwAPt0EMPtV/96lc+hODixYvtpptust13391HMmKMXgUREAEREAERqDYCFRekn332mZ199tk2d+5c+9GPfmS0mRIYFnDzzTe3rl272hlnnOGD11cbPNVHBERABERABCouSO+//3732L388svtZz/7mW266aZ+VxCg+++/v1155ZXex/TJJ590k69umQiIgAiIgAhUE4GKC1JmdNluu+18NpguXbKbbNlHK91yyy19kPpFixZVEzvVRQREQAREQASs4oK0trbWEJg1NTUFb0ecd7ShNAUz64AIiIAIiIAItCKBbBWwFU9UqGhGK8LZiIm88dDNDR988IF78/7gBz+w7t275x5u9P7s2bPtueeecyempAaMcxNTvOWO+ctUb8yNGgeJwLt47NixNm3aNJ9HlUnJJeAbfRuUQQREQATaDYGKC9KDDjrI/vWvf9mpp55qZ555piHo8OT94osv7P3337cLL7zQB2zA/Bs106bSX7hwoZ/rgQce8OEIk4KUrja00yJIk+dh3tRjjz3Wu+BMnz7drrrqKjcz9+rVy8cIXmuttezEE080pndTEAEREAER6HgEKi5IN9hgAzv55JPtmmuu8e4v3bp1c2H2ve99zz7//HMXogiqrbfeull3h0HxH3zwQfvPf/5jmJNzAxombbDHHXdcVr9V5kll7F8E7COPPGKzZs1yL2K0VAT9ddddZ4899pgdcMABGa01t2zti4AIiIAItF8CFRekmGuPOOII7/aCpoiZ96uvvrJ+/fr5BN7f/OY3bc011/R21Kbehnfffdf+9Kc/eRebjTfe2E2zuWUhSBGYhTTfL7/80l577TUbNWqUrbPOOp4ds+5OO+3k8XvssYfXObdc7YuACIiACLRvAhUXpGh4mHIRTqeddlpe2p9++qlriQMHDsx7vFgk7Z8Ivf3228/wEkZYJwPH0VhXW20114InTpzo7bEjRoywAQMGuKl3wYIFNnnyZGPat2RgH42U4wh/BREQAREQgY5FoOKC9Pbbb/d2UdpIe/bsWY8+Zthvf/vbRlsq/Uyj00+9hA1E0M6JJlrIKQiTLoIUAXr99df7IBCTJk0yHI0OP/xw735D+yqORrl1RHjOmzdPfVwb4K9DIiACItCeCZRdkCIYx4wZ40IJsK+88ooLooceeiivVy7tkJhdyYcga0pIOg/ly49GTNvs9ttvb/vss48LUoQjg0H84x//sLXXXtvbSPN100GwUy/KaCjglcx0cQoiIAIi0JIEsOrxfuEd1t7D6quvXpWXWHZBijBiDlLaQxFAcQzd119/PS8ghODQoUNtk002aVY7ad7C05FolXgMJ0Pfvn3tqKOOsvPPP9/w1uUhpa65wjwK0ELabrJMbYuACIiACLQ/AmUXpCDERIupFSGEJyztizgV5X5RIZwYKhAP2W233bbV6FMPNFC6tCRNxwhYBD+Tjg8ePDjTVpqsCF+CmICTXWmSx+M23WOq9Wsq1lFrERCBtkdgxowZ3uSk90vl7l1FBOmwYcPs6KOP9qvGmQchRhtoSwy40BSU9Fm97LLL7Cc/+UnGI5dyeEDRiHFywqOXASMYIIK+ozHgEcz1cFxBBERABESg4xGo+BCBaIHMN1rINIq2iAb7t7/9rZ5ZtaVuF3XAieiuu+4yurkg2HE+uuOOO9ykjLCnPylOSwwegfcuaZi55tFHH3WPYI4riIAIiIAIdDwCZddIEYyYQ2NggAT2t9hiCzetxvi4Rmj985//dK2QNspiJtSYrzFrTLjMh/rXv/7VLr74Ym+TxWsXTZSBFuLE4syNSjxpMDcjSBlQYrfddssyCTfm3EorAiIgAiLQtgmUXZCC6/TTT894sDL4AgISx558WindTjCvrrjiii0irHbccUdvn02akSl/q622cpMtXWAYppA2UUy2OB3FgPDE/Esa6k2alVZaKSNoYzqtRUAEREAEOg6BsgtShNZ3v/tdu+iiizKmWgQoC8dyA9ogQu5b3/pWXkGbm77YPuVFDTOZNgprBHZDAcGaFK4NpdUxERABERCB9k+g7IIUpAyrd++997ogvfbaa10DZLzd3MEOEK547Sa1x/Z/S3SFIiACIiACbYlARQQp2l/UCn/84x97NxjaI/OZdtsSTNVVBERABESg4xGoiCBNYsYjlplVmOnl2WeftTfeeMNNvKNHj7aXX37Z+2gyZymaqYIIiIAIiIAIVBuBigtSBozHzIuJF49YvHJx4kG43nffffbwww/b8ccf7+2quabfaoOp+oiACIiACHQ8AvW9e8rM4L333vMJtfGI/fOf/2yHHHKI14BRjo488khjBpYbbrjBnnnmmTLXTKcTAREQAREQgeIEKi5IGQRh5ZVXtt/97ne2zTbbGEPpEWhHZRjBm266yQesf+mll/JOyF38EpVCBERABERABFqPQMUF6fjx423TTTfNCNDcSx00aJAP1sCIQ5iBFURABERABESgmghUXJC8Rmi4AAAytklEQVTSJkp7aO6sKklIc+bMcWejfP1Mk+m0LQIiIAIiIALlJlBxQcqsLi+88IIx+DvDByYDGugTTzxhTLG2xhprqD9pEo62RUAEREAEqoJAxb1299tvP/fMPe2003xS7bfeessYFvDBBx+0N9980+655x4Xorvuuqv6mVbFI6NKiIAIiIAIJAlUXJAyh955551nv/zlL+2aa65xJyM001/84hc+TynHf/Ob32RNb5a8AG2LgAiIgAiIQCUJVFyQ0u65ww47+ATfY8aMsXHjxvmA8MzIwhi7zLiiuT4r+Yjo3CIgAiIgAg0RqLggjZVjPN099tjD5/+kbbR3794+kTb9SRVEQAREQAREoFoJVIUgxSv3L3/5i91///02d+5cdzrCm5f+pcwUs+eee1YrP9VLBERABESggxOouNcuk3r//Oc/tz/84Q+GQEUTZSozNNSPP/7YTjrpJB/5aNGiRR38VunyRUAEREAEqpFAxTXSRx991AerP+aYY+yAAw6w4cOHG+ZcBCeDNdx6660+dOBGG21ke+21VzUyVJ1EQAREQAQ6MIGKa6QPPfSQ0Zf0Rz/6ka299touRLkfaKSbb765XXDBBT7q0YsvvqiRjTrwg6pLFwEREIFqJVBxQYo5d6WVVnKTbj5Iffv2tXXXXdfbTmtra/MlUZwIiIAIiIAIVIxAxQXp9ttvbwzCwFi6+cK0adOMGWKYBQYtVUEEREAEREAEqolAxQXpoYce6uPsnnnmmfbOO+9kxtxl7N23337bTjnlFOvTp4/tv//+1rlz52pip7qIgAiIgAiIgJXd2Qjv3KuvvjoLPUKThTlHBw4caJhzMfnOmDHD45kB5j//+Y93hcnKqB0REAEREAERqDCBsgtS2jv32WefRl/20KFDG51HGURABERABESgtQmUXZCOGjXKdt5550ZfV9euXRudRxlEQAREQAREoLUJlF2Q0kdUw/619m1V+SIgAiIgAuUiUHFno3JdqM4jAiIgAiIgAq1BQIK0NaiqTBEQAREQgQ5DQIK0w9xqXagIiIAIiEBrEJAgbQ2qKlMEREAERKDDEJAg7TC3WhcqAiIgAiLQGgTK7rWbexEMxMBUah9++KEPUs/oRdOnT7cbb7zRhw7cYIMN7KijjrJVVlnFampqcrNrXwREQAREQAQqSqDiGilj6Z511ln2ne98xyZOnGjz5s2zc8891wUp85HecccddvLJJ9uECRMqCkonFwEREAEREIF8BCouSMeMGWPPP/+8nXjiiTZ48GDXQv/3v//Zeuut53ORXnnllR73xBNPZMbhzXchihMBERABERCBShCouCB96qmnfKSj73//+9ajRw974403bPbs2T5I/Zprrmm77babjRw50k2/TPatIAIiIAIiIALVRKDigpSB6dFEEaILFizwGV+Yd/TrX/96hhOzvyBEly1blonThgiIgAiIgAhUA4GKC9L+/fu7s9HixYtt1qxZbsZda621bPXVV3c+CxcutPHjx/tUal26VNw3qhrumeogAiIgAiJQRQQqLkh33313e/rpp+3OO++0P/7xj/bBBx/YAQcc4IhwMDr99NN9SrWNNtpIY/RW0YOjqoiACIiACKQIVFzF22uvveyVV16xK664wk23zA6DIEVDve666+zxxx+3gw8+2IhXEAEREAEREIFqI1BxQTpgwAAbPXq0nXDCCbZ06VIbMmSIYe6lfykCFSG6/vrrW+/evauNneojAiIgAiIgAlYRQYqQjIMrsMaZiCUZiN96662TUdoWAREQAREQgaojUHZB+txzz9mLL75o2223nW2//fb25JNP2tixY4uCIS15FERABERABESgmgiUXZAiRK+++mpngGCkH+ltt91WlEmnTp0kSItSUgIREAEREIFyEyi7ID3ssMNs1113tWHDhrl59wc/+IHtt99+Ra+b9AoiIAIiIAIiUG0Eyi5IV1ppJWOJYdVVVzUWBREQAREQARFoiwQq3o+0LUJTnUVABERABEQgEpAgjSS0FgEREAEREIEmEJAgbQI0ZREBERABERCBSECCNJLQWgREQAREQASaQKDigpQp06ZMmeKjGjWh/soiAiIgAiIgAhUlUHFBeu2119opp5xi06dPrygInVwEREAEREAEmkKg7N1fcivJgPXz5s3zsXVzj2lfBERABERABKqdQMU1UgZn+PLLL+399993gdrak3czMD7znjLeb74wf/58w9zMulAoJU2hvIoXAREQARFoXwQqrpFuttlmNmbMGDvjjDN87N2VV17ZevToUY/yNttsYyzNCQjPN9980+6//34788wzrXv37pnilixZYs8//7y9/PLLPv9p3759fUhCzhknFC8lTaZAbYiACIiACHQIAhUXpIy1izbK/KMIOEKcGSZ5B3760582W5B++umnPq7vZ5995nOfJst/4YUX7JZbbjEmGt9zzz19svGbb77ZunbtmpmFppQ0yTK1LQIiIAIi0P4JVFyQHn744T72bjHUq622WrEkBY8vXLjQZ5y5/fbbrba2tl462miZlWaTTTaxI444wo9vuOGGduGFF9qzzz5rG2+8sQveYml69uxZr2xFiIAIiIAItG8CFReka6yxhrG0ZnjrrbfskUcecU0T8+wDDzyQdbq5c+faRx99ZD/60Y8y8WjFO++8s917773edkvbarE0EqQZfNoQAREQgQ5DoOKCNJLG4ei+++7zNkzaJC+55BLXEgcPHmzrr79+TNakNflPO+00GzBggD366KP1yli0aJEhTIcOHZp1jMH0qRdmZzTZYmmyMmtHBERABESgQxCouCBF08PZ6Lzzzst0g0F4ojmiRf7973+3iy66yA488EBvr2zKXendu7exFAoLFiywzp07+5JMg9MT9cCTuJQ0yby521wnAllBBERABFqSAO8V3lMd4f3SrVu3lkTXYmVVXJC+/fbbdumll9p6663nplccel5//XX3lMXxZ/z48XbZZZf51GuYWlsjYMaNS275ePqyxOOsc0NMkxuf3J85c6ZNmDAhGaVtERABEWg2AbrzseAY2d7DuuuuW5WXWHFBijkXk+sFF1zgbaVTp07NCFL6mK611lo+8TddU3bYYYdMV5SWpEnbJqbb3D6sOCnxcKKtlpKmoTr179/fVl999YaS6JgIiIAINJrAjBkzrFevXnq/NJpcy2WouCB97bXXjL6k+Sb3RvsbPny4bb755jZt2jQ3XcQ+nS2HwLw/aZ8+ffwcq6yySqboL774woU8wpTzFkuTyZhnA2FcrWaJPNVVlAiIQBshwHuFd5TeL5W7YRUf2QgBhW0/VxtMIsHJh3T5zKrJdE3djl9z9GmN9UBDffrpp23NNde0FVZYIfPF11Capp5f+URABERABNougYoLUrRNzLaTJk3KSxHBRfcV+pHmG/Eob6ZGRuKItP322xva8Q033GAvvfSSMZg+3V123HFHP28paRp5WiUXAREQARFoBwQqbto9+OCDvV/nkUceaaeeempmSjVGO0IjvPrqq23YsGG2yy67tIhGinkWM3JSu2V7p512MrrBPPzww/bGG294m+gxxxyTGdWIe11KmnbwTOgSREAEREAEGkGgJnic5h+9vRGFNCcpJtTHHnvMBSYevIROnTq5Foizz0YbbWQnnHCC7bHHHlnCrznnbCgvwpSRjjDnFmpzKCVN8hyjR4/20ZtwnlIQAREQgZYkgLMRS7V6tLbktVZrWRXXSGn7REjicES3F8yrdBVh0HjMviNHjvSBEpIaZGvCZCD75GD2+c5VSpp8+RQnAiIgAiLQ/ghUXJCCFI9WzLcs3/jGN9ofZV2RCIiACIhAuyVQFYIUr9x3330308UlH20GbGBREAEREAEREIFqIlBxQYoZ9/zzz/dxdWl7jN1PciEdf/zxEqS5ULQvAiIgAiJQcQIVF6QPPvigsTADzHbbbWcDBw7M61S0xRZbVByWKiACIiACIiACuQQqLkjx2GXuzz/84Q82YsSI3PppXwREQAREQASqmkDFB2SYPXu2m2yHDBlS1aBUOREQAREQARHIR6DignTTTTf1QRiYpkxBBERABERABNoagYoL0m9/+9s+efYdd9xhEydO9Hn12hpE1VcEREAERKDjEih7G+ltt91mCM0Y8NKdPHmyj2171113+WAIjGyUGxhCkEVBBERABERABKqJQNkFKTO5z58/P4sBc3USGK2QYQHzhY4w+3u+61acCIiACIhAdRMouyA96KCDbNSoUY2mEoVtozMqgwiIgAiIgAi0IoGyC1IEooRiK95RFS0CIiACIlBWAmUXpLlXN2bMGHv55Zdzo7P2GYuX6c8YtIFB7FdaaSWf6DsrkXZEQAREQAREoAIEKi5ImTz7/vvvd89dZoKhP2nPnj2N/qVMDYQzEpNq035KF5lVVlnFTjvtNNt7770lTCvwwOiUIiACIiAC2QQqLkiZ7eXee++14cOH25lnnmkrr7yyzwaDc9FLL71kv/71r42+pmeddZZ98cUXdskll9iVV15pW221lafNvhztiYAIiIAIiEB5CVRckGLaRRO96qqr6glGhgxkgu1zzjnHhejOO+/saQ477DAbO3ZsvfTlRaeziYAIiIAIiIBZ/Q6bZabyzDPPGAPSr7jiinnPzKTfdJl55513/PiAAQNsnXXWsQ8//DBvekWKgAiIgAiIQDkJVFyQoo3Sr7S2tjbvdTNXKdOrJQPtpYXSJ9NpWwREQAREQARam0DFBen2229v//3vf+2FF14whCZCkrB06VJ3NqKNtFevXrb22msb7aZooh988IGtu+66rc1G5YuACIiACIhAUQIVbyPdf//97T//+Y+dfvrpRhso7aLdu3d3r9033njDXn31VWMQh2222cYeeughu+KKK2zYsGG25ZZbFr04JRABERABERCB1iZQcUFKn9Df/OY3PtbuP//5T9c6a2pqXDNFYJ599tmGsMXpCC/eVVdd1X7605/a0KFDW5uNyhcBERABERCBogRqgik1ZUstmrT1E2DaHT9+vM2aNcsGDx5s66+/vvXo0aP1T9zKZxg9erTtuuuuvrTyqVS8CIhAByNAf3sWNXdV7sZXXCNNXjpaJyZcBREQAREQARFoKwTKLkgfeeQRe/TRR41uLXvuuacPxkAXmGLh//7v/4zBGxREQAREQAREoJoIlF2QTpgwwb106QuKVRkPXLx2i4X11luvWBIdFwEREAEREIGyEyi7IP3mN7/pA8+vttpqhlPRIYccYl/72teKXjjpFURABERABESg2giUXZAiEJNCcfXVVzcWBREQAREQARFoiwTKLkhzIWHexUuXAemnTJnioxzlcyTGIw1zsIIIiIAIiIAIVBOBigvSyZMn24UXXmhPPfWULVy4sCAb+o6efPLJBY/rgAiIgAiIgAhUgkDFBel9991njz/+uH3961+3fffd1wYOHOhtp7kwmIdUQQREQAREoOUJ/O1vfzOGa2U6y5YKTDby73//20ehY3Cd9hwqLkjp+sJwfxdddFHBGWDa8w3QtYmACLQcAZqI/vWvf9mf//xnH9yFQV4GDRpk2223nX3729/2LnT9+vXLnBAr2CmnnGLXXXddJo6Nq6++2k488cSsuPa4M2fOHDvvvPPs9ttvdwYtKUhnzpzpHLE63nPPPe4Lg4NpewwVF6TM4sLN69mzZ3vkq2sSAREoE4Fx48bZqaeeanyc805BePJemT17to/ZTR92hOwuu+ySqVHnzp19xDFmoSIwtjcTaHSEwKxbv/3tb+2WW26xCy64wOhR0ZKBDxjK/f73v2/f+c537E9/+pNtuOGGLXmKqimr4oKUkYxefvllW7Bggc/yUjVkVBEREIE2Q2Dq1Kl2/PHH2//+9z87+uij7cwzz/RhRhGUmBgRpsxpPHLkyKxr6tq1qx188MF2wAEHeDzjfr/44otZadrrzpNPPumTgPzsZz+zY4891mDRkgHtc6uttrIbbrjBRo0a5WOqX3nlldanT5+WPE1VlFV2QcpXEEIzht13393uv/9+/yo69NBDfWzdfOo/U6lJa43UtBYBEYgE8PK/++67DY10iy228Bc2vhbJsOKKK9oaa6yRjMpso41GjTSuMwdL2MB8zFi38b3GuwptjHWh8Omnn7pzJV3/OOeXX35pX331lc+z3Lt3b2Myj4YEG5Y8zkmPB9a8V5nII2m2LnRu4smHA+cmm2xixx13XIPniuXwMYK5lutkmkvGQec6+/btG5PUW/Mup+31l7/8pV188cXGO54R7dpbKLsgffDBB31YwAhy2bJl/sV47bXXGrO/DBkyJO9NZSo1FgUREAERSBKgnY/R0WjvxLM/V4gm07bkNu8uNOA//vGPfv5Jkya5oyT95BkClbZX5lHOF2h/feWVVwyt8Pnnn/c2XczKXAsCH3MoWnU+pWLevHl266232p133mlMNYkQHTBggO222272k5/8xHbYYQfr1Knh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1TNbb731bJNNNvG2044wcW1eCIoUAREQARGoWgIVF6RooDgbxSnLckkRz0D2DM+nIAIiIAIiIALVRqDi0okZVRgekNlWcgPdYP79738b7ai0oSZHBcpNq30REAEREAERqASBinvt7rPPPnbvvffaqaee6vOBfu1rX8uMcvT444/bI488YsxZOmrUKGmllXhCdE4REAEREIEGCVRckKJpnnnmme5sdPvtt3tXGGrMSDN0haHt9OKLL7a11167wQvRQREQAREQARGoBIGKC1LaPvfcc093KqKLC9Oq0WaKEF199dV9Mu2VVqrOqXMqccN0ThEQAREQgeoiUHFBCg60T4a42nTTTX3cXRyM5syZ4+2jtJMqiIAIiIAIiEC1Eqi4sxFj6/7+97+3Aw44wO6//35vB+3SpYvNnTvXrrnmGtdW7777bhe01QpR9RIBERABEei4BCouSJ955hm79dZbfYo0HI1iWHHFFe2UU07xPqSXXnqpe/bGY1qLgAiIgAiIQLUQqLgg/ec//2kbbbSRnXvuucbg9DEwdyda6hVXXOFa6tNPPy2tNMLRWgREQAREoGoIVFyQfvbZZ7bOOuv4mLq5VGg7xWt35MiRxqTftKMqiIAIiIAIiEA1Eai4IB06dKhNnTrVp07LBwbhOWnSJENDZU5PBREQAREQARGoJgIVF6R77LGHz0X68MMP1+OCEMXhCK11/fXXbzeTfNe7UEWIgAiIgAi0WQIV7/6y6667Gu2kv/zlL+3OO++0rbfe2md6nzlzpj3//PP2/vvvexx9TTH1KoiACIiACIhANRGouCDFO/ecc86xv/71r/bSSy/ZXXfd5YPUMyDD8OHD7fvf/74dddRRRjoFERABERABEag2AhUXpGiZOBudccYZhhZKv9La2lpvD6VdlHF24xyl1QZP9REBERABERCBigtSbkFdXZ175OJ4RGBko8mTJ/ugDIxsNGTIEGOQBgUREAEREAERqDYCFXc2YrJuZng5++yzfVhAAD3wwAP23e9+1/bdd1836952220FvXqrDajqIwIiIAIi0LEIVFyQvvfeez4Yw5gxY7wbzMSJE91Td8qUKbbffvvZCiusYH/84x/d8ahj3RpdrQiIgAiIQFsgUHFBylykffv29XF211prLRs3bpwhRPHmZWjAv/zlL276xRFJA9i3hUdKdRQBERCBjkWg4oL0rbfesm233dY9dHEyGj9+vHvtMuE3AY2UWWGmTZsm827HejZ1tSIgAiLQJghUXJDSRopXLvOSMuPL22+/7Y5FO+ywQwbg/PnzvQ+p+pFmkGhDBERABESgSghUXJCut9569u677/qE3h9++KG98cYbtssuu7gmumjRIhs7dqwvjLnbrVu3KsGmaoiACIiACIhAikDF+5Qww8vJJ59sp59+us2ePdvbQQ8//HBDU2VwBhyNBg0a5MJVY+3qsRUBERABEag2AhXXSLfYYgu74IILrHfv3j56EdOpbb/99s6J4QEZkOHyyy+3zTbbrNrYqT4iIAIiIAIiYBXXSBlogYHrWXLDz3/+czfn0n6qIAIiIAIiIALVSKDigrQhKD169GjosI6JgAiIgAiIQMUJSNWr+C1QBURABERABNoyAQnStnz3VHcREAEREIGKE5AgrfgtUAVEQAREQATaMgEJ0rZ891R3ERABERCBihOQIK34LVAFREAEREAE2jIBCdK2fPdUdxEQAREQgYoTkCCt+C1QBURABERABNoygaruR9qWwebWfd68eT7fam689kVABESgOQRmzZplLFOnTm1OMW0i75AhQ6qynhKkZbotL7/8srEoiIAIiIAINI3A6NGjm5axlXPV1IXQyufo8MV3hC/FDn+TBUAERKDVCVSrRipB2uq3XicQAREQARFozwTkbNSe766uTQREQAREoNUJSJC2OmKdQAREQAREoD0TkCBtz3dX1yYCIiACItDqBCRIWx2xTiACIiACItCeCUiQtue7q2sTAREQARFodQISpK2OWCcQAREQARFozwQkSNvz3dW1iYAIiIAItDoBjWyUB/HixYvtk08+sSVLlmQd7d27t6266qpWW1trH374Ydax5M4aa6xhPXv29CjGuxg7dqxNmzbNhg0bZiNHjrSamppkct9+7733bMKECdanTx/bcsstrVu3bllpli5dam+88YZNnDjRevXqZZtuuqkNHDgwK412REAEqptAJd4tEOGd9eSTT/p7Y/DgwVmQeEfxbvn8888z7x/eMQqlE9CADHlYvfvuu3b55Ze7IO3UabnSvtFGG9mxxx5rs2fPtnPPPdeWLVuWlXvhwoXGQ3nRRRfZWmutZdOnT7errrrKJk2a5MJvzpw5Hn/iiSda//79Pe/8+fPt5ptvtv/973/Wt29fowyE6cknn2yrrbaap0F4Xn311S6MEeYIeNJ973vfsx133NGSdcyqkHZEQASqikA53y3xwhGiTzzxhN1+++12xhln2CabbBIP2VdffWXXXnutvf/++9avXz9btGiRdenSxU466SRbd9118370ZzJrI0NAGmkGxfINtEceqOOOO85WWGGFzAEEXI8ePaxr164u6JKjK86dO9duu+02F5QMY4Wwe+SRR3wwaR5eNFke1uuuu84ee+wxO+CAA/whffrpp11jPeGEE2zjjTe2KVOm2PXXX28PPPCAHXPMMZ7mwQcftAULFtjPfvYzQ9tFIN9zzz1299132wYbbGC5X5iZCmtDBESgqgiU693SuXNnv27eFbxvHn74Yf/4TsJAEfjvf//r7yXePwjYGTNm2B//+Ed//xAnzTRJrPC2BGkeNjzsCMztttsur7bHF1vyq44H8oYbbvCSDj74YNcov/zyS3vttdds1KhRts466/gxzLo77bSTx++xxx7+5UcaBOhWW23lQnP11Vd3IXvjjTe65ovQxoy8884724YbbujlYDbee++97bnnnvMHX4I0z01UlAhUIYFyvVvQLhnj+5prrvHmID64edckA5rq5MmTbdCgQbb11lv7+4cP/u233941WD7eJUiTxApvL7dbFk7ToY7QhsEDiFmVNoPnn3/eXn31VRdYuabcCGbcuHH24osvunBDYyTwEPKQRuEX07L/xRdf+HHMszFNst2Uh5ljM2fOtAEDBtivfvUr22+//WIRvkYDpt20e/fuWfHaEQERqE4C5Xy3QIDzrbLKKnbeeefZbrvtZlFLjXRQCBCiCHeaj7DCocG+8847Hp/rpxHzaV2fgDTSHCY8TAhSHixMrGiEtHHSNnn44f9/e2eoE1kMheG+wwjCCLJiEsaO4gUIIQEMhqxAILBYDAgMBgVvMAZICCEkOBQWiSYIeJHdr5uS3m4nVN2dDd9JyM709naWL3fO355zWn7GQqA8J0mOk/AID+Ta2trnaAghod9UdJQuMFPkb5MigognglgWDfHAcx9hFowHPjdytDc3NzGHMRgM8ku+loAE5pRAn74FBMPhMOzv70c/g1iWhh8jQsaC4ezsLCwvL8ecKX1JK+VprfJe33cJdD1099q3fMeqk5kY4Y3Nzc0opAjfxcVFuL29DaPRKK4SExxymoRMKEIiHJyMHCkCmK80uYZIIrB8Dv8iqOXMj3u4FzEuDRElh/Hx8REoWiJvq0lAAvNPoE/fAo18wj+LDpN1dgvgh/A5+C3+SDiRMoory1XsrHG+e7tCWjwBrBgPDw87rVTT7u7uhpOTk1iJS7g12dPTU6C4iNlcbogjD2dekMT1FB5GLJNg8vDmNktgmSlOp9Pw+voaZ5qTySS/zdcSkMAcE+jTt7RgIBpG0SLRtuPj4880EQsGChlJQ5Fm0r4mYI60YITQkSdABHPjS8CMjVBuMgSQ3Oh4PP4rDMLqlBkhudLcyHvy4DIWP4RPKEHPjSIAPicP+bLPlMIBZpBsjVlZWclv8bUEJDDnBPr0LS0oiLS9v7+HjY2NTxHlPsK9+CYm7FobAYW04EQh0NHRUXh7e+tcQcAQxlzcCIkwq6PAiFxqbggpK9XyYWQfGQczcJ0fXtOWG/8HVrRp5csYhHMRZcK5hFw0CUjg/yLQp29pIZOiYkzcSysjaeV133cJKKRdHrHcm0IfinnYwsKsjeKjy8vLuOUliRu3Ud2GGC4uLhajhJi7RPAeHh5ivoFxyGs+Pj7G043IbVJaTp/n5+c4Fn0Q7Lu7u9iHVTAr0/v7+9i+t7cXZ4rkZclh8EMBgyYBCcw/Ab7vffmWFhpExjh0Af+CL8H/EDHj8AYiclzT2giYIy04IV7b29vh+vo6nJ6ehoWFhVi1y0qUQxTySjaqeVmJplOK8qFoX11djfcyDrkGhJT9XHkpOkVNHEd4fn4efvzeQ4po8xnr6+vxS0f18MvLSzzii8q60g4ODuKxX2W77yUggfki0Ldv+eq3R0i3trbC1dVVPI1taWkp7l2n2GhnZydG1L4aw+t/CHhEYOVJIJdB3hIRo0qWAw8IwVJ0RDgkGatH9moRwp1V3cb9jMN4jMPqNRdjxmLVSdiHWSErXsrW+dLxWeRhaZ9lbLspt9jM6mu7BCTwbwn07VvSb8sOAPwV2+WIoiUjhIuPIsrFD+LKHnr8EHlSrY2AQtrGyV4SkIAEJCCBKgFzpFUsNkpAAhKQgATaCCikbZzsJQEJSEACEqgSUEirWGyUgAQkIAEJtBFQSNs42UsCEpCABCRQJaCQVrHYKAEJSEACEmgjoJC2cbKXBCQgAQlIoEpAIa1isVECEpCABCTQRkAhbeNkLwlIQAISkECVgEJaxWKjBCQgAQlIoI2AQtrGyV4SkIAEJCCBKgGFtIrFRglIQAISkEAbgV/y/ntGTsHMyQAAAABJRU5ErkJggg==&quot;&gt;
&lt;p&gt;Performance improvement of spreading a holey array of integers (&lt;a href=&quot;https://v8.dev/blog/elements-kinds&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HOLEY_SMI_ELEMENTS&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;The filling of holes with &lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt; that our fast path has to perform is not as simple as it sounds: it may require converting the whole array to a different elements kind. The next graph measures such a situation. The setup is the same as above, except that this time the 600 array elements are unboxed doubles and the array has the &lt;code class=&quot;language-text&quot;&gt;HOLEY_DOUBLE_ELEMENTS&lt;/code&gt; elements kind. Since this elements kind cannot hold tagged values such as &lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;, spreading involves a costly elements kind transition, which is why the score for &lt;code class=&quot;language-text&quot;&gt;[...a]&lt;/code&gt; is much lower than in the previous graph. Nevertheless, it is still much faster than &lt;code class=&quot;language-text&quot;&gt;clone(a)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;对于在空洞中填入&lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;这件事情，并不如听起来的那么简单：可能会需要将整个数组转成一种不同的elements kind。下一张图表会展示这样的情况。初始设定和上面一致，除了这次600个数组元素是未装箱的双精度浮点型（unboxed doubles），此外这个数组拥有&lt;code class=&quot;language-text&quot;&gt;HOLEY_DOUBLE_ELEMENTS&lt;/code&gt; elements kind。因为这个数组的elements kind可以包含有标签的值，例如&lt;code class=&quot;language-text&quot;&gt;undefined&lt;/code&gt;，扩展运算就必须包含代价很大的elements kind转化，这导致了&lt;code class=&quot;language-text&quot;&gt;[...a]&lt;/code&gt;的分数比上一张图表中下降了那么多。尽管如此，它仍旧比&lt;code class=&quot;language-text&quot;&gt;clone(a)&lt;/code&gt;要快很多。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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&quot;&gt;
&lt;p&gt;Performance improvement of spreading a holey array of doubles (&lt;a href=&quot;https://v8.dev/blog/elements-kinds&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener noreferrer&quot;&gt;HOLEY_DOUBLE_ELEMENTS&lt;/a&gt;)&lt;/p&gt;
&lt;h2 id=&quot;spreading-strings-sets-and-maps&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#spreading-strings-sets-and-maps&quot; aria-label=&quot;spreading strings sets and maps permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Spreading strings, sets, and maps&lt;/h2&gt;
&lt;p&gt;The idea of skipping the iterator object and avoiding growing the result array equally applies to spreading other standard data types. Indeed, we implemented similar fast paths for primitive strings, for sets, and for maps, each time taking care to bypass them in the presence of modified iteration behavior.&lt;/p&gt;
&lt;p&gt;我们也有想法，跳过迭代对象，并避免其他数据类型的扩展运算导致的数组增长（这句话简直了）。确实，我们对原始字符串、sets、maps，也实现了类似的快速修正，并小心跳过迭代行为被改变的情况。&lt;/p&gt;
&lt;p&gt;Concerning sets, the fast path supports not only spreading a set directly (&lt;code class=&quot;language-text&quot;&gt;[...set]&lt;/code&gt;), but also spreading its keys iterator (&lt;code class=&quot;language-text&quot;&gt;[...set.keys()]&lt;/code&gt;) and its values iterator (&lt;code class=&quot;language-text&quot;&gt;[...set.values()]&lt;/code&gt;). In our micro-benchmarks, these operations are now about 18× faster than before.&lt;/p&gt;
&lt;p&gt;对sets来说，快速修正支持不仅仅直接扩展一个set（&lt;code class=&quot;language-text&quot;&gt;[...set]&lt;/code&gt;），也支持扩展它的键（&lt;code class=&quot;language-text&quot;&gt;[...set.keys()]&lt;/code&gt;）以及它的值（&lt;code class=&quot;language-text&quot;&gt;[...set.values()]&lt;/code&gt;）。在我们的微型benchmark中，这些操作现在比之前要快大约18x。&lt;/p&gt;
&lt;p&gt;The fast path for maps is similar but does not support spreading a map directly (&lt;code class=&quot;language-text&quot;&gt;[...map]&lt;/code&gt;), because we consider this an uncommon operation. For the same reason, neither fast path supports the &lt;code class=&quot;language-text&quot;&gt;entries()&lt;/code&gt; iterator. In our micro-benchmarks, these operations are now about 14× faster than before.&lt;/p&gt;
&lt;p&gt;对maps来说，情况比较类似，但不支持直接扩展一个map（&lt;code class=&quot;language-text&quot;&gt;[...map]&lt;/code&gt;），因为我们认为这样的操作比较罕见。同样的理由，快速修正也不支持&lt;code class=&quot;language-text&quot;&gt;entries()&lt;/code&gt;迭代。在我们的微型benchmark中，这些操作比之前要快大约x14。&lt;/p&gt;
&lt;p&gt;For spreading strings (&lt;code class=&quot;language-text&quot;&gt;[...string]&lt;/code&gt;), we measured a roughly 5× improvement, as shown in the graph below by the purple and green lines. Note that this is even faster than a TurboFan-optimized for-of-loop (TurboFan understands string iteration and can generate optimized code for it), represented by the blue and pink lines. The reason for having two plots in each case is that the micro-benchmarks operate on two different string representations (one-byte strings and two-byte strings).&lt;/p&gt;
&lt;p&gt;对字符串来说（&lt;code class=&quot;language-text&quot;&gt;[...string]&lt;/code&gt;），我们获得了大约5x的性能提升，请查看下图中紫色和绿色的线。请注意，这已经比经过TurboFan优化的for-of循环还要快了（TurboFan能理解字符串迭代，并为其创建经过优化的代码），请查看蓝色和粉色的线。为什么每个情况都会有两条线，是因为微型benchmark是在两种不同的字符串上进行测试的（one-byte strings and two-byte strings）。&lt;/p&gt;
&lt;img style=&quot;background-color: #FFFFFF;&quot; src=&quot;data:image/png;base64,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