<?xml version="1.0" encoding="utf-8" ?>


<feed xmlns="http://www.w3.org/2005/Atom">
  <title>IMLANE</title>

  <description></description>

  <link href="http://imlane.zhanglintc.co/"></link>

  <link ref="self" href="http://imlane.zhanglintc.co/feed"></link>

  <id></id>


  <updated>2025-05-07T15:20:00Z</updated>


  <entry>


    <title>古代汉语音韵学</title>

    <link href="http://imlane.zhanglintc.co/post/gu-dai-yi-yu-yin-yun-xue"  rel="alternate"></link>

    <updated>2025-05-07T15:20:00Z</updated>
    <id>post/gu-dai-yi-yu-yin-yun-xue</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;四声分类&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;平上去入&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;&lt;strong class="md_compiled md_compiled_strong"&gt;平&lt;/strong&gt;：平稳、不升不降的音调。现为阴平（一声）、阳平（二声）。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;&lt;strong class="md_compiled md_compiled_strong"&gt;上&lt;/strong&gt;：先降后升的音调。现为三声。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;&lt;strong class="md_compiled md_compiled_strong"&gt;去&lt;/strong&gt;：高到低的音调。现为四声。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;&lt;strong class="md_compiled md_compiled_strong"&gt;入&lt;/strong&gt;：以塞音（如-p、-t、-k）结尾的音节，发音短促。普通话中不存在，粤语等方言中存在。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;古代四声：平声、上声、去声、入声。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;现代四声：阴平（一声）、阳平（二声）、上声（三声）、去声（四声）。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_1" class="h16"&gt;&lt;span class="span_for_h"&gt;平仄的划分&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start"&gt;&lt;strong class="md_compiled md_compiled_strong"&gt;平声&lt;/strong&gt;：属于“平”，包括古代汉语的平声（现代汉语的阴平和阳平，即一声和二声）&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;&lt;strong class="md_compiled md_compiled_strong"&gt;仄声&lt;/strong&gt;：属于“仄”，包括古代汉语的上声、去声和入声（现代汉语的上声（三声）、去声（四声），以及部分方言中保留的入声）&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>K3s Node NotReady State</title>

    <link href="http://imlane.zhanglintc.co/post/k3s-node-notready-state"  rel="alternate"></link>

    <updated>2025-02-11T17:54:00Z</updated>
    <id>post/k3s-node-notready-state</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;master 上查看 node 状态，可见 &lt;code&gt;devops010012007114&lt;/code&gt; 状态为 &lt;code&gt;NotReady&lt;/code&gt;：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;app@devops010012007068 zhanglin&lt;span class="o"&gt;]&lt;/span&gt;&amp;lt;&lt;span class="m"&gt;20250120&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:26:35&amp;gt;$ k get nodes
NAME                 STATUS     ROLES    AGE      VERSION
devops010012007068   Ready      master   3y240d   v1.19.8+k3s1
devops010012007069   Ready      &amp;lt;none&amp;gt;   288d     v1.19.8+k3s1
devops010012007070   Ready      &amp;lt;none&amp;gt;   3y240d   v1.19.8+k3s1
devops010012007071   Ready      &amp;lt;none&amp;gt;   3y240d   v1.19.8+k3s1
devops010012007073   Ready      &amp;lt;none&amp;gt;   3y240d   v1.19.8+k3s1
devops010012007109   Ready      &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
devops010012007111   Ready      &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
devops010012007113   Ready      &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
devops010012007114   NotReady   &amp;lt;none&amp;gt;   207d     v1.19.8+k3s1
devops010012007116   Ready      &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;node &lt;code&gt;devops010012007114&lt;/code&gt; 上查看 k3s-agent 状态，有报错：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@localhost app&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# systemctl status k3s-agent -l&lt;/span&gt;
● k3s-agent.service - Lightweight Kubernetes
   Loaded: loaded &lt;span class="o"&gt;(&lt;/span&gt;/etc/systemd/system/k3s-agent.service&lt;span class="p"&gt;;&lt;/span&gt; enabled&lt;span class="p"&gt;;&lt;/span&gt; vendor preset: disabled&lt;span class="o"&gt;)&lt;/span&gt;
   Active: active &lt;span class="o"&gt;(&lt;/span&gt;running&lt;span class="o"&gt;)&lt;/span&gt; since Mon &lt;span class="m"&gt;2025&lt;/span&gt;-01-20 &lt;span class="m"&gt;12&lt;/span&gt;:20:21 CST&lt;span class="p"&gt;;&lt;/span&gt; 2h 8min ago
     Docs: https://k3s.io
  Process: &lt;span class="m"&gt;9197&lt;/span&gt; &lt;span class="nv"&gt;ExecStartPre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/sbin/modprobe overlay &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;exited, &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;/SUCCESS&lt;span class="o"&gt;)&lt;/span&gt;
  Process: &lt;span class="m"&gt;9167&lt;/span&gt; &lt;span class="nv"&gt;ExecStartPre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/sbin/modprobe br_netfilter &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;exited, &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;/SUCCESS&lt;span class="o"&gt;)&lt;/span&gt;
  Process: &lt;span class="m"&gt;9148&lt;/span&gt; &lt;span class="nv"&gt;ExecStartPre&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/bin/sh -xc ! /usr/bin/systemctl is-enabled --quiet nm-cloud-setup.service &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;exited, &lt;span class="nv"&gt;status&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;/SUCCESS&lt;span class="o"&gt;)&lt;/span&gt;
 Main PID: &lt;span class="m"&gt;9209&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;k3s-agent&lt;span class="o"&gt;)&lt;/span&gt;
    Tasks: &lt;span class="m"&gt;10&lt;/span&gt;
   Memory: &lt;span class="m"&gt;122&lt;/span&gt;.8M
   CGroup: /system.slice/k3s-agent.service
           └─9209 /usr/local/bin/k3s agent

Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:27:55 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:27:55.207578649+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:00 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:00.220559879+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:05 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:05.233453150+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:10 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:10.246519473+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:15 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:15.259321936+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:20 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:20.272576559+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:25 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:25.285244932+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:30 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:30.297600069+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:35 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:35.313884545+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:40 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:40.326131507+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;使用 &lt;code&gt;journalctl&lt;/code&gt; 也可查看 log：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@localhost app&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# journalctl -u k3s-agent -f&lt;/span&gt;
-- Logs begin at Mon &lt;span class="m"&gt;2025&lt;/span&gt;-01-20 &lt;span class="m"&gt;12&lt;/span&gt;:20:12 CST. --
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:10 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:10.246519473+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:15 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:15.259321936+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:20 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:20.272576559+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:25 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:25.285244932+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:30 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:30.297600069+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:35 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:35.313884545+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:40 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:40.326131507+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:45 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:45.339057664+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:50 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:50.352345609+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:28:55 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:28:55.364271075+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
Jan &lt;span class="m"&gt;20&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:29:00 localhost.localdomain k3s&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;9209&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;: &lt;span class="nv"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2025-01-20T14:29:00.377075556+08:00&amp;quot;&lt;/span&gt; &lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;error &lt;span class="nv"&gt;msg&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &amp;#39;/etc/rancher/node/password&amp;#39; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;其中的报错：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Failed to retrieve agent config: Node password rejected, duplicate hostname or contents of &lt;span class="s1"&gt;&amp;#39;/etc/rancher/node/password&amp;#39;&lt;/span&gt; may not match server node-passwd entry, try enabling a unique node name with the --with-node-id flag
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;曾把我引入歧途，我一直以为是密码错误，或者是缺乏 &lt;code&gt;--with-node-id flag&lt;/code&gt;。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;但是注意到 &lt;code&gt;or contents of '/etc/rancher/node/password' may not match server node-passwd entry&lt;/code&gt;，且发现 &lt;code&gt;[root@localhost app]#&lt;/code&gt; hostname 是 &lt;code&gt;localhost&lt;/code&gt;，&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;联想到服务器曾重启，hostname 好像被恢复成了默认，似乎重置 hostname 可能有用。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;于是尝试：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@localhost app&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# hostname devops010012007114&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;重启后：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;root@devops010012007114 app&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="c1"&gt;# &lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;此时注意到 hostname 已变为 &lt;code&gt;devops010012007114&lt;/code&gt;。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;然后回到 master 上查看状态，果然恢复了：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;app@devops010012007068 zhanglin&lt;span class="o"&gt;]&lt;/span&gt;&amp;lt;&lt;span class="m"&gt;20250120&lt;/span&gt; &lt;span class="m"&gt;14&lt;/span&gt;:29:36&amp;gt;$ k get nodes
NAME                 STATUS   ROLES    AGE      VERSION
devops010012007068   Ready    master   3y240d   v1.19.8+k3s1
devops010012007069   Ready    &amp;lt;none&amp;gt;   288d     v1.19.8+k3s1
devops010012007070   Ready    &amp;lt;none&amp;gt;   3y240d   v1.19.8+k3s1
devops010012007071   Ready    &amp;lt;none&amp;gt;   3y240d   v1.19.8+k3s1
devops010012007073   Ready    &amp;lt;none&amp;gt;   3y240d   v1.19.8+k3s1
devops010012007109   Ready    &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
devops010012007111   Ready    &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
devops010012007113   Ready    &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
devops010012007114   Ready    &amp;lt;none&amp;gt;   207d     v1.19.8+k3s1
devops010012007116   Ready    &amp;lt;none&amp;gt;   542d     v1.19.8+k3s1
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;</summary>

  </entry>


  <entry>


    <title>TDengine 笔记</title>

    <link href="http://imlane.zhanglintc.co/unfinished/tdenginebi-ji"  rel="alternate"></link>

    <updated>2024-06-14T14:47:00Z</updated>
    <id>unfinished/tdenginebi-ji</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;基本概念&lt;/span&gt;&lt;/h2&gt;
