<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>岁月细碎点滴快查</title>
	<atom:link href="https://blog.mutadecheng.com/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.mutadecheng.com</link>
	<description></description>
	<lastBuildDate>Thu, 21 May 2026 09:47:31 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>
	<item>
		<title>MySql Docker 安装以及配置</title>
		<link>https://blog.mutadecheng.com/2026/05/21/mysql-docker-%e5%ae%89%e8%a3%85%e4%bb%a5%e5%8f%8a%e9%85%8d%e7%bd%ae/</link>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Thu, 21 May 2026 09:47:30 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=694</guid>

					<description><![CDATA[创建镜像 使用密码登录 然后输入密码。 然后输入如下]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">创建镜像</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="version: &quot;3.8&quot;

services:  
  mysql:
    image: swr.cn-north-4.myhuaweicloud.com/library/mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: &quot;mypassword&quot;
    ports:
      - &quot;3306:3306&quot;
    volumes:
      - mysql_data:/var/lib/mysql
    restart: unless-stopped
    logging:
      driver: &quot;json-file&quot;
      options:
        max-size: &quot;100m&quot;
        max-file: &quot;3&quot;
    networks:
      - admin-net 

volumes: 
  mysql_data:
    
networks:
  admin-net:
    external: true
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">version</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;3.8&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">services</span><span style="color: #D4D4D4">:  </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">mysql</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">image</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">swr.cn-north-4.myhuaweicloud.com/library/mysql:8.0</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">environment</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">MYSQL_ROOT_PASSWORD</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;mypassword&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">ports</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;3306:3306&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">volumes</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">mysql_data:/var/lib/mysql</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">restart</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">unless-stopped</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">logging</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">driver</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;json-file&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">options</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-size</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;100m&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-file</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;3&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">networks</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">admin-net</span><span style="color: #D4D4D4"> </span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">volumes</span><span style="color: #D4D4D4">: </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">mysql_data</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span></span>
<span class="line"><span style="color: #569CD6">networks</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">admin-net</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">external</span><span style="color: #D4D4D4">: </span><span style="color: #569CD6">true</span></span>
<span class="line"></span></code></pre></div>



<h2 class="wp-block-heading">使用密码登录</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="mysql -u root -p" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">mysql</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-u</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">root</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-p</span></span></code></pre></div>



<p class="wp-block-paragraph">然后输入密码。</p>



<h2 class="wp-block-heading">然后输入如下</h2>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="-- 创建或更新 root 用户,允许从任何主机连接
CREATE USER 'root'@'%' IDENTIFIED BY 'mypassword';

-- 授予所有权限
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;

-- 刷新权限使其生效
FLUSH PRIVILEGES;

-- 查看当前 root 用户的主机配置
SELECT host, user FROM mysql.user WHERE user='root';
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">--</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">创建或更新</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">root</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">用户,允许从任何主机连接</span></span>
<span class="line"><span style="color: #DCDCAA">CREATE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">USER</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;root&#39;@&#39;%&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">IDENTIFIED</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">BY</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;mypassword&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">--</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">授予所有权限</span></span>
<span class="line"><span style="color: #DCDCAA">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ALL</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">PRIVILEGES</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">ON</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">*</span><span style="color: #CE9178">.</span><span style="color: #569CD6">*</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">TO</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&#39;root&#39;@&#39;%&#39;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">WITH</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">GRANT</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">OPTION</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">--</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">刷新权限使其生效</span></span>
<span class="line"><span style="color: #DCDCAA">FLUSH</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">PRIVILEGES</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #DCDCAA">--</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">查看当前</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">root</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">用户的主机配置</span></span>
<span class="line"><span style="color: #DCDCAA">SELECT</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">host,</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">user</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">FROM</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">mysql.user</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">WHERE</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">user=&#39;root&#39;</span><span style="color: #D4D4D4">;</span></span>
<span class="line"></span></code></pre></div>



<p class="wp-block-paragraph"> </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Hyper-V 虚拟机安全设置中启用 TPM 时报错</title>
		<link>https://blog.mutadecheng.com/2026/05/14/hyper-v-%e8%99%9a%e6%8b%9f%e6%9c%ba%e5%ae%89%e5%85%a8%e8%ae%be%e7%bd%ae%e4%b8%ad%e5%90%af%e7%94%a8-tpm-%e6%97%b6%e6%8a%a5%e9%94%99/</link>
					<comments>https://blog.mutadecheng.com/2026/05/14/hyper-v-%e8%99%9a%e6%8b%9f%e6%9c%ba%e5%ae%89%e5%85%a8%e8%ae%be%e7%bd%ae%e4%b8%ad%e5%90%af%e7%94%a8-tpm-%e6%97%b6%e6%8a%a5%e9%94%99/#respond</comments>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Thu, 14 May 2026 06:38:12 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=692</guid>

					<description><![CDATA[问题现象 在 Hyper-V 虚拟机安全设置中启用 TPM 时报错： &#8220;设置密钥保护器失败。无法为 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">问题现象</h2>



<p class="wp-block-paragraph">在 Hyper-V 虚拟机安全设置中启用 TPM 时报错：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">&#8220;设置密钥保护器失败。无法为包装中的证书签名。已尝试为证书 Signing 签名。&#8221;</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">根本原因（层层递进）</h2>



<pre class="wp-block-preformatted">启用 TPM 失败
    │
    ▼
Hyper-V 尝试用"签名证书"对密钥保护器签名
    │
    ▼
证书存在于 Cert:\LocalMachine\Shielded VM Local Certificates
但私钥提供程序类型损坏（NTE_PROV_TYPE_NOT_DEF / 无效的提供程序类型）
    │
    ▼
HasPrivateKey = True（元数据显示有私钥）
但实际访问私钥时返回 NULL（私钥文件损坏或提供程序不匹配）
    │
    ▼
VMMS 无法完成签名操作 → 报错
</pre>



<h3 class="wp-block-heading">具体原因分解</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">层级</th><th class="has-text-align-left" data-align="left">问题</th></tr></thead><tbody><tr><td><strong>表层</strong></td><td>Hyper-V 启用 TPM 报错</td></tr><tr><td><strong>中层</strong></td><td>Shielded VM Local Certificates&nbsp;中的签名/加密证书私钥损坏</td></tr><tr><td><strong>深层</strong></td><td>证书绑定的加密提供程序类型无效，私钥文件实际不可访问</td></tr><tr><td><strong>附加坑</strong></td><td>修复时&nbsp;-KeySpec Signature&nbsp;参数与&nbsp;Microsoft Software Key Storage Provider&nbsp;不兼容，导致修复脚本中签名证书创建失败</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">解决逻辑</h2>



<pre class="wp-block-preformatted">第一步：定位问题
├── 检查 Cert:\LocalMachine\Shielded VM Local Certificates
├── 发现证书存在但 PrivateKey 返回 NULL
└── 确认私钥提供程序类型损坏

第二步：清理损坏环境
├── 停止 VMMS 服务
├── 删除损坏的 Shielded VM 证书
└── 删除旧的 HGS 守护者 (UntrustedGuardian)

第三步：重建证书
├── 使用 Microsoft Software Key Storage Provider
├── 不带 -KeySpec 参数（KSP 不兼容 KeySpec）
├── 创建签名证书（KeyUsage: DigitalSignature）
└── 创建加密证书（KeyUsage: KeyEncipherment/DataEncipherment）

第四步：重建守护者
├── New-HgsGuardian -Name "UntrustedGuardian"
├── 绑定新签名证书 Thumbprint
└── 绑定新加密证书 Thumbprint

第五步：验证
├── 启动 VMMS
├── 确认 Shielded VM Local Certificates 中出现 2 张新证书
└── Hyper-V 管理器中成功启用 TPM
</pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">关键命令回顾</h2>



<pre class="wp-block-preformatted">powershell</pre>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="# 1. 停止服务
Stop-Service vmms -Force

# 2. 删除损坏证书
Get-ChildItem &quot;Cert:\LocalMachine\Shielded VM Local Certificates&quot; | Remove-Item -Force

# 3. 删除旧守护者
Import-Module HgsClient
Get-HgsGuardian | Remove-HgsGuardian

# 4. 创建新证书（关键：不带 -KeySpec）
$signingCert = New-SelfSignedCertificate `
    -Subject &quot;CN=Shielded VM Signing Certificate (UntrustedGuardian) ($env:COMPUTERNAME)&quot; `
    -CertStoreLocation &quot;Cert:\LocalMachine\My&quot; `
    -KeyUsage DigitalSignature `
    -Provider &quot;Microsoft Software Key Storage Provider&quot; `
    -NotAfter (Get-Date).AddYears(10)

$encryptionCert = New-SelfSignedCertificate `
    -Subject &quot;CN=Shielded VM Encryption Certificate (UntrustedGuardian) ($env:COMPUTERNAME)&quot; `
    -CertStoreLocation &quot;Cert:\LocalMachine\My&quot; `
    -KeyUsage KeyEncipherment, DataEncipherment `
    -Provider &quot;Microsoft Software Key Storage Provider&quot; `
    -NotAfter (Get-Date).AddYears(10)

# 5. 重建守护者
New-HgsGuardian `
    -Name &quot;UntrustedGuardian&quot; `
    -SigningCertificateThumbprint $signingCert.Thumbprint `
    -EncryptionCertificateThumbprint $encryptionCert.Thumbprint `
    -AllowUntrustedRoot

# 6. 重启服务
Start-Service vmms" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #6A9955"># 1. 停止服务</span></span>
<span class="line"><span style="color: #DCDCAA">Stop-Service</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vmms</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-Force</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># 2. 删除损坏证书</span></span>
<span class="line"><span style="color: #DCDCAA">Get-ChildItem</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Cert:\LocalMachine\Shielded VM Local Certificates&quot;</span><span style="color: #D4D4D4"> | </span><span style="color: #DCDCAA">Remove-Item</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">-Force</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># 3. 删除旧守护者</span></span>
<span class="line"><span style="color: #DCDCAA">Import-Module</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">HgsClient</span></span>
<span class="line"><span style="color: #DCDCAA">Get-HgsGuardian</span><span style="color: #D4D4D4"> | </span><span style="color: #DCDCAA">Remove-HgsGuardian</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># 4. 创建新证书（关键：不带 -KeySpec）</span></span>
<span class="line"><span style="color: #9CDCFE">$signingCert</span><span style="color: #D4D4D4"> = New-SelfSignedCertificate </span><span style="color: #CE9178">`</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #DCDCAA">-Subject</span><span style="color: #CE9178"> &quot;CN=Shielded VM Signing Certificate (UntrustedGuardian) (</span><span style="color: #9CDCFE">$env</span><span style="color: #CE9178">:COMPUTERNAME)&quot; `</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">-CertStoreLocation</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Cert:\LocalMachine\My&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">`</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #DCDCAA">-KeyUsage</span><span style="color: #CE9178"> DigitalSignature `</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">-Provider</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;Microsoft Software Key Storage Provider&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">`</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #DCDCAA">-NotAfter</span><span style="color: #CE9178"> (Get-Date).AddYears(</span><span style="color: #DCDCAA">10</span><span style="color: #CE9178">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #9CDCFE">$encryptionCert</span><span style="color: #CE9178"> = New-SelfSignedCertificate `</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">-Subject</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">&quot;CN=Shielded VM Encryption Certificate (UntrustedGuardian) (</span><span style="color: #9CDCFE">$env</span><span style="color: #CE9178">:COMPUTERNAME)&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">`</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #DCDCAA">-CertStoreLocation</span><span style="color: #CE9178"> &quot;Cert:\LocalMachine\My&quot; `</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">-KeyUsage</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">KeyEncipherment,</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">DataEncipherment</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">`</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #DCDCAA">-Provider</span><span style="color: #CE9178"> &quot;Microsoft Software Key Storage Provider&quot; `</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">-NotAfter</span><span style="color: #D4D4D4"> (Get-Date).AddYears(</span><span style="color: #DCDCAA">10</span><span style="color: #D4D4D4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># 5. 重建守护者</span></span>
<span class="line"><span style="color: #DCDCAA">New-HgsGuardian</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">`</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #DCDCAA">-Name</span><span style="color: #CE9178"> &quot;UntrustedGuardian&quot; `</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">-SigningCertificateThumbprint</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">$signingCert</span><span style="color: #CE9178">.Thumbprint</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">`</span></span>
<span class="line"><span style="color: #CE9178">    </span><span style="color: #DCDCAA">-EncryptionCertificateThumbprint</span><span style="color: #CE9178"> </span><span style="color: #9CDCFE">$encryptionCert</span><span style="color: #CE9178">.Thumbprint `</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">-AllowUntrustedRoot</span></span>
<span class="line"></span>
<span class="line"><span style="color: #6A9955"># 6. 重启服务</span></span>
<span class="line"><span style="color: #DCDCAA">Start-Service</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">vmms</span></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">经验教训</h2>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>为什么常规修复手段都无效？</strong></p>
</blockquote>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th class="has-text-align-left" data-align="left">尝试过的方法</th><th class="has-text-align-left" data-align="left">无效原因</th></tr></thead><tbody><tr><td>SFC 扫描</td><td>损坏的是证书私钥数据，不是系统文件</td></tr><tr><td>重装 Hyper-V 功能</td><td>重装不会重建已存在的损坏证书</td></tr><tr><td>重启 Hyper-V 服务</td><td>服务正常，问题在证书层</td></tr><tr><td>查看事件日志</td><td>证书私钥错误不会写入常规 Hyper-V 日志</td></tr></tbody></table></figure>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>为什么&nbsp;certmgr.msc&nbsp;看不到证书？</strong><br>因为损坏的证书存储在&nbsp;<strong>本地计算机</strong>&nbsp;的&nbsp;Shielded VM Local Certificates&nbsp;节点，<br>certmgr.msc&nbsp;只显示<strong>当前用户</strong>证书，需要用&nbsp;certlm.msc&nbsp;才能看到。</p>
</blockquote>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.mutadecheng.com/2026/05/14/hyper-v-%e8%99%9a%e6%8b%9f%e6%9c%ba%e5%ae%89%e5%85%a8%e8%ae%be%e7%bd%ae%e4%b8%ad%e5%90%af%e7%94%a8-tpm-%e6%97%b6%e6%8a%a5%e9%94%99/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>多态大模型与Stable Diffusion类模型 图片生成的区别</title>
		<link>https://blog.mutadecheng.com/2026/02/26/%e5%a4%a7%e6%a8%a1%e5%9e%8b%e4%b8%8estable-diffusion%e7%b1%bb%e6%a8%a1%e5%9e%8b-%e5%9b%be%e7%89%87%e7%94%9f%e6%88%90%e7%9a%84%e5%8c%ba%e5%88%ab/</link>
					<comments>https://blog.mutadecheng.com/2026/02/26/%e5%a4%a7%e6%a8%a1%e5%9e%8b%e4%b8%8estable-diffusion%e7%b1%bb%e6%a8%a1%e5%9e%8b-%e5%9b%be%e7%89%87%e7%94%9f%e6%88%90%e7%9a%84%e5%8c%ba%e5%88%ab/#respond</comments>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Thu, 26 Feb 2026 07:48:14 +0000</pubDate>
				<category><![CDATA[大模型]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=686</guid>

					<description><![CDATA[从原理和提示词用法两个角度，详细解释“大模型生成图片”与“Stable Diffusion（SD）生成图片”的 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">从<strong>原理</strong>和<strong>提示词用法</strong>两个角度，详细解释“大模型生成图片”与“Stable Diffusion（SD）生成图片”的区别，以及为何提示词的用法会不同。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">一、原理上的区别</h2>



<h3 class="wp-block-heading">1. Stable Diffusion（SD）类模型</h3>



<ul class="wp-block-list">
<li><strong>原理</strong>：SD属于扩散模型（Diffusion Model）。它通过“噪声还原”的方式，把一张随机噪声图片逐步还原成符合你输入文本描述的图片。</li>



<li><strong>文本理解</strong>：SD通常会用CLIP或者类似的文本编码器，把你的提示词（prompt）转成向量，然后引导图片生成过程。</li>



<li><strong>训练数据</strong>：SD训练时，提示词通常是简短、标签式的描述（如“a dog, in the park, sunny day”），而不是长篇自然语言。</li>
</ul>



<h3 class="wp-block-heading">2. 大模型（如GPT-4V、ERNIE-ViLG、文心一格等）</h3>



<ul class="wp-block-list">
<li><strong>原理</strong>：大模型（尤其是多模态大模型）可能包含更复杂的文本理解和图像生成能力，甚至可以直接理解更长、更复杂的自然语言描述。</li>



<li><strong>文本理解</strong>：这些模型的文本理解能力更强，能解析更细腻的描述和上下文。</li>



<li><strong>训练数据</strong>：大模型训练时，可能会用到大量自然语言描述和更复杂的上下文信息。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">二、提示词用法的区别</h2>



<h3 class="wp-block-heading">1. SD模型的提示词（Prompt）</h3>



<ul class="wp-block-list">
<li><strong>风格</strong>：更偏向关键词、标签式的组合，比如“a cat, sitting on a chair, 4k, ultra realistic, soft light”。</li>



<li><strong>原因</strong>：SD训练时用的是类似的标签描述，模型对这类提示词的理解最准确，能直接影响生成效果。</li>



<li><strong>优化</strong>：很多“AI绘画”高手会用一长串英文关键词来精细调控画面风格、细节、构图等。</li>
</ul>



<h3 class="wp-block-heading">2. 大模型的提示词</h3>



<ul class="wp-block-list">
<li><strong>风格</strong>：更接近自然语言，可以是完整的一句话，甚至一段话，比如“请生成一张猫咪坐在椅子上的高清照片，阳光明媚，画面温馨”。</li>



<li><strong>原因</strong>：大模型的文本理解能力强，能处理更复杂的语义和上下文，适合用自然语言描述。</li>



<li><strong>优势</strong>：对新手更友好，不需要掌握复杂的关键词搭配。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">三、举例对比</h2>



<ul class="wp-block-list">
<li><strong>SD提示词</strong>：<code>a cat, sitting on a chair, 4k, ultra realistic, soft light</code></li>



<li><strong>大模型提示词</strong>：<code>请生成一只猫咪坐在椅子上的照片，画面清晰，阳光明媚，环境温馨。</code></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">四、总结</h2>



<ol class="wp-block-list">
<li><strong>SD更适合标签式关键词</strong>，因为它的训练和文本理解机制决定了这样效果最好。</li>



<li><strong>大模型更适合自然语言描述</strong>，能理解更复杂的场景和细节。</li>



<li><strong>选择哪种提示词方式</strong>，要看用的是什么模型。如果是SD，建议用关键词+风格词；如果是大模型，可以直接用自然语言。</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.mutadecheng.com/2026/02/26/%e5%a4%a7%e6%a8%a1%e5%9e%8b%e4%b8%8estable-diffusion%e7%b1%bb%e6%a8%a1%e5%9e%8b-%e5%9b%be%e7%89%87%e7%94%9f%e6%88%90%e7%9a%84%e5%8c%ba%e5%88%ab/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>RabbitMQ 使用踩坑记录：并发控制与超时机制实践</title>
		<link>https://blog.mutadecheng.com/2026/02/11/rabbitmq-%e4%bd%bf%e7%94%a8%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95%ef%bc%9a%e5%b9%b6%e5%8f%91%e6%8e%a7%e5%88%b6%e4%b8%8e%e8%b6%85%e6%97%b6%e6%9c%ba%e5%88%b6%e5%ae%9e%e8%b7%b5/</link>
					<comments>https://blog.mutadecheng.com/2026/02/11/rabbitmq-%e4%bd%bf%e7%94%a8%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95%ef%bc%9a%e5%b9%b6%e5%8f%91%e6%8e%a7%e5%88%b6%e4%b8%8e%e8%b6%85%e6%97%b6%e6%9c%ba%e5%88%b6%e5%ae%9e%e8%b7%b5/#respond</comments>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Wed, 11 Feb 2026 02:20:57 +0000</pubDate>
				<category><![CDATA[c#]]></category>
		<category><![CDATA[工作记录]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=682</guid>

					<description><![CDATA[背景 在实际项目中，我使用 RabbitMQ 作为消息队列，后端用 C# 消费消息并做业务处理。随着业务量增大 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">背景</h2>



<p class="wp-block-paragraph">在实际项目中，我使用 RabbitMQ 作为消息队列，后端用 C# 消费消息并做业务处理。随着业务量增大，遇到了<strong>消息消费速度慢</strong>、<strong>并发被拖死</strong>的问题。这里记录下踩过的坑和解决思路。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">1. 并发控制</h2>



<h3 class="wp-block-heading">坑点</h3>



<p class="wp-block-paragraph">RabbitMQ 默认是单线程消费，如果业务处理速度较慢，消息会越积越多。<br>我一开始采用了如下方式控制消费端并发：</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="private readonly SemaphoreSlim _concurrentSemaphore = new SemaphoreSlim(8); // 最大并发8
private readonly ushort prefetchCount = 8;" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">readonly</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SemaphoreSlim</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">_concurrentSemaphore</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">new</span><span style="color: #D4D4D4"> </span><span style="color: #4EC9B0">SemaphoreSlim</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">8</span><span style="color: #D4D4D4">); </span><span style="color: #6A9955">// 最大并发8</span></span>
<span class="line"><span style="color: #569CD6">private</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">readonly</span><span style="color: #D4D4D4"> </span><span style="color: #569CD6">ushort</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">prefetchCount</span><span style="color: #D4D4D4"> = </span><span style="color: #B5CEA8">8</span><span style="color: #D4D4D4">;</span></span></code></pre></div>



<p class="wp-block-paragraph">每次消费消息前 <code>_concurrentSemaphore.Wait()</code>，处理完后 <code>.Release()</code>，并设置 <code>prefetchCount</code> 限制 RabbitMQ 推送未确认消息数。</p>



<h3 class="wp-block-heading">遇到的问题</h3>



<ul class="wp-block-list">
<li>如果某些消息处理很慢（比如卡了10分钟），就会占用并发槽位，导致后面的消息迟迟得不到处理。</li>



<li>只要有慢消息，整个消费端就会“卡死”，消费速度极慢。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">2. 超时机制</h2>



<h3 class="wp-block-heading">解决思路</h3>



<p class="wp-block-paragraph">针对慢消息，我引入了<strong>超时机制</strong>：<br>为每条消息的处理设置最大超时时间（比如5分钟），超过即放弃处理，释放并发槽位。</p>



<h3 class="wp-block-heading">实现方式</h3>



<p class="wp-block-paragraph">只需在消费消息的地方（比如 <code>RabbitMQReceiver</code>）加一层超时包装：</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="TimeSpan timeout = TimeSpan.FromMinutes(5);

var handleTask = _messageHandler.HandleAsync(ea.Body.ToArray());
var timeoutTask = Task.Delay(timeout, stoppingToken);

var completedTask = await Task.WhenAny(handleTask, timeoutTask);

if (completedTask == handleTask)
{
    result = await handleTask;
}
else
{
    // 超时处理
    _logger.LogError($&quot;[RabbitMQ] 消息处理超时（&gt;{timeout.TotalMinutes}分钟），自动放弃 DeliveryTag={ea.DeliveryTag}&quot;);
    result = false;
}" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #4EC9B0">TimeSpan</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">timeout</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">TimeSpan</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">FromMinutes</span><span style="color: #D4D4D4">(</span><span style="color: #B5CEA8">5</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">handleTask</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">_messageHandler</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">HandleAsync</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">ea</span><span style="color: #D4D4D4">.</span><span style="color: #9CDCFE">Body</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">ToArray</span><span style="color: #D4D4D4">());</span></span>
<span class="line"><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">timeoutTask</span><span style="color: #D4D4D4"> = </span><span style="color: #9CDCFE">Task</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">Delay</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">timeout</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">stoppingToken</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">var</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">completedTask</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">await</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">Task</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">WhenAny</span><span style="color: #D4D4D4">(</span><span style="color: #9CDCFE">handleTask</span><span style="color: #D4D4D4">, </span><span style="color: #9CDCFE">timeoutTask</span><span style="color: #D4D4D4">);</span></span>
<span class="line"></span>
<span class="line"><span style="color: #C586C0">if</span><span style="color: #D4D4D4"> (</span><span style="color: #9CDCFE">completedTask</span><span style="color: #D4D4D4"> == </span><span style="color: #9CDCFE">handleTask</span><span style="color: #D4D4D4">)</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">result</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">await</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">handleTask</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span>
<span class="line"><span style="color: #C586C0">else</span></span>
<span class="line"><span style="color: #D4D4D4">{</span></span>
<span class="line"><span style="color: #6A9955">    // 超时处理</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">_logger</span><span style="color: #D4D4D4">.</span><span style="color: #DCDCAA">LogError</span><span style="color: #D4D4D4">(</span><span style="color: #CE9178">$&quot;[RabbitMQ] 消息处理超时（&gt;{</span><span style="color: #9CDCFE">timeout</span><span style="color: #CE9178">.</span><span style="color: #9CDCFE">TotalMinutes</span><span style="color: #CE9178">}分钟），自动放弃 DeliveryTag={</span><span style="color: #9CDCFE">ea</span><span style="color: #CE9178">.</span><span style="color: #9CDCFE">DeliveryTag</span><span style="color: #CE9178">}&quot;</span><span style="color: #D4D4D4">);</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #9CDCFE">result</span><span style="color: #D4D4D4"> = </span><span style="color: #569CD6">false</span><span style="color: #D4D4D4">;</span></span>
<span class="line"><span style="color: #D4D4D4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">这样一来，慢消息不会拖死整个消费端，并发利用率大大提升！</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">3. 日志观察</h2>



<p class="wp-block-paragraph">优化前，经常看到类似日志：</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="[RabbitMQ] 消息全流程结束 DeliveryTag=940850，总耗时: 594604 ms，结果: 成功" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">[</span><span style="color: #4EC9B0">RabbitMQ</span><span style="color: #D4D4D4">] </span><span style="color: #4EC9B0">消息全流程结束</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">DeliveryTag</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">940850</span><span style="color: #D4D4D4">，</span><span style="color: #9CDCFE">总耗时</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">594604</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">ms</span><span style="color: #D4D4D4">，</span><span style="color: #9CDCFE">结果</span><span style="color: #D4D4D4">: </span><span style="color: #9CDCFE">成功</span></span></code></pre></div>



<p class="wp-block-paragraph">有的消息处理竟然超过9分钟！<br>优化后，超时的消息会被及时 Nack 并记录日志：</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="[RabbitMQ] 消息处理超时（&gt;5分钟），自动放弃 DeliveryTag=940850" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #D4D4D4">[</span><span style="color: #4EC9B0">RabbitMQ</span><span style="color: #D4D4D4">] </span><span style="color: #9CDCFE">消息处理超时</span><span style="color: #D4D4D4">（&gt;</span><span style="color: #B5CEA8">5</span><span style="color: #9CDCFE">分钟</span><span style="color: #D4D4D4">），</span><span style="color: #4EC9B0">自动放弃</span><span style="color: #D4D4D4"> </span><span style="color: #9CDCFE">DeliveryTag</span><span style="color: #D4D4D4">=</span><span style="color: #B5CEA8">940850</span></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">4. 建议</h2>



<ul class="wp-block-list">
<li>并发消费一定要配合超时机制，否则慢消息会拖死所有并发。</li>



<li><code>SemaphoreSlim</code> 和 <code>prefetchCount</code> 要一致，保证并发控制有效。</li>



<li>建议对超时消息做告警，方便及时发现和定位问题。</li>



<li>生产环境建议超时时间不要太长，一般2~5分钟足够。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">总结</h2>



<p class="wp-block-paragraph">RabbitMQ 消费端开发中，<strong>并发与超时控制</strong>是高可靠消费的关键。<br>只有二者配合，才能保证高吞吐、低延迟，避免“慢消息拖死全局”的灾难。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.mutadecheng.com/2026/02/11/rabbitmq-%e4%bd%bf%e7%94%a8%e8%b8%a9%e5%9d%91%e8%ae%b0%e5%bd%95%ef%bc%9a%e5%b9%b6%e5%8f%91%e6%8e%a7%e5%88%b6%e4%b8%8e%e8%b6%85%e6%97%b6%e6%9c%ba%e5%88%b6%e5%ae%9e%e8%b7%b5/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Watchtower 实现自动化容器更新</title>
		<link>https://blog.mutadecheng.com/2026/01/14/watchtower-%e5%ae%9e%e7%8e%b0%e8%87%aa%e5%8a%a8%e5%8c%96%e5%ae%b9%e5%99%a8%e6%9b%b4%e6%96%b0/</link>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Wed, 14 Jan 2026 04:02:30 +0000</pubDate>
				<category><![CDATA[DI/CI]]></category>
		<category><![CDATA[Docker]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=676</guid>

					<description><![CDATA[在日常的容器化部署中，应用的镜像经常会有新版本发布。手动更新和重启容器既繁琐又容易出错。为了解决这一问题，我们 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">在日常的容器化部署中，应用的镜像经常会有新版本发布。手动更新和重启容器既繁琐又容易出错。为了解决这一问题，我们可以借助 <a href="https://containrrr.dev/watchtower/">Watchtower</a> 工具，实现容器的自动化更新。本文将结合一个实际的 <code>docker-compose.yml</code> 配置，详细讲解如何配置和使用 Watchtower。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">什么是 Watchtower？</h2>



<p class="wp-block-paragraph">Watchtower 是一个开源工具，用于自动监控和更新运行中的 Docker 容器。当检测到关联镜像有新版本时，Watchtower 会自动拉取新镜像，重建并重启对应的容器。这样可以实现应用的自动“滚动升级”，极大提升运维效率。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Docker Compose 配置示例</h2>



<p class="wp-block-paragraph">下面是一个典型的 <code>docker-compose.yml</code> 配置片段，加入了 Watchtower 服务：</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="version: &quot;3.8&quot;

services: 

  watchtower:
    image: registry.cn-beijing.aliyuncs.com/muta/watchtower:amd64
    restart: unless-stopped
    # 挂载 docker.sock 以便 Watchtower 能管理容器
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /root/.docker/:/config/
    environment:
      - DOCKER_CONFIG=/config
    # 监控项目的容器（tuechpresentation-api-1），这样不会影响其他容器
    command: --cleanup --interval 60 tuechpresentation-api-1" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">version</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;3.8&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">services</span><span style="color: #D4D4D4">: </span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">watchtower</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">image</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">registry.cn-beijing.aliyuncs.com/muta/watchtower:amd64</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">restart</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">unless-stopped</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># 挂载 docker.sock 以便 Watchtower 能管理容器</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">volumes</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">/var/run/docker.sock:/var/run/docker.sock</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">/root/.docker/:/config/</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">environment</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">DOCKER_CONFIG=/config</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #6A9955"># 监控项目的容器（tuechpresentation-api-1），这样不会影响其他容器</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">command</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">--cleanup --interval 60 tuechpresentation-api-1</span></span></code></pre></div>



<p class="wp-block-paragraph">下面我们详细解释每一部分的作用。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">配置详解</h2>



<h3 class="wp-block-heading">1. 镜像设置</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="image: registry.cn-beijing.aliyuncs.com/muta/watchtower:amd64" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">image</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">registry.cn-beijing.aliyuncs.com/muta/watchtower:amd64</span></span></code></pre></div>



<p class="wp-block-paragraph">这里使用的是阿里云镜像仓库中的 Watchtower 镜像，适合国内用户加速下载。</p>



<h3 class="wp-block-heading">2. 容器重启策略</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="restart: unless-stopped" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">restart</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">unless-stopped</span></span></code></pre></div>



<p class="wp-block-paragraph">表示除非手动停止容器，否则 Watchtower 会一直保持运行状态。</p>



<h3 class="wp-block-heading">3. 挂载 Docker Socket</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="volumes:
  - /var/run/docker.sock:/var/run/docker.sock
  - /root/.docker/:/config/" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">volumes</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  - </span><span style="color: #CE9178">/var/run/docker.sock:/var/run/docker.sock</span></span>
<span class="line"><span style="color: #D4D4D4">  - </span><span style="color: #CE9178">/root/.docker/:/config/</span></span></code></pre></div>



<ul class="wp-block-list">
<li><code>/var/run/docker.sock:/var/run/docker.sock</code><br>Watchtower 需要通过 Docker 的 Unix Socket 与 Docker Daemon 通信，从而管理和重启其他容器。</li>



<li><code>/root/.docker/:/config/</code><br>挂载主机上的 Docker 配置目录，便于 Watchtower 使用 Docker 配置（如私有仓库认证信息等）。</li>
</ul>



<h3 class="wp-block-heading">4. 环境变量</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="environment:
  - DOCKER_CONFIG=/config" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">environment</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">  - </span><span style="color: #CE9178">DOCKER_CONFIG=/config</span></span></code></pre></div>



<p class="wp-block-paragraph">指定 Docker 配置的路径为 <code>/config</code>，即上面挂载的 <code>/root/.docker/</code>。</p>



<h3 class="wp-block-heading">5. 启动命令</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="command: --cleanup --interval 60 tuechpresentation-api-1" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">command</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">--cleanup --interval 60 tuechpresentation-api-1</span></span></code></pre></div>



<ul class="wp-block-list">
<li><code>--cleanup</code><br>更新后自动删除旧的无用镜像，节省磁盘空间。</li>



<li><code>--interval 60</code><br>每 60 秒检查一次镜像是否有更新。</li>



<li><code>tuechpresentation-api-1</code><br>只监控名为 <code>tuechpresentation-api-1</code> 的容器，不会影响其他容器的运行和更新。</li>
</ul>



<p class="wp-block-paragraph">这样配置后，Watchtower 只会自动更新指定的 API 容器，非常适合只希望自动维护某个服务的场景。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">使用建议</h2>



<ul class="wp-block-list">
<li><strong>安全性</strong>：挂载 Docker Socket 具有一定风险，建议只在可信环境下使用。</li>



<li><strong>精细化控制</strong>：通过在 command 部分指定容器名，可以避免 Watchtower 无差别地更新所有容器，更加灵活。</li>



<li><strong>日志查看</strong>：可以通过 <code>docker logs watchtower</code> 查看 Watchtower 的工作日志，了解其自动更新的动态。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">总结</h2>



<p class="wp-block-paragraph">通过在 Docker Compose 中集成 Watchtower，可以实现容器的自动更新，极大降低了运维成本。合理配置后，还能做到只更新指定容器，安全高效。你可以根据自己的实际需求调整监控容器的范围和更新频率，让你的 Docker 环境始终保持最新和安全。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>游戏开发学习笔记-NPC的AI开发</title>
		<link>https://blog.mutadecheng.com/2026/01/07/%e6%b8%b8%e6%88%8f%e5%bc%80%e5%8f%91%e5%ad%a6%e4%b9%a0%e7%ac%94%e8%ae%b0-npc%e7%9a%84ai%e5%bc%80%e5%8f%91/</link>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Wed, 07 Jan 2026 05:56:59 +0000</pubDate>
				<category><![CDATA[游戏开发]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=669</guid>

					<description><![CDATA[在游戏开发中，NPC（非玩家角色）的智能行为设计十分重要。不同的AI开发方式适用于不同复杂度和类型的NPC。本 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">在游戏开发中，NPC（非玩家角色）的智能行为设计十分重要。不同的AI开发方式适用于不同复杂度和类型的NPC。本篇详细介绍主流的NPC AI开发方法，并配有树状图示例，帮助初学者轻松理解。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">一、有限状态机（FSM，Finite State Machine）</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph">有限状态机是一种把NPC行为分成几个“状态”的设计方式，比如“巡逻”、“攻击”、“逃跑”等。NPC任意时刻只会处于某一个状态，满足条件才会切换到其他状态。</p>



<h3 class="wp-block-heading">2. 原理</h3>



<ul class="wp-block-list">
<li><strong>状态</strong>：NPC所处的行为阶段。</li>



<li><strong>切换条件</strong>：决定何时从一个状态跳转到另一个状态。</li>



<li><strong>每个状态的具体行为</strong>：比如巡逻状态下，NPC会在场景中来回走动。</li>
</ul>



<h3 class="wp-block-heading">3. 树图示例</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="巡逻
└─ 发现敌人? 是 → 追击敌人
    └─ 距离很近? 是 → 攻击敌人
        └─ 血量很低? 是 → 逃跑" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">巡逻</span></span>
<span class="line"><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">发现敌人?</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">追击敌人</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">距离很近?</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">攻击敌人</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">血量很低?</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">逃跑</span></span></code></pre></div>



<h3 class="wp-block-heading">4. 讲解</h3>



<p class="wp-block-paragraph">比如一个警卫巡逻，发现敌人就追击，靠近了就攻击，受伤严重就逃跑。每个行为就是一个“状态”，切换条件清晰简单，非常适合新手入门和简单AI。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">二、决策树（Decision Tree）</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph">决策树就像一系列嵌套的“如果……那么……”的判断题。NPC会沿着判断条件，一步步选择最终要做的事情。</p>



<h3 class="wp-block-heading">2. 原理</h3>



<ul class="wp-block-list">
<li>每一层是一个判断问题。</li>



<li>满足条件就继续往下判断，直到找到适合当前情况的行为。</li>
</ul>



<h3 class="wp-block-heading">3. 树图示例</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="发现敌人?
├─ 是
│   └─ 距离近?
│       ├─ 是 → 攻击
│       └─ 否 → 追击
└─ 否 → 巡逻" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">发现敌人?</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">距离近?</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">       </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">攻击</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">       </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">否</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">追击</span></span>
<span class="line"><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">否</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">巡逻</span></span></code></pre></div>



<h3 class="wp-block-heading">4. 讲解</h3>



<p class="wp-block-paragraph">比如NPC先问自己“看到敌人了吗？”如果看到，再问“敌人近吗？”，如果近就攻击，不近就追。如果没看到，就继续巡逻。适合逻辑不复杂的NPC。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">三、行为树（Behavior Tree）</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph">行为树是一种模块化的设计，把复杂行为拆解成一个个“小动作”，再像拼积木一样组合起来。每个“树枝”表示一个决策流程，叶子节点是具体动作。</p>



<h3 class="wp-block-heading">2. 原理</h3>



<ul class="wp-block-list">
<li>从根节点出发，按顺序或优先级检查每个子节点。</li>



<li>组合复杂行为，比如“先做A，如果不行再做B”。</li>



<li>节点可以复用，易于扩展。</li>
</ul>



<h3 class="wp-block-heading">3. 树图示例</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="选择器
├─ 行为1：发现敌人?
│   └─ 是 → 顺序器
│       ├─ 面向敌人
│       ├─ 接近敌人
│       └─ 攻击敌人
├─ 行为2：血量低?
│   └─ 是 → 寻找掩体
└─ 行为3：巡逻" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">选择器</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">行为1：发现敌人?</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">顺序器</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">       </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">面向敌人</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">       </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">接近敌人</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">       </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">攻击敌人</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">行为2：血量低?</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">寻找掩体</span></span>
<span class="line"><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">行为3：巡逻</span></span></code></pre></div>



<h3 class="wp-block-heading">4. 讲解</h3>



<p class="wp-block-paragraph">行为树就像一个智能化的流程表，先判断优先级高的事（比如有敌人就先攻击），否则做次要的事（比如巡逻）。树的结构让每个行为都能灵活组合，非常适合复杂NPC。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">四、GOAP（目标导向动作规划，Goal-Oriented Action Planning）</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph">GOAP不是提前写好所有流程，而是让NPC根据“目标”动态规划怎么做。比如目标是“活下来”，NPC会自动选择“找药包”“找掩体”等步骤。</p>



<h3 class="wp-block-heading">2. 原理</h3>



<ul class="wp-block-list">
<li>给NPC设定多个目标，如“消灭敌人”“保持安全”。</li>



<li>每个动作有“前提条件”和“结果”。</li>



<li>NPC根据当前情况，自动规划一系列动作达成目标。</li>
</ul>



<h3 class="wp-block-heading">3. 树图示例（目标：消灭敌人）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="目标：消灭敌人
├─ 需要武器?
│   └─ 是 → 去找武器
├─ 有武器 → 靠近敌人
└─ 接近后 → 攻击敌人" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">目标：消灭敌人</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">需要武器?</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">是</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">去找武器</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">有武器</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">靠近敌人</span></span>
<span class="line"><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">接近后</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">攻击敌人</span></span></code></pre></div>



<h3 class="wp-block-heading">4. 讲解</h3>



<p class="wp-block-paragraph">比如NPC没有武器，就会先去找武器；有了武器后再去接近敌人，最后攻击。GOAP让NPC像“思考”一样，灵活应对不同情况，行为更智能。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">五、黑板系统（Blackboard System）</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph">黑板系统是一个信息共享平台，NPC的各个模块（比如感知、决策、行动）都可以在黑板上读写信息，实现协同。</p>



<h3 class="wp-block-heading">2. 原理</h3>



<ul class="wp-block-list">
<li>黑板就像一个公告栏，大家都能看到。</li>



<li>感知模块发现敌人后，把信息写到黑板上。</li>



<li>行为模块读取这些信息，决定要做什么。</li>
</ul>



<h3 class="wp-block-heading">3. 树图示例</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="黑板
├─ 发现敌人 → 决策模块读取 → 切换到攻击状态
├─ 发现血包 → 决策模块读取 → 前往拾取
└─ 其他信息" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">黑板</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">发现敌人</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">决策模块读取</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">切换到攻击状态</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">发现血包</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">决策模块读取</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">前往拾取</span></span>
<span class="line"><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">其他信息</span></span></code></pre></div>



<h3 class="wp-block-heading">4. 讲解</h3>



<p class="wp-block-paragraph">黑板让NPC的不同部分可以互相沟通，比如“感知”发现敌人，“决策”模块就能知道要攻击。这种方式多用于复杂AI系统。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">六、基于规则的系统（Rule-based System）</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph">基于规则的系统，就是提前写好一堆“如果……那么……”的规则，NPC遇到情况就一条条检查，满足条件就执行相应行为。</p>



<h3 class="wp-block-heading">2. 原理</h3>



<ul class="wp-block-list">
<li>规则库里存着各种条件和结果。</li>



<li>NPC不断检查当前所有规则，执行最先匹配的行为。</li>
</ul>



<h3 class="wp-block-heading">3. 树图示例</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="规则库
├─ 如果血量低 → 寻找医疗包
├─ 如果敌人靠近 → 攻击
└─ 否则 → 巡逻" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">规则库</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">如果血量低</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">寻找医疗包</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">如果敌人靠近</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">攻击</span></span>
<span class="line"><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">否则</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">巡逻</span></span></code></pre></div>



<h3 class="wp-block-heading">4. 讲解</h3>



<p class="wp-block-paragraph">比如“如果血量低，去找药包；如果敌人靠近，先攻击”。适合简单或者中等复杂度的AI，但规则多了后管理会变复杂。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">七、机器学习/深度学习方法</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph">机器学习让NPC通过“学习”来变得更聪明，比如通过反复试错，自动学会最佳行为。</p>



<h3 class="wp-block-heading">2. 原理</h3>



<ul class="wp-block-list">
<li>通过大量训练，AI模型掌握在不同情况下的最佳反应。</li>



<li>强化学习：NPC每做一次选择，都会得到奖励或惩罚，通过不断尝试，学会最优策略。</li>
</ul>



<h3 class="wp-block-heading">3. 树图示例（简化思路）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="环境反馈
├─ 尝试动作A → 得到奖励 → 增强动作A
├─ 尝试动作B → 得到惩罚 → 减少动作B
└─ 反复迭代 → 学习到最佳行为" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">环境反馈</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">尝试动作A</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">得到奖励</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">增强动作A</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">尝试动作B</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">得到惩罚</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">减少动作B</span></span>
<span class="line"><span style="color: #DCDCAA">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">反复迭代</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">→</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">学习到最佳行为</span></span></code></pre></div>



<h3 class="wp-block-heading">4. 讲解</h3>



<p class="wp-block-paragraph">比如NPC在模拟环境里尝试“攻击”“逃跑”“躲避”，每次尝试后都通过奖励机制调整行为，最终学会如何做得最好。这种方法适合做高智能NPC，但开发和训练成本高。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">八、基于大语言模型的生成式智能体架构（以斯坦福AI小人虚拟小镇为例）</h2>



<h3 class="wp-block-heading">1. 概念</h3>



<p class="wp-block-paragraph"><strong>生成式智能体</strong>（Generative Agent）是一种借助大语言模型（如GPT）作为“智能大脑”，结合记忆、检索、反思、计划等模块，模拟出高度拟人的行为和交互。其典型代表是斯坦福大学提出的“AI小人虚拟小镇”，在开源社区（如a16z重写版）得到了广泛应用。</p>



<p class="wp-block-paragraph">传统AI方法如有限状态机、行为树、GOAP等，行为多为“脚本化”或“规则化”。生成式智能体则通过自然语言驱动行为，能够自我进化、动态适应环境，表现出类似人类的复杂行为。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 技术架构与整体思路</h3>



<h4 class="wp-block-heading">2.1 架构树状图</h4>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="生成式智能体架构
├─ 记忆流（Memory Stream）
│   ├─ 观察（Observations）
│   ├─ 反思（Reflections）
│   └─ 计划（Plans）
├─ 检索机制（Retrieval）
│   ├─ 近因性
│   ├─ 重要性
│   └─ 相关性（向量数据库）
├─ 反思机制（Reflection）
│   └─ 抽象/推理（生成反思树）
├─ 计划与反应（Planning &amp; Reaction）
│   ├─ 高层计划
│   └─ 递归细化
├─ 行为生成（Action Generation）
│   ├─ 环境互动
│   └─ 代理对话
├─ 用户交互
│   └─ 用户输入（自然语言）
├─ 外部支持系统
│   ├─ 游戏引擎、数据库
│   ├─ 向量数据库
│   ├─ 文字生成模型（LLM）
│   └─ 像素图生成等" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">生成式智能体架构</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">记忆流（Memory</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">Stream）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">观察（Observations）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">反思（Reflections）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">计划（Plans）</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">检索机制（Retrieval）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">近因性</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">重要性</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">相关性（向量数据库）</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">反思机制（Reflection）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">抽象/推理（生成反思树）</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">计划与反应（Planning</span><span style="color: #D4D4D4"> &amp; </span><span style="color: #DCDCAA">Reaction）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">高层计划</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">递归细化</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">行为生成（Action</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">Generation）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">环境互动</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">代理对话</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">用户交互</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">用户输入（自然语言）</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">外部支持系统</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">游戏引擎、数据库</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">向量数据库</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">文字生成模型（LLM）</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">像素图生成等</span></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h4 class="wp-block-heading">2.2 架构详细讲解</h4>



<p class="wp-block-paragraph"><strong>A. 记忆流（Memory Stream）</strong></p>



<ul class="wp-block-list">
<li>每个智能体都有自己的“记忆数据库”，记录着所有经历过的事件、对话、计划、反思等。</li>



<li>记忆以自然语言形式存储，包含时间戳和访问时间，既有“观测”也有“抽象反思”。</li>



<li>例如：AI小人“伊莎贝拉”会记得“今天早上在厨房遇到朋友做早餐”。</li>
</ul>



<p class="wp-block-paragraph"><strong>B. 检索机制（Retrieval）</strong></p>



<ul class="wp-block-list">
<li>智能体需要从大量记忆中检索出“当前最相关”的记忆，指导当下行为。</li>



<li>检索包括三大指标：
<ul class="wp-block-list">
<li><strong>近因性</strong>：越新发生的事件，分数越高。</li>



<li><strong>重要性</strong>：事件越重要，分数越高（如“分手”比“刷牙”重要）。</li>



<li><strong>相关性</strong>：用向量数据库（如Pinecone）计算与当前情境的相似度。</li>
</ul>
</li>



<li>例如，AI小人要决定是否去见某人，会回忆最近有关此人的经历和情感。</li>
</ul>



<p class="wp-block-paragraph"><strong>C. 反思机制（Reflection）</strong></p>



<ul class="wp-block-list">
<li>不只是被动记忆，还会主动“总结归纳”，形成“反思”。</li>



<li>反思是对多个相关记忆的抽象，比如“我和朋友的关系变得更亲密了”。</li>



<li>反思会形成“树状结构”，叶节点是具体事件，高层节点是抽象见解。</li>



<li>反思周期性发生，重要事件累积到阈值时触发。</li>
</ul>



<p class="wp-block-paragraph"><strong>D. 计划与反应（Planning &amp; Reaction）</strong></p>



<ul class="wp-block-list">
<li>智能体会制定自己的“日程计划”，比如“早上做早餐、上午去公园、下午工作”。</li>



<li>计划可以递归细化成更小的行动步骤，并随时根据环境变化做出调整。</li>



<li>每当环境或其他智能体行为发生变化，计划会实时更新。</li>
</ul>



<p class="wp-block-paragraph"><strong>E. 行为生成（Action Generation）</strong></p>



<ul class="wp-block-list">
<li>智能体的每一步行为由大语言模型（如GPT）生成，行为描述为自然语言，并映射到具体动作。</li>



<li>智能体之间的对话、与环境的交互都通过自然语言描述和解释。</li>
</ul>



<p class="wp-block-paragraph"><strong>F. 用户交互</strong></p>



<ul class="wp-block-list">
<li>用户可以通过自然语言输入影响智能体（如指派任务、修改属性）。</li>



<li>用户也可以“化身”进入虚拟小镇，成为其中一员。</li>
</ul>



<p class="wp-block-paragraph"><strong>G. 外部支持系统</strong></p>



<ul class="wp-block-list">
<li>游戏引擎（Convex）、数据库、向量数据库（Pinecone）、文字生成模型（OpenAI）、像素图生成（Replicate/Fal.ai）等，构成整个技术栈的基础设施。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 与传统AI方法的对比</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>传统方法</th><th>特点</th><th>生成式智能体</th></tr></thead><tbody><tr><td>有限状态机、行为树、GOAP等</td><td>规则/脚本驱动，行为固定，扩展性差</td><td>记忆驱动，行为高度拟人，动态自适应</td></tr><tr><td>规则系统</td><td>依赖开发者预设规则</td><td>通过大语言模型自动推理与规划</td></tr><tr><td>强化学习</td><td>需大量训练，适应性有限</td><td>通过记忆、环境、反思即时适应新情境</td></tr><tr><td>机器学习</td><td>难以解释、训练成本高</td><td>LLM强提示+外逻辑架构，易于扩展</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 生成式智能体的创新点</h3>



<ul class="wp-block-list">
<li><strong>内逻辑与外逻辑结合</strong>：大语言模型负责“想”，外部系统负责“管”数据和操作。</li>



<li><strong>记忆驱动行为</strong>：不再依赖死板脚本，行为由“记忆-检索-反思-计划”动态生成。</li>



<li><strong>行为高度拟人</strong>：能模拟人类的长期记忆、情感变化、临场反应、社会互动。</li>



<li><strong>自进化能力</strong>：环境或用户输入变化时，智能体能自动适应，无需修改代码。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5. 示例：AI小人的一天（树状图）</h3>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="伊莎贝拉的一天
├─ 记忆流
│   ├─ 早上做早餐
│   ├─ 与朋友聊天
│   ├─ 计划去公园
│   └─ 下午工作
├─ 检索
│   ├─ 最近与朋友的对话
│   └─ 上次工作时的反思
├─ 反思
│   ├─ 今天与朋友关系更亲密
│   └─ 工作效率提升
├─ 计划
│   ├─ 上午：社交
│   └─ 下午：工作
├─ 行为
│   ├─ 与朋友互动
│   └─ 执行工作任务" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #DCDCAA">伊莎贝拉的一天</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">记忆流</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">早上做早餐</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">与朋友聊天</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">计划去公园</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">下午工作</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">检索</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">最近与朋友的对话</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">上次工作时的反思</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">反思</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">今天与朋友关系更亲密</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">工作效率提升</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">计划</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">上午：社交</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">下午：工作</span></span>
<span class="line"><span style="color: #DCDCAA">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">行为</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">├─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">与朋友互动</span></span>
<span class="line"><span style="color: #DCDCAA">│</span><span style="color: #D4D4D4">   </span><span style="color: #CE9178">└─</span><span style="color: #D4D4D4"> </span><span style="color: #CE9178">执行工作任务</span></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">这些行为全自动生成，AI小人会根据记忆和环境调整自己的计划和反应。</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">6. 适用场景与未来趋势</h3>



<ul class="wp-block-list">
<li><strong>虚拟世界/元宇宙</strong>：高度拟人NPC、虚拟居民。</li>



<li><strong>游戏开发</strong>：复杂剧情与开放世界中的真实NPC行为。</li>



<li><strong>社交/教育/陪伴</strong>：情感丰富、可自我进化的AI伙伴。</li>



<li><strong>智能体系统</strong>：自动化办公、协作机器人等。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">7. 相关资源</h3>



<ul class="wp-block-list">
<li><a href="https://github.com/joonspk-research/generative_agents">项目地址（GitHub）</a></li>



<li><a href="https://arxiv.org/pdf/2304.03442.pdf">论文原文（英文）</a></li>



<li><a href="http://cyberxz.com/aiweb/file/Chinese_GenerativeAgentsInteractiveSimulacraofHumanBehavior.pdf">论文（中文机翻）</a></li>



<li><a href="https://www.convex.dev/ai-town?continueFlag=cd9be6edc56bfb72f6d0dc908d439184">官方演示</a></li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">总结</h2>



<p class="wp-block-paragraph">斯坦福AI小人虚拟小镇项目开启了大语言模型驱动的AI智能体新时代。它打破了传统脚本和规则系统的限制，让AI像“人”一样，有记忆、会反思、能规划、会交流，真正实现了“虚拟居民”的可信模拟。这一架构的理解，对设计下一代AI应用极具参考价值。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>一些想要实现的构思&#8211;厨房设计</title>
		<link>https://blog.mutadecheng.com/2026/01/04/%e4%b8%80%e4%ba%9b%e6%83%b3%e8%a6%81%e5%ae%9e%e7%8e%b0%e7%9a%84%e6%9e%84%e6%80%9d/</link>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Sun, 04 Jan 2026 10:37:06 +0000</pubDate>
				<category><![CDATA[设计构思]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=659</guid>

					<description><![CDATA[这是用来展示我构思, 啊 当然现在这里啥都没有 那 玩一下鸭子吧]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">这是用来展示我构思,</p>



<p class="wp-block-paragraph">啊</p>



<p class="wp-block-paragraph">当然现在这里啥都没有</p>



<p class="wp-block-paragraph">那</p>



<p class="wp-block-paragraph">玩一下鸭子吧</p>



<!-- 引入 model-viewer 组件 -->
<script type="module" src="https://unpkg.com/@google/model-viewer/dist/model-viewer.min.js"></script>

<!-- 3D模型展示 -->
<model-viewer
  src="https://blog.mutadecheng.com/wp-content/uploads/2026/01/Duck.glb"
  alt="Duck 3D模型"
  auto-rotate
  camera-controls
  ar
  style="width: 500px; height: 400px; background: white; border-radius: 10px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); display: block; margin: 40px auto;"
></model-viewer>




<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>工作记录&#8211;振动MQTT接收与处理</title>
		<link>https://blog.mutadecheng.com/2026/01/04/%e5%b7%a5%e4%bd%9c%e8%ae%b0%e5%bd%95-%e6%8c%af%e5%8a%a8mqtt%e6%8e%a5%e6%94%b6%e4%b8%8e%e5%a4%84%e7%90%86/</link>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Sun, 04 Jan 2026 08:56:23 +0000</pubDate>
				<category><![CDATA[工作记录]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=650</guid>

					<description><![CDATA[]]></description>
										<content:encoded><![CDATA[
<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#1E1E1E"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="version: '3.8'

services:  
  emqx:
    image: registry.cn-beijing.aliyuncs.com/muta/emqx:amd64
    restart: always
    container_name: emqx
    ports:
      - &quot;1883:1883&quot;   # MQTT 协议端口
      - &quot;8083:8083&quot;   # WebSocket 端口
      - &quot;8084:8084&quot;   # WebSocket(SSL) 端口
      - &quot;18083:18083&quot; # 管理后台端口
    logging:
      driver: &quot;json-file&quot;
      options:
        max-size: &quot;100m&quot;
        max-file: &quot;3&quot;

  rabbitmq:
    image: registry.cn-beijing.aliyuncs.com/muta/rabbitmq:management-amd64
    restart: always
    container_name: rabbitmq
    ports:
      - &quot;5672:5672&quot;   # AMQP 协议端口
      - &quot;15672:15672&quot; # 管理页面端口
    environment:
      RABBITMQ_DEFAULT_USER: admin
      RABBITMQ_DEFAULT_PASS: admin123
    logging:
      driver: &quot;json-file&quot;
      options:
        max-size: &quot;100m&quot;
        max-file: &quot;3&quot;

  mqtt2rabbitmq:
    image: registry.cn-beijing.aliyuncs.com/dfzh/mqtt2rabbitmq:latest
    restart: always
    container_name: mqtt2rabbitmq
    environment:
      RabbitMQ__Hostname: rabbitmq
      RabbitMQ__Username: admin
      RabbitMQ__Password: admin123
      RabbitMQ__QueueName: Sensor 
      MQTT__Broker: emqx
      MQTT__Topic: /dev/luna/# 
    logging:
      driver: &quot;json-file&quot;
      options:
        max-size: &quot;100m&quot;
        max-file: &quot;3&quot;

  rabbitmqvbrationwebapi:
    image: registry.cn-beijing.aliyuncs.com/dfzh/rabbitmqvibrationwebapi:latest
    restart: always
    container_name: rabbitmqvbrationwebapi
    ports:
      - &quot;8222:5759&quot;   
    volumes:
      - /home/HisDatas:/app/HisDatas
    environment:
      RabbitMQ__Hostname: rabbitmq
      RABBITMQ__Port: 5672
      RabbitMQ__Username: admin
      RabbitMQ__Password: admin123
      RabbitMQ__QueueName: vibhex  
      RABBITMQ__ProductionEnvironment: true
    logging:
      driver: &quot;json-file&quot;
      options:
        max-size: &quot;100m&quot;
        max-file: &quot;3&quot;
" style="color:#D4D4D4;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki dark-plus" style="background-color: #1E1E1E" tabindex="0"><code><span class="line"><span style="color: #569CD6">version</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&#39;3.8&#39;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #569CD6">services</span><span style="color: #D4D4D4">:  </span></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">emqx</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">image</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">registry.cn-beijing.aliyuncs.com/muta/emqx:amd64</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">restart</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">always</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">container_name</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">emqx</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">ports</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;1883:1883&quot;</span><span style="color: #D4D4D4">   </span><span style="color: #6A9955"># MQTT 协议端口</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;8083:8083&quot;</span><span style="color: #D4D4D4">   </span><span style="color: #6A9955"># WebSocket 端口</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;8084:8084&quot;</span><span style="color: #D4D4D4">   </span><span style="color: #6A9955"># WebSocket(SSL) 端口</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;18083:18083&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># 管理后台端口</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">logging</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">driver</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;json-file&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">options</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-size</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;100m&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-file</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;3&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">rabbitmq</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">image</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">registry.cn-beijing.aliyuncs.com/muta/rabbitmq:management-amd64</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">restart</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">always</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">container_name</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">rabbitmq</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">ports</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;5672:5672&quot;</span><span style="color: #D4D4D4">   </span><span style="color: #6A9955"># AMQP 协议端口</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;15672:15672&quot;</span><span style="color: #D4D4D4"> </span><span style="color: #6A9955"># 管理页面端口</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">environment</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RABBITMQ_DEFAULT_USER</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">admin</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RABBITMQ_DEFAULT_PASS</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">admin123</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">logging</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">driver</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;json-file&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">options</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-size</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;100m&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-file</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;3&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">mqtt2rabbitmq</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">image</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">registry.cn-beijing.aliyuncs.com/dfzh/mqtt2rabbitmq:latest</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">restart</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">always</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">container_name</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">mqtt2rabbitmq</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">environment</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__Hostname</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">rabbitmq</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__Username</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">admin</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__Password</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">admin123</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__QueueName</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">Sensor</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">MQTT__Broker</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">emqx</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">MQTT__Topic</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">/dev/luna/#</span><span style="color: #D4D4D4"> </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">logging</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">driver</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;json-file&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">options</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-size</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;100m&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-file</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;3&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D4D4D4">  </span><span style="color: #569CD6">rabbitmqvbrationwebapi</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">image</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">registry.cn-beijing.aliyuncs.com/dfzh/rabbitmqvibrationwebapi:latest</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">restart</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">always</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">container_name</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">rabbitmqvbrationwebapi</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">ports</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">&quot;8222:5759&quot;</span><span style="color: #D4D4D4">   </span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">volumes</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      - </span><span style="color: #CE9178">/home/HisDatas:/app/HisDatas</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">environment</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__Hostname</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">rabbitmq</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RABBITMQ__Port</span><span style="color: #D4D4D4">: </span><span style="color: #B5CEA8">5672</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__Username</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">admin</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__Password</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">admin123</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RabbitMQ__QueueName</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">vibhex</span><span style="color: #D4D4D4">  </span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">RABBITMQ__ProductionEnvironment</span><span style="color: #D4D4D4">: </span><span style="color: #569CD6">true</span></span>
<span class="line"><span style="color: #D4D4D4">    </span><span style="color: #569CD6">logging</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">driver</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;json-file&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">      </span><span style="color: #569CD6">options</span><span style="color: #D4D4D4">:</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-size</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;100m&quot;</span></span>
<span class="line"><span style="color: #D4D4D4">        </span><span style="color: #569CD6">max-file</span><span style="color: #D4D4D4">: </span><span style="color: #CE9178">&quot;3&quot;</span></span>
<span class="line"></span></code></pre></div>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>浅谈视觉运动检测中光流法和帧差法</title>
		<link>https://blog.mutadecheng.com/2025/12/30/%e6%b5%85%e8%b0%88%e8%a7%86%e8%a7%89%e8%bf%90%e5%8a%a8%e6%a3%80%e6%b5%8b%e4%b8%ad%e5%85%89%e6%b5%81%e6%b3%95%e5%92%8c%e5%b8%a7%e5%b7%ae%e6%b3%95/</link>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Tue, 30 Dec 2025 01:05:16 +0000</pubDate>
				<category><![CDATA[未分类]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=646</guid>

					<description><![CDATA[光流法和帧差法都是视频图像处理领域常用的运动检测/分析方法，但它们的原理、输出和适用场景有明显区别。下面详细对 [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">光流法和帧差法都是视频图像处理领域常用的运动检测/分析方法，但它们的原理、输出和适用场景有明显区别。下面详细对比说明：</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">1. 原理区别</h3>



<p class="wp-block-paragraph"><strong>帧差法（Frame Difference）</strong></p>



<ul class="wp-block-list">
<li><strong>基本思想</strong>：直接对连续两帧图像的像素灰度值做差分，若差值大于阈值，则判定为运动区域。</li>



<li><strong>输出结果</strong>：主要得到运动的“掩膜”或“区域”，即哪个像素发生了变化。</li>



<li><strong>适用场景</strong>：简单的运动检测和目标分割。</li>
</ul>



<p class="wp-block-paragraph"><strong>光流法（Optical Flow）</strong></p>



<ul class="wp-block-list">
<li><strong>基本思想</strong>：基于亮度一致性假设，通过分析连续帧间像素灰度分布的变化，估计每个像素的速度矢量（即运动方向和幅度）。</li>



<li><strong>输出结果</strong>：每个像素的运动矢量场（速度场），可进一步分析位移、速度、振动等物理量。</li>



<li><strong>适用场景</strong>：需要精确估计物体运动、结构振动、速度场、位移场等场景。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">2. 结果对比</h3>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>方法</th><th>输出类型</th><th>能否得出运动方向</th><th>能否得出运动幅值</th><th>适用场景</th></tr></thead><tbody><tr><td>帧差法</td><td>二值/灰度掩膜</td><td>否</td><td>否</td><td>运动检测、目标分割</td></tr><tr><td>光流法</td><td>运动矢量场</td><td>是</td><td>是</td><td>振动分析、速度估计、模态识别</td></tr></tbody></table></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">3. 优缺点对比</h3>



<p class="wp-block-paragraph"><strong>帧差法：</strong></p>



<ul class="wp-block-list">
<li><strong>优点</strong>：实现简单，计算速度快，适合实时检测。</li>



<li><strong>缺点</strong>：只能检测运动区域，无法准确估计运动的方向和幅度，易受光照变化影响，对微小运动不敏感。</li>
</ul>



<p class="wp-block-paragraph"><strong>光流法：</strong></p>



<ul class="wp-block-list">
<li><strong>优点</strong>：可获得像素级别的运动方向和幅度信息，适合微小运动（如结构振动、模态识别、运动放大）。</li>



<li><strong>缺点</strong>：计算复杂度高，对噪声和光照变化较敏感，需较好的视频质量。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">4. 应用举例</h3>



<ul class="wp-block-list">
<li><strong>帧差法</strong>：适合用于安防监控中检测是否有物体进入画面，或简单的运动目标检测。</li>



<li><strong>光流法</strong>：适合用于结构健康监测、桥梁/建筑物振动检测、模态参数识别、运动放大等需要高精度运动分析的场景。</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">5. 总结</h3>



<p class="wp-block-paragraph"><strong>帧差法</strong>更偏向于“有没有运动”的检测，而<strong>光流法</strong>则能“量化运动”，包括运动的方向和幅度。在结构振动、模态识别、运动放大等需要定量分析运动的场景，光流法明显优于帧差法。</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Portainer 基础知识</title>
		<link>https://blog.mutadecheng.com/2025/12/29/portainer-%e5%9f%ba%e7%a1%80%e7%9f%a5%e8%af%86/</link>
		
		<dc:creator><![CDATA[木它]]></dc:creator>
		<pubDate>Mon, 29 Dec 2025 03:48:11 +0000</pubDate>
				<category><![CDATA[Docker]]></category>
		<guid isPermaLink="false">https://blog.mutadecheng.com/?p=644</guid>

					<description><![CDATA[Portainer 入门详解教程 —— 用安卓应用商店类比，帮助初学者轻松理解 前言 对于很多初学者来说，Po [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Portainer 入门详解教程 —— 用安卓应用商店类比，帮助初学者轻松理解</p>



<p class="wp-block-paragraph">前言</p>



<p class="wp-block-paragraph">        对于很多初学者来说，Portainer 这个工具可能比较陌生。其实，Portainer 的作用和安卓手机上的“应用商店”非常类似。应用商店让我们方便地安装、管理和卸载各种手机应用，而 Portainer 则让我们在服务器上用可视化方式管理 Docker 容器（各种服务器应用）。本教程将用详细的类比和表格，帮助初学者快速理解 Portainer 的各项功能和实际操作细节。</p>



<p class="wp-block-paragraph">一、Portainer 与安卓应用商店功能对照表</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>功能/场景</th><th>Portainer 细节说明</th><th>安卓应用商店细节说明</th></tr></thead><tbody><tr><td>管理对象</td><td>管理服务器上的 Docker 容器和镜像，包括应用、数据库等</td><td>管理手机上的各类应用</td></tr><tr><td>安装方式</td><td>需要先安装 Docker，然后通过命令或图形界面部署 Portainer</td><td>手机厂商预装或用户下载应用商店</td></tr><tr><td>应用安装</td><td>选择镜像或模板，填写参数，设置端口、存储路径等，点击部署</td><td>搜索应用，确认权限，点击安装</td></tr><tr><td>应用卸载</td><td>停止并删除容器，必要时清理相关数据和镜像</td><td>长按应用图标或在应用商店中卸载</td></tr><tr><td>应用启动/停止</td><td>选择容器，点击启动或停止，支持一键操作</td><td>点击应用图标打开或关闭</td></tr><tr><td>更新应用</td><td>拉取新镜像，重新部署容器，注意数据备份和兼容性</td><td>应用商店提示更新，点击升级</td></tr><tr><td>查看日志</td><td>进入容器详情页，查看实时日志，支持过滤和搜索错误信息</td><td>开发者选项或应用详情中查看崩溃日志</td></tr><tr><td>权限管理</td><td>支持多用户登录，分配不同角色和权限，适合团队协作</td><td>账号管理，家长控制、隐私权限设置</td></tr><tr><td>应用分类</td><td>分类展示常用服务类型，如数据库、内容管理、工具等</td><td>社交、游戏、工具等应用分类</td></tr><tr><td>多平台管理</td><td>可同时管理本地和远程服务器上的容器，适合多台设备场景</td><td>多台手机或平板统一管理应用</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">二、Portainer 安装与初次使用细节</p>



<ol class="wp-block-list">
<li>安装 Docker</li>
</ol>



<ul class="wp-block-list">
<li>Portainer 依赖 Docker 环境，需先在服务器上安装好 Docker。类似于安卓系统必须先准备好，才能安装应用商店。</li>



<li>初学者推荐在干净的服务器或虚拟机上操作，避免环境冲突。</li>
</ul>



<ol class="wp-block-list">
<li>部署 Portainer</li>
</ol>



<ul class="wp-block-list">
<li>Portainer 本身也是一个容器应用。部署后，会自动生成管理界面，通常通过浏览器访问。</li>



<li>访问方式为：http://服务器IP:9000，首次进入需要设置管理员账号和密码，确保安全性。</li>
</ul>



<ol class="wp-block-list">
<li>首次登录</li>
</ol>



<ul class="wp-block-list">
<li>建议初学者使用强密码，并妥善保存账号信息。</li>



<li>登录后会看到主界面，包括管理节点、容器、镜像、网络、卷等模块。</li>
</ul>



<p class="wp-block-paragraph">三、Portainer 图形界面与应用商店界面细节对比</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>Portainer 页面</th><th>安卓应用商店页面</th><th>细节说明</th></tr></thead><tbody><tr><td>首页（Home）</td><td>推荐页/首页</td><td>展示所有已管理的环境和服务，快速入口</td></tr><tr><td>容器列表（Containers）</td><td>已安装应用列表</td><td>展示已安装和运行的所有容器，支持筛选、排序、批量操作</td></tr><tr><td>镜像库（Images）</td><td>应用市场库</td><td>展示可用的容器镜像，相当于应用安装包，可手动拉取或删除</td></tr><tr><td>应用模板（App Templates）</td><td>精品推荐/分类应用</td><td>一键部署常用服务，内置参数简化部署流程，适合初学者</td></tr><tr><td>日志（Logs）</td><td>应用详情/崩溃日志</td><td>实时展示容器输出和运行日志，支持搜索错误信息</td></tr><tr><td>用户与权限（Users）</td><td>账号/家长控制</td><td>添加和管理不同用户，分配管理权限，适合多人协作</td></tr><tr><td>设置（Settings）</td><td>应用商店设置</td><td>配置 Portainer 的基本参数，包括界面语言、通知等</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">四、典型操作场景细节讲解</p>



<ol class="wp-block-list">
<li>安装新容器服务（如 WordPress 网站）</li>
</ol>



<ul class="wp-block-list">
<li>在应用模板中找到 WordPress，点击部署。</li>



<li>细致填写数据库密码、端口号等参数，确认后即可自动完成安装。</li>



<li>部署后自动跳转到容器列表，可一键启动、停止或重启服务。</li>



<li>类似于在应用商店中搜索微信，点击安装，填写账号信息后即可使用。</li>
</ul>



<ol class="wp-block-list">
<li>启动或停止容器</li>
</ol>



<ul class="wp-block-list">
<li>容器列表中，每个容器都有启动、停止、重启按钮。</li>



<li>可根据需要灵活操作，适合测试和维护环境。</li>



<li>类比于手机上打开或关闭应用。</li>
</ul>



<ol class="wp-block-list">
<li>卸载容器服务</li>
</ol>



<ul class="wp-block-list">
<li>停止容器后，点击删除即可完成卸载。</li>



<li>建议初学者在删除前备份重要数据（如数据库内容），避免误删。</li>



<li>类似于卸载手机应用时确认是否保留数据。</li>
</ul>



<ol class="wp-block-list">
<li>更新容器应用</li>
</ol>



<ul class="wp-block-list">
<li>检查镜像库是否有新版本，拉取最新镜像后重建容器。</li>



<li>更新前建议备份数据，并确认新版本兼容性。</li>



<li>类比于应用商店提示应用有新版本时，点击升级按钮。</li>
</ul>



<ol class="wp-block-list">
<li>查看容器日志</li>
</ol>



<ul class="wp-block-list">
<li>容器详情页可实时查看运行日志，支持搜索关键字（如“error”、“failed”）。</li>



<li>日志可帮助排查启动失败、配置错误等问题，是运维必备工具。</li>



<li>类似于应用崩溃后查看日志定位问题。</li>
</ul>



<p class="wp-block-paragraph">五、常见问题与细节排查方法</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>问题场景</th><th>Portainer 细节排查方法</th><th>安卓应用商店类比说明</th></tr></thead><tbody><tr><td>容器无法启动</td><td>查看日志，检查端口冲突、环境变量设置、依赖问题</td><td>应用打不开，检查网络或重启手机</td></tr><tr><td>镜像下载慢或失败</td><td>切换国内镜像源，检查网络连接，重试拉取</td><td>应用下载缓慢，切换 Wi-Fi 或移动网络</td></tr><tr><td>权限不足</td><td>检查用户角色，调整权限设置，避免误操作</td><td>家长控制或权限限制导致无法安装应用</td></tr><tr><td>占用资源过多</td><td>停止或删除不常用容器，释放服务器内存和存储空间</td><td>清理不常用应用，释放手机空间</td></tr><tr><td>版本兼容性问题</td><td>查看容器日志，确认 Docker 和镜像版本匹配</td><td>应用不兼容当前系统版本，升级或降级系统</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">六、进阶建议</p>



<ul class="wp-block-list">
<li>初学者可优先使用模板部署常用服务，熟悉参数填写和基本管理流程。</li>



<li>建议定期查看容器日志，及时发现和解决潜在问题。</li>



<li>多用户协作时，合理分配权限，避免误操作影响整个环境。</li>



<li>学习数据卷和网络管理，提高服务的稳定性和安全性。</li>



<li>探索远程节点管理，适合多台服务器或云平台场景。</li>
</ul>



<p class="wp-block-paragraph">结语</p>



<p class="wp-block-paragraph">Portainer 就像服务器世界里的“应用商店”，让初学者无需复杂命令，就能像管理手机应用一样，轻松管理服务器上的各种服务。通过图形界面、详细日志和丰富模板，Portainer 不仅提升了管理效率，也降低了运维门槛。建议初学者在实践中多尝试、多探索，逐步掌握容器化应用的管理技巧。</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