&lt;h4 id="toc_1" class="h16"&gt;&lt;span class="span_for_h"&gt;表（Table）&lt;/span&gt;&lt;/h4&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;为充分利用其数据的时序性和其他数据特点，TDengine 采取&lt;strong&gt;一个数据采集点一张表&lt;/strong&gt;的策略，要求对每个数据采集点单独建表（比如有一千万个智能电表，就需创建一千万张表），用来存储这个数据采集点所采集的时序数据。&lt;/span&gt;
&lt;/p&gt;

&lt;h4 id="toc_2" class="h16"&gt;&lt;span class="span_for_h"&gt;超级表（STable）&lt;/span&gt;&lt;/h4&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;超级表是指某一特定类型的数据采集点的集合。同一类型的数据采集点，其表的结构是完全一样的，但每个表（数据采集点）的静态属性（TAG）是不一样的&lt;/span&gt;
&lt;/p&gt;

&lt;h4 id="toc_3" class="h16"&gt;&lt;span class="span_for_h"&gt;子表（Subtable）&lt;/span&gt;&lt;/h4&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;当为某个具体数据采集点创建表时，用户可以使用超级表的定义做模板，同时指定该具体采集点（表）的具体标签值（TAG）来创建该表。&lt;strong&gt;通过超级表创建的表称之为子表&lt;/strong&gt;。&lt;/span&gt;
&lt;/p&gt;

&lt;h4 id="toc_4" class="h16"&gt;&lt;span class="span_for_h"&gt;标签（Tag）&lt;/span&gt;&lt;/h4&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;标签是指传感器、设备或其他类型采集点的静态属性，不是随时间变化的，比如设备型号、颜色、设备的所在地等，数据类型可以是任何类型。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;TAG 是一个很特殊的数据列：&lt;/span&gt;
&lt;/p&gt;

&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;属于静态数据，创建后无需更新及插入。

&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;同一张子表里每一行数据都应具有相同的 TAG 值。

&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;TAG 值在做 &lt;code&gt;group by&lt;/code&gt; 或者 &lt;code&gt;partition by&lt;/code&gt; 的时候可以带来极高的性能。

&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;因为不同 TAG 组合的表在物理上存储在不同的连续地址上，相当于提前 &lt;code&gt;group by&lt;/code&gt; 完成了，&lt;strong&gt;空间换时间&lt;/strong&gt;。

&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;比如 &lt;code&gt;group by&lt;/code&gt; 配合 &lt;code&gt;last_row&lt;/code&gt; 的时候，如果是 &lt;code&gt;group by&lt;/code&gt; 的是 TAG 列，则可以直接去每张表中取最后一行，效率极高。

&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;否则如果 &lt;code&gt;group by&lt;/code&gt; 的是普通数据列，则需要遍历全表，性能非常差。

&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;一张&lt;strong&gt;子表&lt;/strong&gt;里同一个 TAG 列的值是一样的，无法在一张子表某个 TAG 列里存入不同的值。所以通过&lt;strong&gt;超级表&lt;/strong&gt;创建的&lt;strong&gt;子表&lt;/strong&gt;的数量，应该等于&lt;strong&gt;超级表&lt;/strong&gt;每个 TAG 列里值的数量的乘积。比如，假设&lt;strong&gt;超级表&lt;/strong&gt;有 &lt;code&gt;TAG_1&lt;/code&gt;，&lt;code&gt;TAG_2&lt;/code&gt; 两个 TAG 列，&lt;code&gt;TAG_1&lt;/code&gt; 有 &lt;code&gt;2&lt;/code&gt; 个值，&lt;code&gt;TAG_2&lt;/code&gt; 有 &lt;code&gt;3&lt;/code&gt; 个值，那么创建的&lt;strong&gt;子表&lt;/strong&gt;数量就应该等于 &lt;code&gt;2 &amp;#42; 3 = 6&lt;/code&gt; 张子表。不同的 TAG 值组合必须对应不同的&lt;strong&gt;子表&lt;/strong&gt;，但是子表的名字本身跟 TAG 没有强关联性。&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_mysql  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;-- 先切换到指定database，否则show命令会报错(感觉像TDengine的bug)&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="n"&gt;dispatcher_data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- 描述子表，可见有两个TAG列(type, enterprise_id)&lt;/span&gt;
&lt;span class="k"&gt;describe&lt;/span&gt; &lt;span class="n"&gt;tag_two_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;-------------+---------+------+----+&lt;/span&gt;
&lt;span class="n"&gt;field&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;note&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-------------+---------+------+----+&lt;/span&gt;
&lt;span class="n"&gt;ts&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kt"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;timestr&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kt"&gt;VARCHAR&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;count&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kt"&gt;INT&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kt"&gt;INT&lt;/span&gt;      &lt;span class="o"&gt;|&lt;/span&gt;     &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;TAG&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;enterprise_id&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kt"&gt;VARCHAR&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;TAG&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-------------+---------+------+----+&lt;/span&gt;

&lt;span class="c1"&gt;-- 查看子表的TAG详细信息&lt;/span&gt;
&lt;span class="c1"&gt;-- 可见TAG值(type, enterprise_id)已经作为meta信息存入了，实际上每张子表的TAG信息必须是一致且不可变的&lt;/span&gt;
&lt;span class="c1"&gt;-- 此时即使我设置不同的TAG值尝试插入，也只有普通数据插入成功，后来设置TAG的值实际上是未使用的&lt;/span&gt;
&lt;span class="k"&gt;show&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tag_two_1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;----------+---------------+------------------------+-------------+-----------+----------+&lt;/span&gt;
&lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;db_name&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;stable_name&lt;/span&gt;             &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tag_name&lt;/span&gt;     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tag_type&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tag_value&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;----------+---------------+------------------------+-------------+-----------+----------+&lt;/span&gt;
&lt;span class="n"&gt;tag_two_1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dispatcher_data&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t_realtime_count_tag_two&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kt"&gt;INT&lt;/span&gt;        &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;         &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="n"&gt;tag_two_1&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;dispatcher_data&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t_realtime_count_tag_two&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;enterprise_id&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="kt"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Kf5ZyXsPU&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;----------+---------------+------------------------+-------------+-----------+----------+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_mysql  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;-- 查看超级表，可见TAG值(type, enterprise_id)&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;t_realtime_count_tag_two&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;-----------------------+-------+-----+----+-------------+&lt;/span&gt;
&lt;span class="n"&gt;ts&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;timestr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;enterprise_id&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-----------------------+-------+-----+----+-------------+&lt;/span&gt;
&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;06&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt; &lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;03&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;Kf5ZyXsPU&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-----------------------+-------+-----+----+-------------+&lt;/span&gt;

&lt;span class="c1"&gt;-- 查看子表信息，看不到TAG值(因为反正本表内TAG值一样，无需显示)&lt;/span&gt;
&lt;span class="c1"&gt;-- 只能看到普通数据的值&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;tag_two_1&lt;/span&gt; &lt;span class="k"&gt;limit&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;-----------------------+-------+-----+&lt;/span&gt;
&lt;span class="n"&gt;ts&lt;/span&gt;                     &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;timestr&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-----------------------+-------+-----+&lt;/span&gt;
&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;06&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;09&lt;/span&gt; &lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;03&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;       &lt;span class="o"&gt;|&lt;/span&gt;    &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;-----------------------+-------+-----+&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;span class="md_repeated_n md_repeated_n_1"&gt;&lt;/span&gt;&lt;h2 id="toc_5" class="h16"&gt;&lt;span class="span_for_h"&gt;基本操作&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_mysql  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;-- 创建数据库&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="k"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="ss"&gt;`dispatcher_data`&lt;/span&gt;
    &lt;span class="n"&gt;SINGLE_STABLE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;  &lt;span class="c1"&gt;-- 允许创建多张超级表&lt;/span&gt;
    &lt;span class="k"&gt;PRECISION&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;us&amp;#39;&lt;/span&gt;  &lt;span class="c1"&gt;-- 时间戳精度微秒&lt;/span&gt;
    &lt;span class="n"&gt;DURATION&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;
    &lt;span class="n"&gt;KEEP&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt;
    &lt;span class="c1"&gt;-- 其他的使用默认值&lt;/span&gt;
&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- 查看数据库建表语句&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="ss"&gt;`dispatcher_data`&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- 创建超级表&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;STABLE&lt;/span&gt; &lt;span class="ss"&gt;`dispatcher_data`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;`t_top_info`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="kt"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="ss"&gt;`content`&lt;/span&gt; &lt;span class="kt"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nf"&gt;TAGS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="ss"&gt;`type`&lt;/span&gt; &lt;span class="kt"&gt;INT&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- 插入数据(`USING`语法)&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="ss"&gt;`dispatcher_data`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;`t_top_info_1`&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="ss"&gt;`dispatcher_data`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;`t_top_info`&lt;/span&gt;
    &lt;span class="nf"&gt;TAGS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;some content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;-- 插入数据(一般语法)&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="ss"&gt;`dispatcher_data`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="ss"&gt;`t_top_info`&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;tbname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;-- 子表名称，此项为必须&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;type&lt;/span&gt;  &lt;span class="c1"&gt;-- TAG&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;t_top_info_1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;some content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;</summary>

  </entry>


  <entry>


    <title>git merge/rebase 用法</title>

    <link href="http://imlane.zhanglintc.co/unfinished/git-maerge-rebaseyong-fa"  rel="alternate"></link>

    <updated>2024-06-13T11:47:00Z</updated>
    <id>unfinished/git-maerge-rebaseyong-fa</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;开个坑&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>docker 笔记</title>

    <link href="http://imlane.zhanglintc.co/post/dockerbi-ji"  rel="alternate"></link>

    <updated>2024-06-13T00:02:00Z</updated>
    <id>post/dockerbi-ji</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;官方一键安装脚本&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 默认安装&lt;/span&gt;
curl -fsSL https://get.docker.com &lt;span class="p"&gt;|&lt;/span&gt; bash -s docker

&lt;span class="c1"&gt;# 带镜像站安装&lt;/span&gt;
curl -fsSL https://get.docker.com &lt;span class="p"&gt;|&lt;/span&gt; bash -s docker --mirror Aliyun

&lt;span class="c1"&gt;# `bash -s docker`这里的docker个人感觉是不需要的&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;span class="md_repeated_n md_repeated_n_1"&gt;&lt;/span&gt;&lt;h2 id="toc_1" class="h16"&gt;&lt;span class="span_for_h"&gt;添加代理或者镜像&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;本来添加&lt;strong&gt;代理&lt;/strong&gt;或者&lt;strong&gt;镜像&lt;/strong&gt;二选其一即可，但是实际发现&lt;strong&gt;代理&lt;/strong&gt;非常的稳定有效，&lt;strong&gt;镜像&lt;/strong&gt;目前不稳定有效，有些镜像可能获取不到或者有其他问题。&lt;/span&gt;
&lt;/p&gt;


&lt;hr&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;可以通过修改&lt;code&gt;daemon.json&lt;/code&gt;(不存在可新建)文件来实现&lt;strong&gt;代理&lt;/strong&gt;或者&lt;strong&gt;镜像&lt;/strong&gt;。&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Linux, regular setup&lt;/span&gt;
sudo vim /etc/docker/daemon.json

&lt;span class="c1"&gt;# Linux, rootless mode&lt;/span&gt;
vim ~/.config/docker/daemon.json

&lt;span class="c1"&gt;# Windows&lt;/span&gt;
C:&lt;span class="se"&gt;\P&lt;/span&gt;rogramData&lt;span class="se"&gt;\d&lt;/span&gt;ocker&lt;span class="se"&gt;\c&lt;/span&gt;onfig&lt;span class="se"&gt;\d&lt;/span&gt;aemon.json
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;参考：&lt;/span&gt;
&lt;/p&gt;

&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;&lt;a class="md_compiled" href="https://docs.docker.com/config/daemon/#configure-the-docker-daemon"&gt;Docker daemon configuration overview&lt;/a&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;添加内容如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  // 代理是有效的
  &lt;span class="s2"&gt;&amp;quot;proxies&amp;quot;&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;http-proxy&amp;quot;&lt;/span&gt;: &lt;span class="s2"&gt;&amp;quot;http://proxy.example.com:3128&amp;quot;&lt;/span&gt;,
    &lt;span class="s2"&gt;&amp;quot;https-proxy&amp;quot;&lt;/span&gt;: &lt;span class="s2"&gt;&amp;quot;https://proxy.example.com:3129&amp;quot;&lt;/span&gt;,
    &lt;span class="s2"&gt;&amp;quot;no-proxy&amp;quot;&lt;/span&gt;: &lt;span class="s2"&gt;&amp;quot;*.test.example.com,.example.org,127.0.0.0/8&amp;quot;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  // 登录阿里云控制台“容器镜像服务”后获取，这个不稳定有效
  &lt;span class="s2"&gt;&amp;quot;registry-mirrors&amp;quot;&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;https://xxx.mirror.aliyuncs.com&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;参考：&lt;/span&gt;
&lt;/p&gt;

&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;&lt;a class="md_compiled" href="https://docs.docker.com/config/daemon/systemd/#httphttps-proxy"&gt;Configure the daemon with systemd&lt;/a&gt;

&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;&lt;a class="md_compiled" href="https://cr.console.aliyun.com/"&gt;阿里云容器镜像服务&lt;/a&gt;

&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr&gt;

&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;最后重启docker服务：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 重启&lt;/span&gt;
sudo systemctl daemon-reload
sudo systemctl restart docker

&lt;span class="c1"&gt;# 查看相应信息&lt;/span&gt;
sudo docker info
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;hr&gt;

&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;也可以通过&lt;code&gt;http-proxy.conf&lt;/code&gt;文件来实现proxy&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 创建文件&lt;/span&gt;
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf

&lt;span class="c1"&gt;# 写入内容&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;Service&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="nv"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;HTTP_PROXY=http://proxy.example.com:3128&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;HTTPS_PROXY=https://proxy.example.com:3129&amp;quot;&lt;/span&gt;
&lt;span class="nv"&gt;Environment&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;NO_PROXY=localhost,127.0.0.1,docker-registry.example.com,.corp&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 验证&lt;/span&gt;
sudo systemctl show --property&lt;span class="o"&gt;=&lt;/span&gt;Environment docker
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;同样参考：&lt;/span&gt;
&lt;/p&gt;

&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;&lt;a class="md_compiled" href="https://docs.docker.com/config/daemon/systemd/#httphttps-proxy"&gt;Docker daemon configuration overview&lt;/a&gt;
&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;</summary>

  </entry>


  <entry>


    <title>@RestController作用于接口和类的区别</title>

    <link href="http://imlane.zhanglintc.co/post/restcontrollerzuo-yong-yu-jie-kou-he-lei-de-qu-bie"  rel="alternate"></link>

    <updated>2024-05-08T11:20:00Z</updated>
    <id>post/restcontrollerzuo-yong-yu-jie-kou-he-lei-de-qu-bie</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;前言&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;最近发现 &lt;code&gt;@RestController&lt;/code&gt; 作用于&lt;strong&gt;类&lt;/strong&gt;上可以正常运行，作用于&lt;strong&gt;接口&lt;/strong&gt;上无法正常运行，于是进行了一番探究。&lt;/span&gt;
&lt;/p&gt;

&lt;span class="md_repeated_n md_repeated_n_2"&gt;&lt;/span&gt;&lt;h2 id="toc_1" class="h16"&gt;&lt;span class="span_for_h"&gt;探究&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;直接进行源码探究。查看 &lt;code&gt;@RestConroller&lt;/code&gt; 注解，可见其本质就是 &lt;code&gt;@Controller&lt;/code&gt;，而 &lt;code&gt;@Controller&lt;/code&gt; 注解的本质其实又是 &lt;code&gt;@Component&lt;/code&gt;，所以这里的本质其实就是 &lt;code&gt;@Component&lt;/code&gt; 作用于接口为什么不能生效。&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Controller&lt;/span&gt;  &lt;span class="c1"&gt;// 注意&lt;/span&gt;
&lt;span class="nd"&gt;@ResponseBody&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="n"&gt;RestController&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="o"&gt;---------&lt;/span&gt;

&lt;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;  &lt;span class="c1"&gt;// 注意&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="o"&gt;---------&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Indicates that an annotated class is a &amp;quot;component&amp;quot;.&lt;/span&gt;
&lt;span class="cm"&gt; * Such classes are considered as candidates for auto-detection&lt;/span&gt;
&lt;span class="cm"&gt; * when using annotation-based configuration and classpath scanning.&lt;/span&gt;
&lt;span class="cm"&gt; *&lt;/span&gt;
&lt;span class="cm"&gt; * &amp;lt;p&amp;gt;Other class-level annotations may be considered as identifying&lt;/span&gt;
&lt;span class="cm"&gt; * a component as well, typically a special kind of component:&lt;/span&gt;
&lt;span class="cm"&gt; * e.g. the {@link Repository @Repository} annotation or AspectJ&amp;#39;s&lt;/span&gt;
&lt;span class="cm"&gt; * {@link org.aspectj.lang.annotation.Aspect @Aspect} annotation.&lt;/span&gt;
&lt;span class="cm"&gt; *&lt;/span&gt;
&lt;span class="cm"&gt; * @author Mark Fisher&lt;/span&gt;
&lt;span class="cm"&gt; * @since 2.5&lt;/span&gt;
&lt;span class="cm"&gt; * @see Repository&lt;/span&gt;
&lt;span class="cm"&gt; * @see Service&lt;/span&gt;
&lt;span class="cm"&gt; * @see Controller&lt;/span&gt;
&lt;span class="cm"&gt; * @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner  // 注意&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="nd"&gt;@Target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ElementType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TYPE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Retention&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RetentionPolicy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RUNTIME&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Documented&lt;/span&gt;
&lt;span class="nd"&gt;@Indexed&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nd"&gt;@interface&lt;/span&gt; &lt;span class="n"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;然后注意到 &lt;code&gt;@Component&lt;/code&gt; 注解上方注释中提到了 &lt;code&gt;ClassPathBeanDefinitionScanner&lt;/code&gt; 类，于是前去查看，并且其中有一个比较重要的方法 &lt;code&gt;doScan&lt;/code&gt;：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeanDefinitionHolder&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;doScan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;basePackages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;notEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basePackages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;At least one base package must be specified&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeanDefinitionHolder&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;beanDefinitions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;LinkedHashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;basePackage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;basePackages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 注意findCandidateComponents&lt;/span&gt;
        &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeanDefinition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;findCandidateComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basePackage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BeanDefinition&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;ScopeMetadata&lt;/span&gt; &lt;span class="n"&gt;scopeMetadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;scopeMetadataResolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;resolveScopeMetadata&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setScope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scopeMetadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getScopeName&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
            &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;beanName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;beanNameGenerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;generateBeanName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;AbstractBeanDefinition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;postProcessBeanDefinition&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;AbstractBeanDefinition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;beanName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;AnnotatedBeanDefinition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;AnnotationConfigUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;processCommonDefinitionAnnotations&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;AnnotatedBeanDefinition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;checkCandidate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;beanName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;BeanDefinitionHolder&lt;/span&gt; &lt;span class="n"&gt;definitionHolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BeanDefinitionHolder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;beanName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;definitionHolder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
                        &lt;span class="n"&gt;AnnotationConfigUtils&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;applyScopedProxyMode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;scopeMetadata&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;definitionHolder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;beanDefinitions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definitionHolder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;registerBeanDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;definitionHolder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;beanDefinitions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;通过调试可以发现是否被加载到 Spring 中是在 &lt;code&gt;findCandidateComponents&lt;/code&gt; 方法中进行的，继续查看：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeanDefinition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;findCandidateComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;basePackage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;componentsIndex&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;indexSupportsIncludeFilters&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;addCandidateComponentsFromIndex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;componentsIndex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;basePackage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 注意这里&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;scanCandidateComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basePackage&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;此处继续进入 &lt;code&gt;scanCandidateComponents&lt;/code&gt;：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeanDefinition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;scanCandidateComponents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;basePackage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BeanDefinition&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;LinkedHashSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;packageSearchPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ResourcePatternResolver&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CLASSPATH_ALL_URL_PREFIX&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;
                &lt;span class="n"&gt;resolveBasePackage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;basePackage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sc"&gt;&amp;#39;/&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;resourcePattern&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Resource&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getResourcePatternResolver&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getResources&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;packageSearchPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;traceEnabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isTraceEnabled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;debugEnabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isDebugEnabled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Resource&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;traceEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Scanning &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isReadable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;MetadataReader&lt;/span&gt; &lt;span class="n"&gt;metadataReader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getMetadataReaderFactory&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getMetadataReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isCandidateComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadataReader&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;ScannedGenericBeanDefinition&lt;/span&gt; &lt;span class="n"&gt;sbd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ScannedGenericBeanDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadataReader&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="n"&gt;sbd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setSource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="c1"&gt;// 注意isCandidateComponent&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isCandidateComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sbd&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debugEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Identified candidate component class: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                            &lt;span class="p"&gt;}&lt;/span&gt;
                            &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sbd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;debugEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ignored because not a concrete top-level class: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                            &lt;span class="p"&gt;}&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;traceEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                            &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ignored because not matching any filter: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                        &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BeanDefinitionStoreException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                            &lt;span class="s"&gt;&amp;quot;Failed to read candidate component class: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;traceEnabled&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ignored because not readable: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BeanDefinitionStoreException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;I/O failure during classpath scanning&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;继续调试发现 &lt;code&gt;isCandidateComponent&lt;/code&gt; 里作用于&lt;strong&gt;接口 =&amp;gt; false&lt;/strong&gt;和&lt;strong&gt;类 =&amp;gt; true&lt;/strong&gt;的返回值是不同的，于是继续进入：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isCandidateComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AnnotatedBeanDefinition&lt;/span&gt; &lt;span class="n"&gt;beanDefinition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;AnnotationMetadata&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;beanDefinition&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMetadata&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// 注意metadata.isConcrete()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isIndependent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isConcrete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isAbstract&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;hasAnnotatedMethods&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Lookup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()))));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;然后此处有一个 &lt;code&gt;metadata.isConcrete()&lt;/code&gt; 方法，进入查看：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isConcrete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isInterface&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;isAbstract&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;此处显然可见，如果被注释的对象是&lt;strong&gt;接口&lt;/strong&gt;或者&lt;strong&gt;抽象类&lt;/strong&gt;，将返回 &lt;code&gt;false&lt;/code&gt;，而如果是 &lt;code&gt;false&lt;/code&gt; 的话，将不会被当做 &lt;strong class="md_compiled md_compiled_strong"&gt;Candidate&lt;/strong&gt;，所以最终将不会被 Spring 载入使用 。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


  <entry>


    <title>Kafka 笔记</title>

    <link href="http://imlane.zhanglintc.co/unfinished/kafkabi-ji"  rel="alternate"></link>

    <updated>2024-02-02T23:20:00Z</updated>
    <id>unfinished/kafkabi-ji</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;配置&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start"&gt;向一个 3 台 机器的 Kafka 集群中创建 1 万个 topic，然后分别观察 &lt;code&gt;/home/vagrant/kafka/kafka-logs&lt;/code&gt; 目录中的实际数据，&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;可见数据基本是均分的：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 192.168.33.10&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Kafka-1 kafka-logs&lt;span class="o"&gt;]&lt;/span&gt;$ &lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/vagrant/kafka/kafka-logs
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Kafka-1 kafka-logs&lt;span class="o"&gt;]&lt;/span&gt;$ ll &lt;span class="p"&gt;|&lt;/span&gt; grep topic &lt;span class="p"&gt;|&lt;/span&gt; wc -l
&lt;span class="m"&gt;3344&lt;/span&gt;

&lt;span class="c1"&gt;# 192.168.33.11&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Kafka-2 kafka-logs&lt;span class="o"&gt;]&lt;/span&gt;$ &lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/vagrant/kafka/kafka-logs
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Kafka-2 kafka-logs&lt;span class="o"&gt;]&lt;/span&gt;$ ll &lt;span class="p"&gt;|&lt;/span&gt; grep topic &lt;span class="p"&gt;|&lt;/span&gt; wc -l
&lt;span class="m"&gt;3353&lt;/span&gt;

&lt;span class="c1"&gt;# 192.168.33.12&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Kafka-3 kafka-logs&lt;span class="o"&gt;]&lt;/span&gt;$ &lt;span class="nb"&gt;pwd&lt;/span&gt;
/home/vagrant/kafka/kafka-logs
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Kafka-3 kafka-logs&lt;span class="o"&gt;]&lt;/span&gt;$ ll &lt;span class="p"&gt;|&lt;/span&gt; grep topic &lt;span class="p"&gt;|&lt;/span&gt; wc -l
&lt;span class="m"&gt;3303&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;</summary>

  </entry>


  <entry>


    <title>Redis AOF 文件探究</title>

    <link href="http://imlane.zhanglintc.co/post/redis-aofwen-jian-tan-jiu"  rel="alternate"></link>

    <updated>2024-01-31T20:20:00Z</updated>
    <id>post/redis-aofwen-jian-tan-jiu</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;配置&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;编辑 redis.conf 文件：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 启用 AOF 持久化模式&lt;/span&gt;
appendonly yes

&lt;span class="c1"&gt;# 各种 redis 操作的工作目录&lt;/span&gt;
dir /home/vagrant/redis-home

&lt;span class="c1"&gt;# AOF 文件存放的文件夹名&lt;/span&gt;
appenddirname &lt;span class="s2"&gt;&amp;quot;appendonlydir&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# AOF 基准名称&lt;/span&gt;
&lt;span class="c1"&gt;# 结合上面的配置，文件将存放在于：&lt;/span&gt;
&lt;span class="c1"&gt;# /home/vagrant/redis-home/appendonlydir&lt;/span&gt;
&lt;span class="c1"&gt;#  - /home/vagrant/redis-home/appendonlydir/appendonly.aof.1.base.rdb&lt;/span&gt;
&lt;span class="c1"&gt;#  - /home/vagrant/redis-home/appendonlydir/appendonly.aof.1.incr.aof&lt;/span&gt;
&lt;span class="c1"&gt;#  - /home/vagrant/redis-home/appendonlydir/appendonly.aof.manifest&lt;/span&gt;
appendfilename &lt;span class="s2"&gt;&amp;quot;appendonly.aof&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# 写入频率，通常推荐 everysec&lt;/span&gt;
appendfsync everysec
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_1" class="h16"&gt;&lt;span class="span_for_h"&gt;文件分析&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# appendonly.aof.manifest 是清单文件&lt;/span&gt;
&lt;span class="c1"&gt;# 会记载哪个是 rdb 类型的文件，哪个是 aof 类型的文件&lt;/span&gt;
&lt;span class="c1"&gt;# type b 即 .base.rdb&lt;/span&gt;
&lt;span class="c1"&gt;# type i 即 .incr.aof&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Redis-1 appendonlydir&lt;span class="o"&gt;]&lt;/span&gt;$ cat appendonly.aof.manifest
file appendonly.aof.1.base.rdb seq &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; b
file appendonly.aof.1.incr.aof seq &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt; i
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# appendonly.aof.1.base.rdb 是快照文件&lt;/span&gt;
&lt;span class="c1"&gt;# 在 aof 文件过大的时候，redis 会自动把过旧的数据合并构建成一个 rdb 类型的快照文件&lt;/span&gt;
&lt;span class="c1"&gt;# 让后再在 aof 文件中记载增量变化，这样可以缩小 aof 文件大小&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Redis-1 appendonlydir&lt;span class="o"&gt;]&lt;/span&gt;$ cat appendonly.aof.1.base.rdb &lt;span class="p"&gt;|&lt;/span&gt; hexdump -C
&lt;span class="m"&gt;00000000&lt;/span&gt;  &lt;span class="m"&gt;52&lt;/span&gt; &lt;span class="m"&gt;45&lt;/span&gt; &lt;span class="m"&gt;44&lt;/span&gt; &lt;span class="m"&gt;49&lt;/span&gt; &lt;span class="m"&gt;53&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="m"&gt;31&lt;/span&gt;  &lt;span class="m"&gt;31&lt;/span&gt; fa &lt;span class="m"&gt;09&lt;/span&gt; &lt;span class="m"&gt;72&lt;/span&gt; &lt;span class="m"&gt;65&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt; &lt;span class="m"&gt;69&lt;/span&gt; &lt;span class="m"&gt;73&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt;REDIS0011..redis&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="m"&gt;00000010&lt;/span&gt;  2d &lt;span class="m"&gt;76&lt;/span&gt; &lt;span class="m"&gt;65&lt;/span&gt; &lt;span class="m"&gt;72&lt;/span&gt; &lt;span class="m"&gt;05&lt;/span&gt; &lt;span class="m"&gt;37&lt;/span&gt; 2e &lt;span class="m"&gt;32&lt;/span&gt;  2e &lt;span class="m"&gt;34&lt;/span&gt; fa 0a &lt;span class="m"&gt;72&lt;/span&gt; &lt;span class="m"&gt;65&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt; &lt;span class="m"&gt;69&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt;-ver.7.2.4..redi&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="m"&gt;00000020&lt;/span&gt;  &lt;span class="m"&gt;73&lt;/span&gt; 2d &lt;span class="m"&gt;62&lt;/span&gt; &lt;span class="m"&gt;69&lt;/span&gt; &lt;span class="m"&gt;74&lt;/span&gt; &lt;span class="m"&gt;73&lt;/span&gt; c0 &lt;span class="m"&gt;40&lt;/span&gt;  fa &lt;span class="m"&gt;05&lt;/span&gt; &lt;span class="m"&gt;63&lt;/span&gt; &lt;span class="m"&gt;74&lt;/span&gt; &lt;span class="m"&gt;69&lt;/span&gt; 6d &lt;span class="m"&gt;65&lt;/span&gt; c2  &lt;span class="p"&gt;|&lt;/span&gt;s-bits.@..ctime.&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="m"&gt;00000030&lt;/span&gt;  d5 3b ba &lt;span class="m"&gt;65&lt;/span&gt; fa &lt;span class="m"&gt;08&lt;/span&gt; &lt;span class="m"&gt;75&lt;/span&gt; &lt;span class="m"&gt;73&lt;/span&gt;  &lt;span class="m"&gt;65&lt;/span&gt; &lt;span class="m"&gt;64&lt;/span&gt; 2d 6d &lt;span class="m"&gt;65&lt;/span&gt; 6d c2 &lt;span class="m"&gt;70&lt;/span&gt;  &lt;span class="p"&gt;|&lt;/span&gt;.&lt;span class="p"&gt;;&lt;/span&gt;.e..used-mem.p&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="m"&gt;00000040&lt;/span&gt;  &lt;span class="m"&gt;37&lt;/span&gt; 0d &lt;span class="m"&gt;00&lt;/span&gt; fa &lt;span class="m"&gt;08&lt;/span&gt; &lt;span class="m"&gt;61&lt;/span&gt; 6f &lt;span class="m"&gt;66&lt;/span&gt;  2d &lt;span class="m"&gt;62&lt;/span&gt; &lt;span class="m"&gt;61&lt;/span&gt; &lt;span class="m"&gt;73&lt;/span&gt; &lt;span class="m"&gt;65&lt;/span&gt; c0 &lt;span class="m"&gt;01&lt;/span&gt; ff  &lt;span class="p"&gt;|&lt;/span&gt;&lt;span class="m"&gt;7&lt;/span&gt;....aof-base...&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="m"&gt;00000050&lt;/span&gt;  &lt;span class="m"&gt;00&lt;/span&gt; d3 de &lt;span class="m"&gt;03&lt;/span&gt; 2c &lt;span class="m"&gt;42&lt;/span&gt; &lt;span class="m"&gt;96&lt;/span&gt; &lt;span class="m"&gt;75&lt;/span&gt;                           &lt;span class="p"&gt;|&lt;/span&gt;....,B.u&lt;span class="p"&gt;|&lt;/span&gt;
&lt;span class="m"&gt;00000058&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# appendonly.aof.1.incr.aof 是增量文件&lt;/span&gt;
&lt;span class="c1"&gt;# 记载每次写入操作的增量命令&lt;/span&gt;
&lt;span class="c1"&gt;# *2 代表有 2 个操作数 (SELECT 0)&lt;/span&gt;
&lt;span class="c1"&gt;# $6 代表命令长度为 6 (SELECT)&lt;/span&gt;
&lt;span class="c1"&gt;# $1 代表数据长度为 1 (0)&lt;/span&gt;
&lt;span class="c1"&gt;# 后半部分的 `set key value`` 以此类推&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;vagrant@Redis-1 appendonlydir&lt;span class="o"&gt;]&lt;/span&gt;$ cat appendonly.aof.1.incr.aof
*2
&lt;span class="nv"&gt;$6&lt;/span&gt;
SELECT
&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="m"&gt;0&lt;/span&gt;

...

*3
&lt;span class="nv"&gt;$3&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt;
&lt;span class="nv"&gt;$3&lt;/span&gt;
key
&lt;span class="nv"&gt;$5&lt;/span&gt;
value
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;</summary>

  </entry>


  <entry>


    <title>SpringBoot 笔记</title>

    <link href="http://imlane.zhanglintc.co/post/springbootbi-ji"  rel="alternate"></link>

    <updated>2024-01-15T22:38:00Z</updated>
    <id>post/springbootbi-ji</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;Initializer&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_text  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;# 官方
https://start.spring.io
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_text  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;# 阿里云
https://start.aliyun.com
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_1" class="h16"&gt;&lt;span class="span_for_h"&gt;JAR / WAR&lt;/span&gt;&lt;/h2&gt;
&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;如果希望使用 jar 启动的话，即类似 &lt;code&gt;java -jar ohMySpringBoot.jar&lt;/code&gt; 的方式启动（微服务推荐方式），则 pom 中如下配置：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_xml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;jar&lt;span class="nt"&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- jar模式下此包可以不要 --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-tomcat&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;如果希望使用 war 的方式启动，则如下配置：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_xml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;packaging&amp;gt;&lt;/span&gt;war&lt;span class="nt"&gt;&amp;lt;/packaging&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-tomcat&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- 为了IDEA里可以调试，此处可以设为默认的compile --&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- 不过部署的时候似乎可能与外部的tomcat冲突 --&amp;gt;&lt;/span&gt;
    &lt;span class="c"&gt;&amp;lt;!-- 如果冲突可以改为provided --&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;compile&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="toc_2" class="h16"&gt;&lt;span class="span_for_h"&gt;数据库&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_xml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-starter-jdbc&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;mysql&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;mysql-connector-java&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nd"&gt;@SpringBootTest&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OhMySpringBootApplicationTests&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="n"&gt;DataSource&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Test&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;contextLoads&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;SQLException&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dataSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConnection&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;IndexController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="n"&gt;JdbcTemplate&lt;/span&gt; &lt;span class="n"&gt;jdbcTemplate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;select * from Student&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jdbcTemplate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;queryForList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_3" class="h16"&gt;&lt;span class="span_for_h"&gt;打 jar 包&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_xml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;plugins&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.maven.plugins&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-jar-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.1.2&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;archive&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;manifest&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;mainClass&amp;gt;&lt;/span&gt;co.zhanglintc.App&lt;span class="nt"&gt;&amp;lt;/mainClass&amp;gt;&lt;/span&gt;
          &lt;span class="nt"&gt;&amp;lt;/manifest&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/archive&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/plugins&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_xml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${spring-boot.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mainClass&amp;gt;&lt;/span&gt;co.zhanglintc.ohMySpringBoot.OhMySpringBootApplication&lt;span class="nt"&gt;&amp;lt;/mainClass&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;skip&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/skip&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;repackage&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;repackage&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_4" class="h16"&gt;&lt;span class="span_for_h"&gt;排错&lt;/span&gt;&lt;/h2&gt;
&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;&lt;code&gt;webxml attribute is required (or pre-existing WEB-INF/web.xml if executing in update mode)&lt;/code&gt;&lt;div class="codehilite code_lang_xml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;failOnMissingWebXml&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/failOnMissingWebXml&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Or --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;maven-war-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;3.0.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;打包完成的 jar 包过小，导致无法直接启动

&lt;div class="codehilite code_lang_xml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.springframework.boot&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;spring-boot-maven-plugin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;${spring-boot.version}&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;mainClass&amp;gt;&lt;/span&gt;co.zhanglintc.ohMySpringBoot.OhMySpringBootApplication&lt;span class="nt"&gt;&amp;lt;/mainClass&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- 检查此处，不能为true，否则此插件被跳过了 --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;skip&amp;gt;&lt;/span&gt;false&lt;span class="nt"&gt;&amp;lt;/skip&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;id&amp;gt;&lt;/span&gt;repackage&lt;span class="nt"&gt;&amp;lt;/id&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;repackage&lt;span class="nt"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="toc_5" class="h16"&gt;&lt;span class="span_for_h"&gt;Spring 基础&lt;/span&gt;&lt;/h2&gt;
&lt;ul class="md_list md_ul"&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;声明 bean

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// 通用注解，下记不适用时使用&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;

&lt;span class="c1"&gt;// 用于 Dao 层&lt;/span&gt;
&lt;span class="nd"&gt;@Repository&lt;/span&gt;

&lt;span class="c1"&gt;// 用于 Service 层&lt;/span&gt;
&lt;span class="nd"&gt;@Service&lt;/span&gt;

&lt;span class="c1"&gt;// 用于 Controller 层&lt;/span&gt;
&lt;span class="nd"&gt;@Controller&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;简单类型赋值

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nd"&gt;@Value&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;引用类型赋值

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// 由 Spring 提供， 默认赋值方式为 byType&lt;/span&gt;
&lt;span class="nd"&gt;@Autowired&lt;/span&gt;
&lt;span class="c1"&gt;// Autowired 需要赋值方式为 byName 时配合使用&lt;/span&gt;
&lt;span class="nd"&gt;@Qualifier&lt;/span&gt;

&lt;span class="c1"&gt;// 由 jdk 提供，默认赋值方式为 byName&lt;/span&gt;
&lt;span class="c1"&gt;// 如果 byName 失败会自动尝试 byType&lt;/span&gt;
&lt;span class="c1"&gt;// 高于 jdk 1.8 需要添加依赖 javax-annotaion-api&lt;/span&gt;
&lt;span class="c1"&gt;// （那么看起来还是用 Autowired 比较科学）&lt;/span&gt;
&lt;span class="nd"&gt;@Resource&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li class="md_li"&gt;&lt;span class="md_li_span"&gt;@Component / @Bean

&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// 直接作用于类&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;lkm&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getName&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// 作用于方法，用于把方法返回的对象注入。没有源码时非常实用。&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// @Configuration 相当于 &amp;lt;beans&amp;gt;&amp;lt;/beans&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;// @Bean 相当于 &amp;lt;bean&amp;gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;
&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WebSocketConfig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt; &lt;span class="nf"&gt;student&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Student&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="toc_6" class="h16"&gt;&lt;span class="span_for_h"&gt;激活 profiles 的方式&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# 命令行方式是一种外部配置的方式，在执行java -jar命令时可以通过 --spring.profiles.active=test的方式进行激活指定的profiles&lt;/span&gt;
java -jar order.0.0.1-SNAPSHOT.jar --spring.profiles.active&lt;span class="o"&gt;=&lt;/span&gt;dev &amp;gt; logs.info &lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;

&lt;span class="c1"&gt;# Java系统属性方式也是一种外部配置的方式，在执行java -jar命令时可以通过-Dspring.profiles.active=test 的方式进行激活指定的profiles&lt;/span&gt;
&lt;span class="c1"&gt;# 注意：-D方式设置Java系统属性要在-jar前定义&lt;/span&gt;
java -Dspring.profiles.active&lt;span class="o"&gt;=&lt;/span&gt;dev -jar order.0.0.1-SNAPSHOT.jar &amp;gt; logs.info &lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;

&lt;span class="c1"&gt;# 编辑环境变量配置文件/etc/profile，添加名为 SPRING_PROFILES_ACTIVE 的环境变量&lt;/span&gt;
&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;SPRING_PROFILES_ACTIVE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev

&lt;span class="c1"&gt;# 配置文件方式是最常用的方式，不过灵活性不强，局限性比较大，不建议使用这种方式来激活配置文件，我们只需要在application.yml配置文件添加配置即可&lt;/span&gt;
spring:
  profiles:
    active: dev
    
&lt;span class="c1"&gt;# 命令行方式 &amp;gt; Java系统属性方式 &amp;gt; 系统变量方式 &amp;gt; 配置文件方式&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;span class="md_repeated_n md_repeated_n_1"&gt;&lt;/span&gt;&lt;h2 id="toc_7" class="h16"&gt;&lt;span class="span_for_h"&gt;Mybatis&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;输出log：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_yaml  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nt"&gt;mybatis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
 &lt;span class="nt"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="nt"&gt;log-impl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;org.apache.ibatis.logging.stdout.StdOutImpl&lt;/span&gt;

&lt;span class="c1"&gt;# Or&lt;/span&gt;

&lt;span class="nt"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nt"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nt"&gt;co.zhanglintc.ohMySpringBoot.mapper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;debug&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;h2 id="toc_8" class="h16"&gt;&lt;span class="span_for_h"&gt;Misc&lt;/span&gt;&lt;/h2&gt;
&lt;div class="codehilite code_lang_java  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// 输出：&lt;/span&gt;
&lt;span class="c1"&gt;// file:/D:/_Git_for_me/IDEA/ohMyApp/target/classes/&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// 相当于 `ohMyApp/src/main/resources/` 目录&lt;/span&gt;
&lt;span class="c1"&gt;// 也对应 `ohMyApp/target/classes/` 目录&lt;/span&gt;
&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClassLoader&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;// 输出：&lt;/span&gt;
&lt;span class="c1"&gt;// file:/D:/_Git_for_me/IDEA/ohMyApp/target/classes/co/zhanglintc/&lt;/span&gt;
&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;</summary>

  </entry>


  <entry>


    <title>autossh 总是自动重连的探究</title>

    <link href="http://imlane.zhanglintc.co/post/autosshzong-shi-zi-dong-zhong-lian-de-tan-jiu"  rel="alternate"></link>

    <updated>2023-10-11T21:38:00Z</updated>
    <id>post/autosshzong-shi-zi-dong-zhong-lian-de-tan-jiu</id>

    <author>
      <name>IMLANE</name>

    </author>
    <summary type="html">&lt;h2 id="toc_0" class="h16 md_first_h"&gt;&lt;span class="span_for_h"&gt;背景&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;用树莓派做了个采集器，采集到的数据需要放到阿里云服务器的 MySQL 上。因为 MySQL 只监听了 127.0.0.1，所以需要做一个端口转发到到阿里云服务器。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;又因为我希望如果端口转发挂掉后能自动重连，所以我选择了使用 &lt;code&gt;autossh&lt;/code&gt; 来帮我完成这个工作。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;使用的命令如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo autossh -f -M &lt;span class="m"&gt;666&lt;/span&gt; -N -o &lt;span class="s2"&gt;&amp;quot;PubkeyAuthentication=yes&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;StrictHostKeyChecking=false&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;PasswordAuthentication=no&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;ServerAliveInterval 10&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;ServerAliveCountMax 3&amp;quot;&lt;/span&gt; -L localhost:1516:localhost:1516 -i /XXXXX/id_rsa user@server.com
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;开始使用后，我观察到采集器的 log 经常报错，基本都类似如下内容：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_text  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2023-10-11 18:59:42,897 [ERROR] MySQLDBManager.py &amp;lt;update_category:161&amp;gt; - e.errno: 2055, error: 2055: Lost connection to MySQL server at &amp;#39;127.0.0.1:3306&amp;#39;, system error: 32 Broken pipe
2023-10-11 18:59:43,944 [ERROR] MySQLDBManager.py &amp;lt;get_category_line:134&amp;gt; - error: 2055: Lost connection to MySQL server at &amp;#39;127.0.0.1:3306&amp;#39;, system error: 32 Broken pipe, sql:
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;全都是连接断掉的相关信息。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;起初我还很高兴，这说明 &lt;code&gt;autossh&lt;/code&gt;正在工作，我选择使用 &lt;code&gt;autossh&lt;/code&gt; 进行自动重连是正确的。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;我认为这只是网络不稳定，所以 ssh 断掉了，所以 &lt;code&gt;autossh&lt;/code&gt; 帮我重连了 ssh，此时我丝毫没有怀疑 &lt;code&gt;autossh&lt;/code&gt;。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;但是后来我有一次 &lt;code&gt;cat trace.log | grep error&lt;/code&gt; 的时候发现错误时间似乎特别有规律：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_text  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;2023-10-11 14:00:29,714 [ERROR] MySQLDBManager.py &amp;lt;insert_multi:280&amp;gt; - e.errno: 2013, error: 2013: Lost connection to MySQL server during query
2023-10-11 14:10:00,456 [ERROR] MySQLDBManager.py &amp;lt;update_category:161&amp;gt; - e.errno: 2013, error: 2013: Lost connection to MySQL server during query
2023-10-11 14:10:31,360 [ERROR] MySQLDBManager.py &amp;lt;insert_multi:280&amp;gt; - e.errno: 2013, error: 2013: Lost connection to MySQL server during query
2023-10-11 14:20:14,978 [ERROR] MySQLDBManager.py &amp;lt;get_category_line:134&amp;gt; - error: 2013: Lost connection to MySQL server during query, sql: 
2023-10-11 14:20:15,025 [ERROR] MySQLDBManager.py &amp;lt;get_category_line:134&amp;gt; - error: 2055: Lost connection to MySQL server at &amp;#39;127.0.0.1:3306&amp;#39;, system error: 32 Broken pipe, sql: 
2023-10-11 14:20:15,059 [ERROR] MySQLDBManager.py &amp;lt;get_category_line:134&amp;gt; - error: 2055: Lost connection to MySQL server at &amp;#39;127.0.0.1:3306&amp;#39;, system error: 32 Broken pipe, sql: 
2023-10-11 14:20:16,554 [ERROR] MySQLDBManager.py &amp;lt;update_category:161&amp;gt; - e.errno: 2055, error: 2055: Lost connection to MySQL server at &amp;#39;127.0.0.1:3306&amp;#39;, system error: 32 Broken pipe
2023-10-11 14:20:44,648 [ERROR] MySQLDBManager.py &amp;lt;insert_multi:280&amp;gt; - e.errno: 2013, error: 2013: Lost connection to MySQL server during query
2023-10-11 14:30:31,055 [ERROR] MySQLDBManager.py &amp;lt;update_category:161&amp;gt; - e.errno: 2013, error: 2013: Lost connection to MySQL server during query
2023-10-11 14:30:43,774 [ERROR] MySQLDBManager.py &amp;lt;insert_multi:280&amp;gt; - e.errno: 2013, error: 2013: Lost connection to MySQL server during query
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;可见错误有明显的的时间间隔 10 分钟。这就不太正常了，如此有规律的断线显然应该不是随机事件，而是有原因的。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;由此我开始了我的调查，此时我依然没有怀疑 &lt;code&gt;autossh&lt;/code&gt;。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_1" class="h16"&gt;&lt;span class="span_for_h"&gt;调查&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;一开始我也没什么思路，先查了下 &lt;code&gt;man autossh&lt;/code&gt;，倒是看到一个环境变量 &lt;code&gt;AUTOSSH_POLL&lt;/code&gt; 它的默认值正好就是 600 秒，符合我观察到的 10 分钟间隔。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;于是我修改了我的 autossh 命令：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;AUTOSSH_POLL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; sudo autossh -f -M &lt;span class="m"&gt;666&lt;/span&gt; -N -o &lt;span class="s2"&gt;&amp;quot;PubkeyAuthentication=yes&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;StrictHostKeyChecking=false&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;PasswordAuthentication=no&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;ServerAliveInterval 10&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;ServerAliveCountMax 3&amp;quot;&lt;/span&gt; -L localhost:1516:localhost:1516 -i /XXXXX/id_rsa user@server.com
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;在前面添加了 &lt;code&gt;export AUTOSSH_POLL=60&lt;/code&gt;，然而并没有什么卵效果。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;于是我又去 v2ex 发了个帖子：&lt;a class="md_compiled" href="https://www.v2ex.com/t/981057"&gt;SSH 端口转发 10 分钟左右自动断开一般是什么原因？&lt;/a&gt;。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;回复里提到了一个 StackOverflow 的提问：&lt;a class="md_compiled" href="https://stackoverflow.com/questions/61732346/autossh-tunnel-getting-killed-after-10-minutes"&gt;https://stackoverflow.com/questions/61732346/autossh-tunnel-getting-killed-after-10-minutes&lt;/a&gt;。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;跟我的现象类似却又不同，它也是 10 分钟掉线，我也是。但是它是有多个 autossh 竞争端口，我并没有。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;但是我看到它也提到了 &lt;code&gt;AUTOSSH_POLL&lt;/code&gt; 这个参数，那么这个参数的嫌疑就很大了。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;而且这个帖子里设置环境变量的写法与我不同，于是尝试修改为与那个回答一致：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo &lt;span class="nv"&gt;AUTOSSH_POLL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;60&lt;/span&gt; autossh -f -M &lt;span class="m"&gt;666&lt;/span&gt; -N -o &lt;span class="s2"&gt;&amp;quot;PubkeyAuthentication=yes&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;StrictHostKeyChecking=false&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;PasswordAuthentication=no&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;ServerAliveInterval 10&amp;quot;&lt;/span&gt; -o &lt;span class="s2"&gt;&amp;quot;ServerAliveCountMax 3&amp;quot;&lt;/span&gt; -L localhost:1516:localhost:1516 -i /XXXXX/id_rsa user@server.com
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;这次有了一点效果，log 中每次报错的时间从 10 分钟变为了 1 分钟，那么现在就比较明显的是 &lt;code&gt;autossh&lt;/code&gt; 的问题了，而不是我起初怀疑的 ssh 的问题。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;但是此时依然没有什么思路说到底是 autossh 的哪里不对。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;尝试查看了系统日志 &lt;code&gt;tail -n100 /var/log/messages&lt;/code&gt;:&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_text  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;Oct 11 18:40:11 raspberrypi autossh[18954]: starting ssh (count 1)
Oct 11 18:40:11 raspberrypi autossh[18954]: ssh child pid is 18955
Oct 11 18:41:26 raspberrypi autossh[18954]: timeout polling to accept read connection
Oct 11 18:41:26 raspberrypi autossh[18954]: port down, restarting ssh
Oct 11 18:41:26 raspberrypi autossh[18954]: starting ssh (count 2)
Oct 11 18:41:26 raspberrypi autossh[18954]: ssh child pid is 19068
Oct 11 18:42:41 raspberrypi autossh[18954]: timeout polling to accept read connection
Oct 11 18:42:41 raspberrypi autossh[18954]: port down, restarting ssh
Oct 11 18:42:41 raspberrypi autossh[18954]: starting ssh (count 3)
Oct 11 18:42:41 raspberrypi autossh[18954]: ssh child pid is 19182
Oct 11 18:43:56 raspberrypi autossh[18954]: timeout polling to accept read connection
Oct 11 18:43:56 raspberrypi autossh[18954]: port down, restarting ssh
Oct 11 18:43:56 raspberrypi autossh[18954]: starting ssh (count 4)
Oct 11 18:43:56 raspberrypi autossh[18954]: ssh child pid is 19295
Oct 11 18:45:11 raspberrypi autossh[18954]: timeout polling to accept read connection
Oct 11 18:45:11 raspberrypi autossh[18954]: port down, restarting ssh
Oct 11 18:45:11 raspberrypi autossh[18954]: starting ssh (count 5)
Oct 11 18:45:11 raspberrypi autossh[18954]: ssh child pid is 19446
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;只是能看到每分钟再自动重启，除此以外并没有什么有用的信息。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;突然灵光一闪现想起来 StackOverflow 里提到了&lt;strong&gt;端口&lt;/strong&gt;竞争，我似乎之前 &lt;code&gt;ps -ef | grep ssh&lt;/code&gt; 的时候似乎发现过什么一个奇怪的端口：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;root     &lt;span class="m"&gt;20959&lt;/span&gt;     &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;:00 ?        &lt;span class="m"&gt;00&lt;/span&gt;:00:00 /usr/lib/autossh/autossh    -M &lt;span class="m"&gt;666&lt;/span&gt; -N -o &lt;span class="nv"&gt;PubkeyAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes -o &lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; -o &lt;span class="nv"&gt;PasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no -o ServerAliveInterval &lt;span class="m"&gt;10&lt;/span&gt; -o ServerAliveCountMax &lt;span class="m"&gt;3&lt;/span&gt; -L localhost:1516:localhost:1516 -i /XXXXX/id_rsa user@server.com
root     &lt;span class="m"&gt;20960&lt;/span&gt; &lt;span class="m"&gt;20959&lt;/span&gt;  &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;:00 ?        &lt;span class="m"&gt;00&lt;/span&gt;:00:43 /usr/bin/ssh -L &lt;span class="m"&gt;666&lt;/span&gt;:127.0.0.1:666 -R &lt;span class="m"&gt;666&lt;/span&gt;:127.0.0.1:667 -N -o &lt;span class="nv"&gt;PubkeyAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes -o &lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; -o &lt;span class="nv"&gt;PasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no -o ServerAliveInterval &lt;span class="m"&gt;10&lt;/span&gt; -o ServerAliveCountMax &lt;span class="m"&gt;3&lt;/span&gt; -L localhost:1516:localhost:1516 -i /XXXXX/id_rsa user@server.com
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;此处可以看到 &lt;code&gt;-R 666:127.0.0.1:667&lt;/code&gt;，这说明 ssh 理应在远端服务器上创建一个 666 端口的监听。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line"&gt;但是我查过远端服务器，并没有观察到过这个端口。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;同时需要注意到这个端口是一个小于 1024 的&lt;strong&gt;低位端口&lt;/strong&gt;，这就比较危险了，似乎有可能是因为端口被服务器禁止启动了。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;于是尝试将&lt;strong&gt;低位端口&lt;/strong&gt; 666 改成&lt;strong&gt;高位端口&lt;/strong&gt; 6666 后再次启用 autossh：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;root     &lt;span class="m"&gt;20959&lt;/span&gt;     &lt;span class="m"&gt;1&lt;/span&gt;  &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;:00 ?        &lt;span class="m"&gt;00&lt;/span&gt;:00:00 /usr/lib/autossh/autossh    -M &lt;span class="m"&gt;6666&lt;/span&gt; -N -o &lt;span class="nv"&gt;PubkeyAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes -o &lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; -o &lt;span class="nv"&gt;PasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no -o ServerAliveInterval &lt;span class="m"&gt;10&lt;/span&gt; -o ServerAliveCountMax &lt;span class="m"&gt;3&lt;/span&gt; -L localhost:1516:localhost:1516 -i /XXXXX/id_rsa user@server.com
root     &lt;span class="m"&gt;20960&lt;/span&gt; &lt;span class="m"&gt;20959&lt;/span&gt;  &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;19&lt;/span&gt;:00 ?        &lt;span class="m"&gt;00&lt;/span&gt;:00:43 /usr/bin/ssh -L &lt;span class="m"&gt;6666&lt;/span&gt;:127.0.0.1:6666 -R &lt;span class="m"&gt;6666&lt;/span&gt;:127.0.0.1:6667 -N -o &lt;span class="nv"&gt;PubkeyAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yes -o &lt;span class="nv"&gt;StrictHostKeyChecking&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt; -o &lt;span class="nv"&gt;PasswordAuthentication&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;no -o ServerAliveInterval &lt;span class="m"&gt;10&lt;/span&gt; -o ServerAliveCountMax &lt;span class="m"&gt;3&lt;/span&gt; -L localhost:1516:localhost:1516 -i /XXXXX/id_rsa user@server.com
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;然后去远端服务器观察，终于发现远端服务器上也出现了 6666 的端口监听。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;接着又进行了一个小时的运行观察，再也没有出现过端口转发断线的问题了。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;由此问题解决。&lt;/span&gt;
&lt;/p&gt;

&lt;h2 id="toc_2" class="h16"&gt;&lt;span class="span_for_h"&gt;总结&lt;/span&gt;&lt;/h2&gt;

&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;&lt;code&gt;autossh&lt;/code&gt; 的原理是先启动自己，然后启动一个 &lt;code&gt;ssh&lt;/code&gt; 子进程。然后因为使用了 &lt;code&gt;-M 6666&lt;/code&gt; 参数， autossh 还会在本地启动两个监听端口： 6666 和 6667，并且在远端启动一个监听端口。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block md_block_as_opening"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;使用 &lt;code&gt;netstat -ntlp&lt;/code&gt; 命令分别观察，可见正常的时候端口监听情况如下：&lt;/span&gt;
&lt;/p&gt;

&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Local&lt;/span&gt;
tcp        &lt;span class="m"&gt;0&lt;/span&gt;      &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:6666          &lt;span class="m"&gt;0&lt;/span&gt;.0.0.0:*               LISTEN      -
tcp        &lt;span class="m"&gt;0&lt;/span&gt;      &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;127&lt;/span&gt;.0.0.1:6667          &lt;span class="m"&gt;0&lt;/span&gt;.0.0.0:*               LISTEN      -
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;&lt;div class="codehilite code_lang_shell  highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# Remote&lt;/span&gt;
tcp        &lt;span class="m"&gt;0&lt;/span&gt;      &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;.0.0.0:6666            &lt;span class="m"&gt;0&lt;/span&gt;.0.0.0:*               LISTEN      &lt;span class="m"&gt;11524&lt;/span&gt;/sshd: lane
&lt;/pre&gt;&lt;/div&gt;

&lt;!--block_code_end--&gt;
&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start"&gt;然后 autossh 会往这些监听端口定时里发消息，以判断 ssh 端口转发是否还能正常工作，时间间隔正好是 &lt;code&gt;AUTOSSH_POLL&lt;/code&gt;。&lt;br /&gt;&lt;/span&gt;
    &lt;span class="md_line md_line_end"&gt;由此可以解释为什么之前会每 10 分钟和每 1 分钟断线重连一次。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;我这次的情况就是远端监听端口没有启动成功，&lt;code&gt;AUTOSSH_POLL&lt;/code&gt; 的时间到后，发送到远端的消息无法在传回来，于是 autossh 认为网络超时自动帮我重启了 ssh 子进程。&lt;/span&gt;
&lt;/p&gt;


&lt;p class="md_block last_md_block_in_page"&gt;
    &lt;span class="md_line md_line_start md_line_end"&gt;所以以后使用 autossh 的时候还要注意监听端口不要选择&lt;strong&gt;低位端口&lt;/strong&gt;，否则可能会在远端启动失败，导致 ssh 总是被重启。&lt;/span&gt;
&lt;/p&gt;</summary>

  </entry>


</feed>