<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>finch xu</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <icon>https://pidan.dev/images/logo.svg</icon>
  <id>https://pidan.dev/</id>
  <link href="https://pidan.dev/" rel="alternate"/>
  <link href="https://pidan.dev/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, finch xu</rights>
  <subtitle>虚拟世界的懒猫</subtitle>
  <title>虚拟世界的懒猫</title>
  <updated>2026-05-26T14:45:37.888Z</updated>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="cc-router" scheme="https://pidan.dev/tags/cc-router/"/>
    <category term="AI" scheme="https://pidan.dev/tags/AI/"/>
    <category term="Codex" scheme="https://pidan.dev/tags/Codex/"/>
    <category term="OpenAI" scheme="https://pidan.dev/tags/OpenAI/"/>
    <category term="cc-switch" scheme="https://pidan.dev/tags/cc-switch/"/>
    <content>
      <![CDATA[<p>Codex CLI 和 Codex Desktop 默认走 OpenAI 官方账号，但我手里同时有 Claude、DeepSeek、Kimi、GLM 这些订阅，想在 Codex 客户端里直接选用它们 —— 一家一家配 base URL 和 API key 又烦又乱。把 cc-router 当本地代理，再用 cc-switch 作为 Codex 的多供应商切换器，就能把所有上游订阅聚合成三个虚拟槽位（opus&#x2F;sonnet&#x2F;haiku），在 Codex 里用一个 token 调度全部。整条链路六步就能跑通，本文按截图一步步走。</p><span id="more"></span><blockquote><p><strong>项目地址：</strong> <a href="https://github.com/finch-xu/cc-router">GitHub - finch-xu&#x2F;cc-router</a> ｜ <a href="https://github.com/finch-xu/cc-router/releases/latest">下载客户端</a> ｜ <a href="https://ccrouter.app/docs/codex-integration/">官方 Codex 集成文档</a></p><p><strong>cc-switch：</strong> Codex 客户端的多供应商切换器，安装入口见上方官方 Codex 集成文档页</p></blockquote><h2 id="工作架构"><a href="#工作架构" class="headerlink" title="工作架构"></a>工作架构</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Codex CLI / Codex Desktop      cc-switch              cc-router (本地)             上游 Provider</span><br><span class="line">┌──────────────────────┐    ┌──────────────┐       ┌──────────────────┐         ┌────────────┐</span><br><span class="line">│  发起对话             │───▶│ 供应商切换    │──────▶│ :23456 网关       │────────▶│ Claude     │</span><br><span class="line">│  选择虚拟模型         │    │ (cc-router/  │       │ + 虚拟模型路由     │         │ DeepSeek   │</span><br><span class="line">│                      │    │  OpenAI/...) │       │ + 请求日志         │         │ Kimi / GLM │</span><br><span class="line">└──────────────────────┘    └──────────────┘       └──────────────────┘         │ ...        │</span><br><span class="line">                                                                                  └────────────┘</span><br></pre></td></tr></table></figure><p>这条链路里两层职责分得很清：</p><ul><li><strong>cc-switch</strong> 负责”我现在让 Codex 走哪个供应商” —— 在 OpenAI 官方账号、cc-router、其他自定义 OpenAI 兼容端点之间一键切换，配置写入 <code>~/.codex/config.toml</code></li><li><strong>cc-router</strong> 负责”我这条请求最终落到哪家上游” —— 接受 Codex 通过 cc-switch 转过来的 HTTP 请求，按虚拟模型槽位（opus&#x2F;sonnet&#x2F;haiku）路由到具体厂商，并处理限流降级</li></ul><p>也就是说：在 cc-switch 这一步告诉 Codex “请求发到 cc-router 的本地端口”，在 cc-router 这一步告诉它”opus 槽位用 DeepSeek、sonnet 槽位用 Kimi”，二者合在一起就把整个调度链拉通了。</p><h2 id="前置准备"><a href="#前置准备" class="headerlink" title="前置准备"></a>前置准备</h2><ul><li><strong>cc-router</strong> 已安装并至少绑定一个虚拟模型（opus &#x2F; sonnet &#x2F; haiku 任选其一）。还没装的看 <a href="https://ccrouter.app/docs/getting-started/">入门文档</a> 或本博客 cc-router 系列前几篇</li><li><strong>cc-switch</strong> 已安装。下载入口见 <a href="https://ccrouter.app/docs/codex-integration/">官方 Codex 集成文档</a></li><li><strong>Codex CLI 或 Codex Desktop</strong> 至少装好一个，二者配置共享同一份 <code>~/.codex/config.toml</code></li><li>从 cc-router 设置页提前复制好 <strong>API Key</strong>（后面要粘进 cc-switch）</li></ul><hr><h2 id="步骤一：打开-cc-switch，切到-Codex-供应商"><a href="#步骤一：打开-cc-switch，切到-Codex-供应商" class="headerlink" title="步骤一：打开 cc-switch，切到 Codex 供应商"></a>步骤一：打开 cc-switch，切到 Codex 供应商</h2><p>cc-switch 同时管 Claude 和 Codex 两套供应商，第一步先把界面切到 Codex 那一侧。点顶部工具栏的 <strong>Codex 图标</strong>（GPT 标志），下方面板会切换到当前已配置的 Codex 供应商列表 —— 一般这里会有 OpenAI 官方账号（如果之前登录过）。</p><p><img src="/img/cc-router/codex-01-open-cc-switch.png" alt="打开 cc-switch 并切到 Codex 供应商"></p><hr><h2 id="步骤二：新增一个自定义-Codex-供应商"><a href="#步骤二：新增一个自定义-Codex-供应商" class="headerlink" title="步骤二：新增一个自定义 Codex 供应商"></a>步骤二：新增一个自定义 Codex 供应商</h2><p>cc-router 不在 cc-switch 内置厂商列表里，需要走”自定义配置”入口手动添加。</p><p>点右上角的 <strong>橙色 + 号</strong> 按钮 → 保持在「Codex 供应商」标签页 → 选左上角第一个蓝色 tile <strong>「自定义配置」</strong>。</p><p><img src="/img/cc-router/codex-02-add-custom-provider.png" alt="新增自定义 Codex 供应商"></p><hr><h2 id="步骤三：填写-cc-router-的接口信息"><a href="#步骤三：填写-cc-router-的接口信息" class="headerlink" title="步骤三：填写 cc-router 的接口信息"></a>步骤三：填写 cc-router 的接口信息</h2><p>这一步是全文最关键的一步，填错任何一项都会导致后面 Codex 报 404 或 401。</p><table><thead><tr><th>字段</th><th>值</th></tr></thead><tbody><tr><td><strong>供应商名称</strong></td><td><code>cc-router</code>（可任意命名，建议保持识别度）</td></tr><tr><td><strong>API Key</strong></td><td>从 cc-router → 设置页复制的 token</td></tr><tr><td><strong>API 请求地址</strong></td><td><code>http://127.0.0.1:23456/v1</code>（本机） 或 <code>http://&lt;内网IP&gt;:23456/v1</code>（局域网）</td></tr><tr><td><strong>模型名称</strong></td><td><code>gpt-5.5</code>、<code>gpt-5.4</code>、<code>gpt-5.4-mini</code> 任选一个先填进去，后面还能切</td></tr></tbody></table><blockquote><p><strong>API 请求地址末尾必须带 <code>/v1</code>。</strong> cc-switch 默认按相对路径在末尾拼接 <code>/responses</code>，如果你填成 <code>http://127.0.0.1:23456</code>（缺 <code>/v1</code>），实际请求路径会变成 <code>/responses</code>，cc-router 找不到这个路由直接返回 404。这是初次接入最容易踩的坑。</p></blockquote><p>模型名映射到 cc-router 的虚拟槽位如下：</p><table><thead><tr><th>cc-switch 中填写</th><th>对应 cc-router 虚拟槽位</th><th>适用场景</th></tr></thead><tbody><tr><td><code>gpt-5.5</code></td><td><code>model-opus</code></td><td>规划、长上下文推理、复杂代码任务</td></tr><tr><td><code>gpt-5.4</code></td><td><code>model-sonnet</code></td><td>日常主力写代码</td></tr><tr><td><code>gpt-5.4-mini</code></td><td><code>model-haiku</code></td><td>工具调用、轻量任务、subagent 高频小请求</td></tr></tbody></table><p>模型名用的是 OpenAI 风格的别名，而不是 Anthropic 的 <code>claude-opus-4-7</code> —— 因为 Codex 那边只认 OpenAI 协议的模型名，cc-router 在网关层做了别名映射。</p><p>填完点保存。</p><p><img src="/img/cc-router/codex-03-fill-interface.png" alt="填写 cc-router 接口信息"></p><hr><h2 id="步骤四：在-Codex-CLI-里验证"><a href="#步骤四：在-Codex-CLI-里验证" class="headerlink" title="步骤四：在 Codex CLI 里验证"></a>步骤四：在 Codex CLI 里验证</h2><p>cc-switch 保存后会立刻把配置写进 <code>~/.codex/config.toml</code>，CLI 这边再启动就能读到新供应商。</p><p>打开终端跑 <code>codex</code> 进入 CLI，先确认顶部状态栏里的 <strong>模型名是刚才填的 <code>gpt-5.5</code> &#x2F; <code>gpt-5.4</code> &#x2F; <code>gpt-5.4-mini</code></strong> 之一，而不是 OpenAI 官方的 <code>gpt-5</code> 或 <code>o5</code> 这类原始模型名。然后发一条测试消息，比如「你好，请简单介绍下自己，并告诉我你是什么模型」。</p><p>正常情况下应该几秒钟内开始流式返回内容，下面这张截图就是 CLI 跑通时的状态。</p><p><img src="/img/cc-router/codex-04-cli-test-ok.png" alt="Codex CLI 测试成功"></p><p>如果模型回的是 OpenAI 风格的自我介绍，那说明请求其实没走到 cc-router，而是落到了 OpenAI 官方 —— 这种情况回 cc-switch 检查当前激活的供应商是不是「cc-router」那一项。</p><hr><h2 id="步骤五：在-Codex-Desktop-里验证"><a href="#步骤五：在-Codex-Desktop-里验证" class="headerlink" title="步骤五：在 Codex Desktop 里验证"></a>步骤五：在 Codex Desktop 里验证</h2><p>Codex Desktop 和 CLI 共享同一份 <code>~/.codex/config.toml</code>，但有一个坑要注意。</p><p><strong>如果你之前登录过 OpenAI 账号，Codex Desktop 进程内会缓存旧的供应商配置，cc-switch 的改动不会立刻生效。</strong> 解决办法：<strong>完全退出 Codex Desktop</strong>（macOS 上 Cmd+Q，不是只关闭窗口），重新打开。</p><p>重启后在对话窗口的模型选择器里点开，应该能看到刚才在 cc-switch 里配置的模型名（<code>gpt-5.5</code> &#x2F; <code>gpt-5.4</code> &#x2F; <code>gpt-5.4-mini</code>），选一个，发条测试消息，成功的样子如下图。</p><p><img src="/img/cc-router/codex-05-desktop-test-ok.png" alt="Codex Desktop 测试成功"></p><hr><h2 id="步骤六：回到-cc-router-看请求日志"><a href="#步骤六：回到-cc-router-看请求日志" class="headerlink" title="步骤六：回到 cc-router 看请求日志"></a>步骤六：回到 cc-router 看请求日志</h2><p>闭环验证：回到 cc-router 主界面，切到 <strong>请求日志</strong> 页面，能看到刚才从 Codex CLI &#x2F; Codex Desktop 发的那两条请求 —— 每条记录会显示：</p><ul><li><strong>客户端字段</strong>：<code>Codex CLI</code> 或 <code>Codex Desktop</code>（说明 cc-router 正确识别了请求来源）</li><li><strong>请求模型</strong>：你在 cc-switch 里填的 <code>gpt-5.5</code> &#x2F; <code>gpt-5.4</code> &#x2F; <code>gpt-5.4-mini</code></li><li><strong>路由到的虚拟槽位</strong>：<code>model-opus</code> &#x2F; <code>model-sonnet</code> &#x2F; <code>model-haiku</code></li><li><strong>真实上游</strong>：DeepSeek &#x2F; Kimi &#x2F; GLM &#x2F; Claude 之类（取决于你给虚拟槽位绑了哪家）</li><li><strong>耗时与 token 数</strong></li></ul><p><img src="/img/cc-router/codex-06-router-log.png" alt="cc-router 请求日志"></p><p>看到日志里出现刚发的请求，整条链路就跑通了 —— Codex 客户端 → cc-switch 选 cc-router → cc-router 按槽位路由 → 真实上游 provider。</p><hr><h2 id="请求链路时序"><a href="#请求链路时序" class="headerlink" title="请求链路时序"></a>请求链路时序</h2><p>发完一条消息后整条链路是这样跑的：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">Codex CLI/Desktop          cc-switch          cc-router :23456            上游 provider</span><br><span class="line">    │                          │                    │                          │</span><br><span class="line">    │ 启动时读 config.toml      │                    │                          │</span><br><span class="line">    ├─────────────────────────▶│                    │                          │</span><br><span class="line">    │ 拿到 base_url = http://  │                    │                          │</span><br><span class="line">    │ 127.0.0.1:23456/v1       │                    │                          │</span><br><span class="line">    │                                               │                          │</span><br><span class="line">    │ POST /v1/responses                            │                          │</span><br><span class="line">    │ Bearer &lt;api-key&gt;                              │                          │</span><br><span class="line">    │ model: gpt-5.4                                │                          │</span><br><span class="line">    ├──────────────────────────────────────────────▶│                          │</span><br><span class="line">    │                                               │ 解析模型名 → sonnet 槽位  │</span><br><span class="line">    │                                               │ 选 provider (权重/健康度) │</span><br><span class="line">    │                                               │ 翻译成上游协议            │</span><br><span class="line">    │                                               ├─────────────────────────▶│</span><br><span class="line">    │                                               │                          │</span><br><span class="line">    │                                               │◀──── stream chunks ──────│</span><br><span class="line">    │◀────────────── stream chunks ─────────────────│                          │</span><br><span class="line">    │                                               │ 写日志：客户端/模型/耗时   │</span><br></pre></td></tr></table></figure><p>如果某家 provider 返回 429 或 5xx，cc-router 会自动在同一槽位内 fallback 到下一家，对 Codex 端透明。</p><hr><h2 id="排错速查"><a href="#排错速查" class="headerlink" title="排错速查"></a>排错速查</h2><table><thead><tr><th>报错信息 &#x2F; 现象</th><th>原因</th><th>解决办法</th></tr></thead><tbody><tr><td><code>connection refused</code></td><td>cc-router 没启动 &#x2F; 端口被改</td><td>打开 cc-router 设置页，确认”实际监听端口”是 <code>23456</code>，必要时改回来或同步到 cc-switch</td></tr><tr><td><code>404 Not Found</code></td><td>API 请求地址少了 <code>/v1</code></td><td>cc-switch 里改成 <code>http://127.0.0.1:23456/v1</code></td></tr><tr><td><code>401 Unauthorized</code></td><td>token 不对或已轮换</td><td>回 cc-router 设置页重新复制 API Key，粘回 cc-switch</td></tr><tr><td><code>model_not_found</code></td><td>模型名拼错或填了 Anthropic 短名</td><td>用 <code>gpt-5.5</code> &#x2F; <code>gpt-5.4</code> &#x2F; <code>gpt-5.4-mini</code> 这类 OpenAI 别名，不要填 <code>opus</code> &#x2F; <code>sonnet</code></td></tr><tr><td>Codex Desktop 还在用旧账号</td><td>配置未生效</td><td>完全退出 Codex Desktop（不是关闭窗口）再重开</td></tr><tr><td>局域网另一台机器连不上</td><td>防火墙 &#x2F; 路由问题</td><td>在 cc-router 主机用 <code>curl http://127.0.0.1:23456/v1/models</code> 测本机，再从远端用 <code>curl http://&lt;IP&gt;:23456/v1/models</code> 测网络，分段定位</td></tr><tr><td>cc-router 日志里没记录请求</td><td>请求根本没走到 cc-router</td><td>检查 cc-switch 里当前激活的供应商是不是 cc-router（OpenAI 官方账号没切走的话请求是直接发到 OpenAI 的）</td></tr></tbody></table><hr><h2 id="安全提醒"><a href="#安全提醒" class="headerlink" title="安全提醒"></a>安全提醒</h2><ul><li><strong>API Key 等同于你所有上游 provider 的访问权</strong> —— 泄漏意味着别人能消耗你 Claude、DeepSeek、Kimi 等所有厂商的额度，请勿截图、勿提交到 git、勿粘到聊天群</li><li><strong><code>~/.codex/config.toml</code> 里 API Key 是明文存储</strong> —— 用云盘同步或备份系统时注意排除这个文件，或单独加密</li><li><strong>局域网开放需谨慎</strong> —— <code>:23456</code> 默认只监听 <code>127.0.0.1</code>，跨机器使用前确认你处在受信任的局域网；公网暴露请配反向代理 + IP 白名单 + 鉴权</li></ul><hr><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li>cc-router GitHub 仓库：<a href="https://github.com/finch-xu/cc-router">finch-xu&#x2F;cc-router</a></li><li>下载客户端：<a href="https://github.com/finch-xu/cc-router/releases/latest">GitHub Releases</a></li><li>官方主页：<a href="https://ccrouter.app/">ccrouter.app</a></li><li>官方 Codex 集成文档：<a href="https://ccrouter.app/docs/codex-integration/">ccrouter.app&#x2F;docs&#x2F;codex-integration</a></li><li>入门文档：<a href="https://ccrouter.app/docs/getting-started/">ccrouter.app&#x2F;docs&#x2F;getting-started</a></li></ul>]]>
    </content>
    <id>https://pidan.dev/20260526/cc-router-integrate-codex/</id>
    <link href="https://pidan.dev/20260526/cc-router-integrate-codex/"/>
    <published>2026-05-26T14:00:00.000Z</published>
    <summary>
      <![CDATA[<p>Codex CLI 和 Codex Desktop 默认走 OpenAI 官方账号，但我手里同时有 Claude、DeepSeek、Kimi、GLM 这些订阅，想在 Codex 客户端里直接选用它们 —— 一家一家配 base URL 和 API key 又烦又乱。把 cc-router 当本地代理，再用 cc-switch 作为 Codex 的多供应商切换器，就能把所有上游订阅聚合成三个虚拟槽位（opus&#x2F;sonnet&#x2F;haiku），在 Codex 里用一个 token 调度全部。整条链路六步就能跑通，本文按截图一步步走。</p>]]>
    </summary>
    <title>用 cc-router 接入 Codex CLI 与 Codex Desktop：一个 Token 调度多家模型订阅</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="cc-router" scheme="https://pidan.dev/tags/cc-router/"/>
    <category term="DeepSeek" scheme="https://pidan.dev/tags/DeepSeek/"/>
    <category term="Claude Code" scheme="https://pidan.dev/tags/Claude-Code/"/>
    <category term="AI" scheme="https://pidan.dev/tags/AI/"/>
    <category term="API" scheme="https://pidan.dev/tags/API/"/>
    <content>
      <![CDATA[<p>Claude 单订阅打满之后想换个口子继续跑，DeepSeek V4 Pro 是个绕不开的选项 —— 旗舰水准、按量计费、长上下文友好。但 Claude Code 只认 Anthropic 协议，DeepSeek 是 OpenAI 兼容协议，两边直连接不上。cc-router 在中间挂一层本地代理，把 DeepSeek 的 OpenAI 协议翻译成 Anthropic 协议，Claude Code 这边只需要改一份 <code>~/.claude/settings.json</code>。下面这篇把整条链路从「DeepSeek 平台领 key」到「Claude Code 跑通第一条对话」走一遍。</p><span id="more"></span><blockquote><p><strong>项目地址：</strong> <a href="https://github.com/finch-xu/cc-router">GitHub - finch-xu&#x2F;cc-router</a> ｜ <a href="https://ccrouter.app/">官方主页</a> ｜ <a href="https://ccrouter.app/docs/getting-started/">入门文档</a></p><p><strong>DeepSeek：</strong> <a href="https://platform.deepseek.com/">开发者平台</a> ｜ <a href="https://api-docs.deepseek.com/">API 文档</a> ｜ <a href="https://platform.deepseek.com/api_keys">API Keys</a></p></blockquote><h2 id="为什么是-DeepSeek-V4-Pro"><a href="#为什么是-DeepSeek-V4-Pro" class="headerlink" title="为什么是 DeepSeek V4 Pro"></a>为什么是 DeepSeek V4 Pro</h2><p>DeepSeek 2026 年发布的 V4 系列把模型清单收敛成两个：</p><ul><li><strong><code>deepseek-v4-pro</code></strong> —— 旗舰，对标 Claude Opus &#x2F; GPT 顶配，适合放在 cc-router 的 <code>model-opus</code> 槽位</li><li><strong><code>deepseek-v4-flash</code></strong> —— 轻量低延迟，适合放在 <code>model-haiku</code> 槽位接 subagent 这种高频小请求</li></ul><p>老的 <code>deepseek-chat</code> &#x2F; <code>deepseek-reasoner</code> 在 <strong>2026-07-24 弃用</strong>，DeepSeek 官方文档里已经标注，新接入直接用 V4 系列即可。</p><p>协议上 DeepSeek 走的是 OpenAI Chat Completions 兼容接口，base URL <code>https://api.deepseek.com</code>。cc-router 已经内置了 DeepSeek 这个 provider（在 cc-router 的厂商列表里归类为「按量付费」），<strong>不需要走「自定义 OpenAI 兼容」入口</strong>，省一步配置。计费形态是预付余额、按 token 计算，没有月度套餐 —— 这点和 Claude &#x2F; GLM 那种 Token Plan 不同，首次接入记得先充小额测试。</p><hr><h2 id="整体连接架构"><a href="#整体连接架构" class="headerlink" title="整体连接架构"></a>整体连接架构</h2><p>cc-router 在本地起一个 Anthropic 协议代理（默认 <code>127.0.0.1:23456</code>），向上对接 Claude Code，向下转发到 DeepSeek 官方 API：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"> claude CLI              cc-router (本地)              DeepSeek 官方</span><br><span class="line">┌──────────┐            ┌─────────────────┐         ┌──────────────────┐</span><br><span class="line">│ HTTP     │──────────▶│ 127.0.0.1:23456 │───────▶ │ api.deepseek.com │</span><br><span class="line">│ Anthropic│            │ 协议翻译         │         │ deepseek-v4-pro  │</span><br><span class="line">│ 协议     │            │ 三槽位虚拟模型   │         │ deepseek-v4-flash│</span><br><span class="line">└──────────┘            └─────────────────┘         └──────────────────┘</span><br><span class="line">       ▲                        │</span><br><span class="line">       │                        └── 请求日志页实时可见</span><br><span class="line">   ~/.claude/settings.json</span><br><span class="line">   注入 env 变量</span><br></pre></td></tr></table></figure><p>Claude Code 这边其实什么都不用改，它原本就支持通过环境变量改写 base URL 和模型名，cc-router 接管的正是这两个口子，外加把 Anthropic 协议的 messages &#x2F; tool_use 翻译成 OpenAI 协议的 messages &#x2F; tool_calls 转发给 DeepSeek。</p><hr><h2 id="步骤一：在-DeepSeek-平台申请-API-Key"><a href="#步骤一：在-DeepSeek-平台申请-API-Key" class="headerlink" title="步骤一：在 DeepSeek 平台申请 API Key"></a>步骤一：在 DeepSeek 平台申请 API Key</h2><p>打开 <a href="https://platform.deepseek.com/">platform.deepseek.com</a>，注册或登录。</p><p>进入 <strong>充值</strong> 页面预存一点余额。按量计费没有免费额度，必须有余额账号才能调用 API；首次测试充 10 块钱足够跑通整条链路 + 跑几个简单任务。</p><p>然后到 <a href="https://platform.deepseek.com/api_keys">API Keys 页面</a> → <strong>Create new API key</strong> → 起个名字（比如 <code>cc-router-local</code>）→ <strong>立即复制</strong> 生成的 <code>sk-xxxxxxxx</code> 串。<strong>关闭对话框后就再也看不到完整 key 了</strong>，DeepSeek 平台只在这一次明文展示。复制完粘到密码管理器或者直接进下一步。</p><p>如果手抄漏了字符，回这里删掉旧 key 重新生成一个，不要尝试在仪表盘上「找回」。</p><hr><h2 id="步骤二：下载并启动-cc-router"><a href="#步骤二：下载并启动-cc-router" class="headerlink" title="步骤二：下载并启动 cc-router"></a>步骤二：下载并启动 cc-router</h2><p>cc-router 是 Tauri 写的桌面应用，macOS &#x2F; Windows &#x2F; Linux 都有打包好的版本，直接到 <a href="https://github.com/finch-xu/cc-router/releases/latest">GitHub Releases</a> 或 <a href="https://ccrouter.app/download/">ccrouter.app&#x2F;download</a> 下载对应平台的 <code>.dmg</code> &#x2F; <code>.exe</code> &#x2F; <code>.AppImage</code> &#x2F; <code>.deb</code>。</p><p>装完打开 App，本地代理服务会自动起在 <code>127.0.0.1:23456</code>。</p><p>如果 23456 端口被别的进程占了，cc-router 会自动 +1 往后递增（23457、23458……）。所以<strong>不要把 23456 硬编码到 settings.json 里</strong>，要回到 cc-router 设置页确认实际监听端口再复制 —— 这是踩坑率最高的一项。</p><p><img src="/img/cc-router/cc-cli-01-app-running.png" alt="cc-router 主界面"></p><hr><h2 id="步骤三：在-cc-router-里添加-DeepSeek-provider"><a href="#步骤三：在-cc-router-里添加-DeepSeek-provider" class="headerlink" title="步骤三：在 cc-router 里添加 DeepSeek provider"></a>步骤三：在 cc-router 里添加 DeepSeek provider</h2><p>进入 <strong>订阅 &#x2F; Providers</strong> 页 → <strong>添加订阅</strong>。</p><p>厂商列表里找 <strong>DeepSeek（按量付费）</strong> —— 注意 cc-router 把每家厂商的「按量付费」和「Token Plan」做了区分入口，DeepSeek 这边只有按量付费一种接入方式。</p><p>填写界面里要注意：</p><ul><li><strong>Base URL &#x2F; Endpoint</strong> 不需要手动填。这是内置 provider，cc-router 自动用官方接入点 <code>https://api.deepseek.com</code>。</li><li><strong>API Key</strong> 字段：粘上一步从 DeepSeek 平台领的 <code>sk-xxx</code>。</li><li>保存后 cc-router 会<strong>自动调用 <code>/v1/models</code> 抓一遍该 key 可用的模型列表</strong>，正常情况下你应该在面板里看到 <code>deepseek-v4-pro</code>、<code>deepseek-v4-flash</code>，以及可能存在的过渡模型如 <code>deepseek-chat</code> &#x2F; <code>deepseek-reasoner</code>（这两个 2026-07-24 弃用，看到了不必绑）。</li></ul><p>如果你拉出来的列表是空的，绝大多数情况是 key 拼错或者账户没充值，回上一步确认 DeepSeek 平台显示「余额 &gt; 0」且 key 状态 <code>active</code>。</p><p>顺便提一下：cc-router 还提供「<strong>自定义 (Anthropic 协议)</strong>」和「<strong>自定义 (Gemini 兼容)</strong>」两个泛用入口，给那些没在内置列表里的小众 provider 用。DeepSeek 是内置 provider，<strong>不要</strong>走自定义入口，否则你得自己填 base URL、headers、模型映射，纯粹给自己找麻烦。</p><hr><h2 id="步骤四：把模型绑到虚拟槽位"><a href="#步骤四：把模型绑到虚拟槽位" class="headerlink" title="步骤四：把模型绑到虚拟槽位"></a>步骤四：把模型绑到虚拟槽位</h2><p>cc-router 对外暴露的不是真实模型名，而是三个虚拟槽位 —— <code>model-opus</code> &#x2F; <code>model-sonnet</code> &#x2F; <code>model-haiku</code>。Claude Code 请求过来时只认这三个别名，cc-router 根据每个槽位的绑定情况决定打到哪家 provider 的哪个真实模型。</p><p>进 <strong>模型 &#x2F; Models</strong> 页，对每个虚拟槽位单独配置：</p><table><thead><tr><th>虚拟槽位</th><th>绑定模型</th></tr></thead><tbody><tr><td><code>model-opus</code></td><td><code>deepseek-v4-pro</code></td></tr><tr><td><code>model-sonnet</code></td><td><code>deepseek-v4-pro</code></td></tr><tr><td><code>model-haiku</code></td><td><code>deepseek-v4-flash</code></td></tr></tbody></table><p>为什么 sonnet 也绑 v4-pro 而不是 flash？Claude Code 把 <strong>subagent &#x2F; Task tool 的默认模型挂在 sonnet 槽位</strong>（除非你显式覆盖 <code>CLAUDE_CODE_SUBAGENT_MODEL</code>）。subagent 是要独立干一段子任务的，把它降级到 flash 等于让一个轻量模型独立完成代码搜索、重构判断这种事，结果质量会被拉低，而你在主对话看到的是「subagent 给的总结」，问题会被层层包裹得不容易追溯。两个槽位都绑旗舰，代价是这两个槽位的请求都按 v4-pro 价位计费，但调试体验干净很多。haiku 槽位 Claude Code 用来跑短小的辅助请求（命令生成、文件名建议这类），给 flash 即可。</p><p><strong>调度模式</strong> 在「同一个槽位绑多家 provider」时才有意义，单家 DeepSeek 直接绑就行。等之后你想加挂第二家厂商做 fallback，再回到这里选：</p><ul><li><strong>Sequential</strong>：A 用完或失败才切 B，保留 prompt cache，适合「先榨干主力账号再切备用」</li><li><strong>Round-robin</strong>：请求间轮换，真负载均衡，但会破坏单家的 prompt cache 命中率</li></ul><hr><h2 id="步骤五：复制-cc-router-的-token-和-base-URL"><a href="#步骤五：复制-cc-router-的-token-和-base-URL" class="headerlink" title="步骤五：复制 cc-router 的 token 和 base URL"></a>步骤五：复制 cc-router 的 token 和 base URL</h2><p>打开 cc-router → <strong>设置</strong> → <strong>代理服务</strong>，这一页有两个东西要抄：</p><ol><li><strong>Base URL</strong>：<code>http://127.0.0.1:实际端口</code>，注意是 <code>http://</code> 不是 <code>https://</code>，端口看实际监听值（可能被 +1）</li><li><strong>Token &#x2F; API Key</strong>：cc-router 自己生成的一串字符串，Claude Code 用这个鉴权进 cc-router（<strong>不是</strong> DeepSeek 那个 <code>sk-xxx</code>）</li></ol><p>用页面上的复制按钮，避免手抄漏字符。</p><p><img src="/img/cc-router/cc-cli-03-copy-token.png" alt="复制 token 与 base URL"></p><blockquote><p>⚠️ 这个 token <strong>等同于你所有挂在 cc-router 上的上游订阅的访问权</strong>（这里就是你的 DeepSeek 余额）。不要截图、不要 push 到 git、不要发到群里。</p></blockquote><hr><h2 id="步骤六：写入-claude-settings-json"><a href="#步骤六：写入-claude-settings-json" class="headerlink" title="步骤六：写入 ~/.claude/settings.json"></a>步骤六：写入 <code>~/.claude/settings.json</code></h2><p>Claude Code 启动时会读 <code>~/.claude/settings.json</code>，把 <code>env</code> 字段里的所有键值对当成环境变量注入到自己进程，这是官方支持的扩展点。文件位置三平台都是同一个：</p><ul><li>macOS &#x2F; Linux：<code>~/.claude/settings.json</code></li><li>Windows：<code>%USERPROFILE%\.claude\settings.json</code></li></ul><p>文件不存在就新建，已存在就合并 <code>env</code> 字段（其它字段别动）。完整模板：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;env&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_BASE_URL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;http://127.0.0.1:23456&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_AUTH_TOKEN&quot;</span><span class="punctuation">:</span> <span class="string">&quot;这里填写cc-router设置里真实token&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;API_TIMEOUT_MS&quot;</span><span class="punctuation">:</span> <span class="string">&quot;3000000&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-opus&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_OPUS_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-opus&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_SONNET_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-sonnet&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_HAIKU_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-haiku&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_SUBAGENT_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-opus&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_ATTRIBUTION_HEADER&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_EFFORT_LEVEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;max&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>四个最容易踩坑的字段：</p><table><thead><tr><th>字段</th><th>注意点</th></tr></thead><tbody><tr><td><code>ANTHROPIC_BASE_URL</code></td><td>端口换成 cc-router 设置页里看到的<strong>实际监听端口</strong>，可能不是 23456</td></tr><tr><td><code>ANTHROPIC_AUTH_TOKEN</code></td><td><strong>不是</strong> <code>ANTHROPIC_API_KEY</code>，字段名写错最常见的 401 来源</td></tr><tr><td><code>API_TIMEOUT_MS</code></td><td>DeepSeek 长上下文请求容易跑久，3000000ms（50 分钟）足够</td></tr><tr><td><code>ANTHROPIC_MODEL</code> 及三个 <code>_DEFAULT_*_MODEL</code></td><td>必须写<strong>虚拟槽位别名</strong>（<code>model-opus</code> 等），不要写 <code>deepseek-v4-pro</code> —— Claude Code 不认真实模型名</td></tr></tbody></table><p>字段全集和每个 env 的细节看<a href="/20260520/cc-router-integrate-claude-code/">用 cc-router 接入 Claude Code</a>，本文不再重复。</p><hr><h2 id="步骤七：起-claude，发一条话验证"><a href="#步骤七：起-claude，发一条话验证" class="headerlink" title="步骤七：起 claude，发一条话验证"></a>步骤七：起 claude，发一条话验证</h2><p>如果还没装 Claude Code：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -fsSL https://claude.ai/install.sh | bash</span><br></pre></td></tr></table></figure><p>随便进一个目录，运行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">claude</span><br></pre></td></tr></table></figure><p>进入对话后随便问一句，比如「写一段 Hello World 的 Python 代码」。</p><p>切回 cc-router 主界面，进<strong>请求日志</strong>页 —— 应该能看到刚刚那条请求的记录：哪个虚拟槽位（<code>model-opus</code>）、被路由到哪家上游 provider（<code>DeepSeek</code>）、命中的真实模型（<code>deepseek-v4-pro</code>）、消耗了多少 token、响应耗时多少。如果日志页没动静，说明请求根本没走到 cc-router，回去检查 <code>ANTHROPIC_BASE_URL</code> 的端口对不对、<code>settings.json</code> 是不是合法 JSON、是否完整退出 claude 进程再重开。</p><p><img src="/img/cc-router/cc-cli-05-request-log.png" alt="cc-router 请求日志"></p><hr><h2 id="DeepSeek-V4-Pro-用起来要注意的点"><a href="#DeepSeek-V4-Pro-用起来要注意的点" class="headerlink" title="DeepSeek V4 Pro 用起来要注意的点"></a>DeepSeek V4 Pro 用起来要注意的点</h2><ul><li><strong>看到老模型 ID 别绑</strong>。如果 cc-router 抓出来的模型列表里只有 <code>deepseek-chat</code> &#x2F; <code>deepseek-reasoner</code> 没有 <code>deepseek-v4-pro</code>，说明账号还在旧模型分组里，去 DeepSeek 平台后台切到 V4 系列。两个老模型 2026-07-24 弃用，没必要绑。</li><li><strong>按量计费 &#x3D; 没有免费额度</strong>。第一次跑 Claude Code 一个简单任务（几次工具调用 + 几千 token 输出）可能消耗几分到几毛钱，正常。盯着 DeepSeek 平台的余额面板，跑大任务前充够。</li><li><strong>协议翻译在 cc-router 这一层</strong>。DeepSeek 用 OpenAI 协议但 Claude Code 发的是 Anthropic 协议，cc-router 在中间做字段映射。如果遇到 tool_use 行为怪异、长 prompt 截断之类的怪现象，<strong>先看 cc-router 请求日志页的原始报文</strong>，能直接看到「Anthropic 协议进 &#x2F; OpenAI 协议出」两段，判断是协议翻译的问题还是 DeepSeek 端的问题。</li><li><strong>单家 provider 不要勾 Round-robin</strong>。Round-robin 是给多家 provider 设计的，单挂 DeepSeek 一家时它和 Sequential 没区别，但开了反而会让 cc-router 内部多走一段无意义的轮询逻辑。等真挂了第二家再回来调度模式选项。</li></ul><hr><h2 id="排错速查"><a href="#排错速查" class="headerlink" title="排错速查"></a>排错速查</h2><table><thead><tr><th>现象</th><th>原因</th><th>修法</th></tr></thead><tbody><tr><td>cc-router 添加完 DeepSeek，模型列表是空的</td><td>API Key 无效 &#x2F; 账号没充值</td><td>回 DeepSeek 平台确认余额 &gt; 0 且 key 状态 active</td></tr><tr><td>模型列表只有 <code>deepseek-chat</code> &#x2F; <code>deepseek-reasoner</code>，看不到 v4-pro</td><td>账号还在旧模型分组</td><td>DeepSeek 平台后台切到 V4 系列；老模型 2026-07-24 弃用</td></tr><tr><td>Claude Code 报 <code>401 Unauthorized</code></td><td>cc-router token 写错 &#x2F; 字段写成了 <code>ANTHROPIC_API_KEY</code></td><td>字段名必须 <code>ANTHROPIC_AUTH_TOKEN</code>，回 cc-router 设置页重新复制 token</td></tr><tr><td>Claude Code 报 <code>model not found</code></td><td>settings.json 里写的是真实模型名 <code>deepseek-v4-pro</code></td><td>改成虚拟槽位名 <code>model-opus</code> &#x2F; <code>model-sonnet</code> &#x2F; <code>model-haiku</code></td></tr><tr><td>Claude Code 报 <code>connection refused</code></td><td>端口对不上</td><td>回 cc-router 设置页看实际监听端口（可能被自动 +1）</td></tr><tr><td>请求日志页 5xx，错误信息含 <code>insufficient_balance</code></td><td>DeepSeek 账户余额耗尽</td><td>平台充值；或同槽位加挂第二家 provider 配 Sequential fallback</td></tr><tr><td>请求日志页没记录</td><td>claude 没读到 settings.json</td><td>完整退出 claude 进程再重开；确认文件路径是 <code>~/.claude/settings.json</code> 且 JSON 合法</td></tr></tbody></table><hr><h2 id="安全提醒"><a href="#安全提醒" class="headerlink" title="安全提醒"></a>安全提醒</h2><ul><li><strong>DeepSeek 的 <code>sk-xxx</code> 直接控制你的余额</strong>。cc-router 把这个 key 存在本地配置目录里，不要把 cc-router 的配置文件夹整体备份到公开仓库或云盘共享链接。</li><li><strong>cc-router 自身的聚合 token 比单一 DeepSeek key 后果更严重</strong> —— 一旦泄漏，攻击者可以消耗你挂在 cc-router 上的所有上游订阅，不只是 DeepSeek 这一家。单独保管，不要和 DeepSeek key 放一起。</li><li><strong>HTTP 监听仅限本机环回</strong>。<code>127.0.0.1:23456</code> 默认只对本机可见，不要为了「在另一台机器上用」把端口暴露到公网。跨机器调用走 cc-router 自带的 HTTPS 模式 + 自签 CA，参考相关阅读那篇 Claude Desktop 接入教程。</li><li><strong>DeepSeek 的 ToS 自己遵守</strong>。cc-router 是透明代理，不解除任何 provider 端的限制；高频跨账号轮询有被限速或封号风险。</li></ul><hr><h2 id="相关阅读"><a href="#相关阅读" class="headerlink" title="相关阅读"></a>相关阅读</h2><ul><li><a href="/20260520/cc-router-integrate-claude-code/">用 cc-router 接入 Claude Code：一份 settings.json 把多家订阅塞进 CLI</a> —— settings.json 字段全集和每个 env 的细节</li><li><a href="/20260514/cc-router-integrate-claude-desktop/">用 cc-router 接入 Claude Desktop：一个 Token 调度多家模型订阅</a> —— HTTPS Gateway + 自签 CA 跨机器方案</li></ul><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li>cc-router：<a href="https://github.com/finch-xu/cc-router">GitHub 仓库</a> &#x2F; <a href="https://ccrouter.app/">官方主页</a> &#x2F; <a href="https://ccrouter.app/docs/getting-started/">入门文档</a> &#x2F; <a href="https://github.com/finch-xu/cc-router/releases/latest">GitHub Releases 下载</a></li><li>DeepSeek：<a href="https://platform.deepseek.com/">开发者平台</a> &#x2F; <a href="https://api-docs.deepseek.com/">API 文档</a> &#x2F; <a href="https://platform.deepseek.com/api_keys">API Keys 申请页</a></li></ul>]]>
    </content>
    <id>https://pidan.dev/20260521/cc-router-add-deepseek-v4-pro/</id>
    <link href="https://pidan.dev/20260521/cc-router-add-deepseek-v4-pro/"/>
    <published>2026-05-21T02:00:00.000Z</published>
    <summary>
      <![CDATA[<p>Claude 单订阅打满之后想换个口子继续跑，DeepSeek V4 Pro 是个绕不开的选项 —— 旗舰水准、按量计费、长上下文友好。但 Claude Code 只认 Anthropic 协议，DeepSeek 是 OpenAI 兼容协议，两边直连接不上。cc-router 在中间挂一层本地代理，把 DeepSeek 的 OpenAI 协议翻译成 Anthropic 协议，Claude Code 这边只需要改一份 <code>~/.claude/settings.json</code>。下面这篇把整条链路从「DeepSeek 平台领 key」到「Claude Code 跑通第一条对话」走一遍。</p>]]>
    </summary>
    <title>把 DeepSeek V4 Pro 接进 cc-router：从申请 API Key 到 Claude Code 跑通</title>
    <updated>2026-05-26T14:45:37.884Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="cc-router" scheme="https://pidan.dev/tags/cc-router/"/>
    <category term="Claude Code" scheme="https://pidan.dev/tags/Claude-Code/"/>
    <category term="AI" scheme="https://pidan.dev/tags/AI/"/>
    <category term="CLI" scheme="https://pidan.dev/tags/CLI/"/>
    <content>
      <![CDATA[<p>Claude Code 默认只走 Anthropic 官方 API，单订阅一旦打满就只能干瞪眼；想换成 DeepSeek、Kimi、GLM 又要手动改环境变量，每次切都要折腾。cc-router 干的就是把这些零散订阅聚合成一份「虚拟订阅」，在本地起一个 Anthropic 协议网关，Claude Code 一份 <code>settings.json</code> 就接管完毕 —— 不装证书、不进 Developer 菜单、不重启系统，整个过程十分钟以内。</p><span id="more"></span><blockquote><p><strong>项目地址：</strong> <a href="https://github.com/finch-xu/cc-router">GitHub - finch-xu&#x2F;cc-router</a> ｜ <a href="https://ccrouter.app/">官方主页</a> ｜ <a href="https://ccrouter.app/docs/getting-started/">入门文档</a> ｜ <a href="https://ccrouter.app/download/">下载客户端</a></p></blockquote><h2 id="cc-router-到-Claude-Code-是怎么连起来的"><a href="#cc-router-到-Claude-Code-是怎么连起来的" class="headerlink" title="cc-router 到 Claude Code 是怎么连起来的"></a>cc-router 到 Claude Code 是怎么连起来的</h2><p>cc-router 在本地起一个 Anthropic 协议代理（默认 <code>127.0.0.1:23456</code>），上游挂着 DeepSeek、Qwen、Kimi、GLM、Claude 官方等近 20 家厂商。它对外暴露三个虚拟模型槽位 —— <code>model-opus</code>、<code>model-sonnet</code>、<code>model-haiku</code>，每个槽位都可以挂多家厂商，按顺序 fallback 或者轮询调度。</p><p>Claude Code 这边其实什么都不用改，它原本就支持通过环境变量改写 base URL 和模型名，cc-router 正好接管这两个口子。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"> claude CLI                cc-router (本地)              上游 provider</span><br><span class="line">┌──────────┐              ┌─────────────────┐          ┌────────────────┐</span><br><span class="line">│ HTTP     │──────────▶  │ 127.0.0.1:23456 │────────▶ │ DeepSeek / Kimi│</span><br><span class="line">│ Anthropic│              │ 三槽位虚拟模型    │          │ GLM / Qwen     │</span><br><span class="line">│ 协议     │              │ 顺序/轮询/Fallback│          │ Claude 官方 等 │</span><br><span class="line">└──────────┘              └─────────────────┘          └────────────────┘</span><br><span class="line">       ▲                          │</span><br><span class="line">       │                          └── 请求日志页实时可见</span><br><span class="line">   ~/.claude/settings.json</span><br><span class="line">   注入 env 变量</span><br></pre></td></tr></table></figure><p><strong>和 Claude Desktop 接入方式的差别：</strong></p><ul><li>Claude Code 是 <strong>HTTP 直连本机环回</strong>，不用装自签 CA 证书 —— Desktop 那篇博文里大半篇幅的钥匙串&#x2F;证书管理这里全部跳过</li><li>配置位置是 <strong><code>~/.claude/settings.json</code> 的 <code>env</code> 字段</strong>，不是 Desktop 那种 Developer 菜单点点点</li><li>三槽位走的是 <strong><code>model-opus</code> &#x2F; <code>model-sonnet</code> &#x2F; <code>model-haiku</code></strong> 这种 cc-router 自定义别名，不是 <code>anthropic/claude-opus-4-7</code> 这种带厂商前缀的真模型名</li></ul><hr><h2 id="步骤一：下载并启动-cc-router"><a href="#步骤一：下载并启动-cc-router" class="headerlink" title="步骤一：下载并启动 cc-router"></a>步骤一：下载并启动 cc-router</h2><p>cc-router 是 Tauri 写的桌面应用，macOS &#x2F; Windows &#x2F; Linux 都有打包好的版本，直接到 <a href="https://github.com/finch-xu/cc-router/releases/latest">GitHub Releases</a>  或 <a href="https://ccrouter.app/download/">https://ccrouter.app/download/</a> 下载对应平台的 <code>.dmg</code>、<code>.exe</code>、<code>.AppImage</code> 或 <code>.deb</code>。装完打开 App，本地代理服务会自动起在 <code>127.0.0.1:23456</code>。</p><p>如果 23456 端口被别的进程占了，cc-router 会自动 +1 往后递增（23457、23458……）。所以<strong>不要把 23456 硬编码到 settings.json 里</strong>，要回到 cc-router 设置页确认实际监听端口再复制 —— 这是踩坑率最高的一项。</p><p><img src="/img/cc-router/cc-cli-01-app-running.png" alt="cc-router 主界面"></p><hr><h2 id="步骤二：在-App-里绑一家-provider-到虚拟槽位"><a href="#步骤二：在-App-里绑一家-provider-到虚拟槽位" class="headerlink" title="步骤二：在 App 里绑一家 provider 到虚拟槽位"></a>步骤二：在 App 里绑一家 provider 到虚拟槽位</h2><p>cc-router 自己不卖 token，它是个调度器，你得把已有的厂商订阅挂上来。流程是「选厂商 → 选接入点 → 粘贴该厂商 API Key → 自动拉模型」，每加一家都要把它绑到某个虚拟槽位。</p><p>最小可用配置：<strong>至少把一家 provider 绑到 <code>model-opus</code></strong>（比如 DeepSeek-V4-Pro 或 GLM-5.1）。如果你想让 sonnet &#x2F; haiku 槽位也能用，再各绑一家就行；同一槽位也可以挂多家走 fallback。</p><p>调度模式选哪个：</p><ul><li><strong>Sequential</strong>：A 用完或失败才切 B，保留 prompt cache，适合「榨干小额订阅」</li><li><strong>Round-robin</strong>：请求轮换，真正负载均衡，每个账号独立 cache</li></ul><p>只有一家 provider 的时候这两个选哪个都一样，等你后续挂多家了再回来调。</p><hr><h2 id="步骤三：从-cc-router-复制-token-和-base-URL"><a href="#步骤三：从-cc-router-复制-token-和-base-URL" class="headerlink" title="步骤三：从 cc-router 复制 token 和 base URL"></a>步骤三：从 cc-router 复制 token 和 base URL</h2><p>打开 cc-router → <strong>设置</strong> → <strong>代理服务</strong>，这一页有两个东西要抄：</p><ol><li><strong>Base URL</strong>：<code>http://127.0.0.1:实际端口</code>，注意是 <code>http://</code> 不是 <code>https://</code></li><li><strong>Token &#x2F; API Key</strong>：cc-router 自己生成的一串字符串，Claude Code 用这个鉴权进 cc-router（不是任何上游厂商的原 key）</li></ol><p>直接用页面上的复制按钮，避免手抄漏字符。token 一次性生成、不会自动轮换，如果你确认泄漏了再到这里重置。</p><p><img src="/img/cc-router/cc-cli-03-copy-token.png" alt="复制 token 与 base URL"></p><blockquote><p>⚠️ 这个 token <strong>等同于你所有挂在 cc-router 上的上游订阅的访问权</strong>。不要截图、不要 push 到 git、不要发到群里。</p></blockquote><hr><h2 id="步骤四：写入-claude-settings-json"><a href="#步骤四：写入-claude-settings-json" class="headerlink" title="步骤四：写入 ~/.claude/settings.json"></a>步骤四：写入 <code>~/.claude/settings.json</code></h2><p>Claude Code 在启动时会读取 <code>~/.claude/settings.json</code>，把里面 <code>env</code> 字段的所有键值对当成环境变量注入到自己进程。这是官方支持的扩展点，我们要做的就是把 cc-router 的 base URL 和 token 写进去。</p><p>文件位置三平台都是同一个：</p><ul><li>macOS &#x2F; Linux：<code>~/.claude/settings.json</code></li><li>Windows：<code>%USERPROFILE%\.claude\settings.json</code></li></ul><p>如果文件不存在就新建，如果已存在就合并 <code>env</code> 字段（其它字段别动）。完整模板原样照抄自<a href="https://ccrouter.app/docs/getting-started/">官方文档</a>：</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;env&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_BASE_URL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;http://127.0.0.1:23456&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_AUTH_TOKEN&quot;</span><span class="punctuation">:</span> <span class="string">&quot;这里填写cc-router设置里真实token&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;API_TIMEOUT_MS&quot;</span><span class="punctuation">:</span> <span class="string">&quot;3000000&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-opus&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_OPUS_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-opus&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_SONNET_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-sonnet&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;ANTHROPIC_DEFAULT_HAIKU_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-haiku&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_SUBAGENT_MODEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;model-opus&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_ATTRIBUTION_HEADER&quot;</span><span class="punctuation">:</span> <span class="string">&quot;0&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;CLAUDE_CODE_EFFORT_LEVEL&quot;</span><span class="punctuation">:</span> <span class="string">&quot;max&quot;</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p><strong>关键字段解释：</strong></p><table><thead><tr><th>字段</th><th>作用</th></tr></thead><tbody><tr><td><code>ANTHROPIC_BASE_URL</code></td><td>把 Claude Code 的请求改打到 cc-router 本地代理，端口别忘了换成实际监听端口</td></tr><tr><td><code>ANTHROPIC_AUTH_TOKEN</code></td><td><strong>注意不是 <code>ANTHROPIC_API_KEY</code></strong> —— 字段名写错最常见的 401 来源</td></tr><tr><td><code>API_TIMEOUT_MS</code></td><td>长 prompt 防超时，3000000ms（50 分钟）足够长 prompt 跑完不被掐</td></tr><tr><td><code>CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC</code></td><td>关掉 telemetry 等非必要请求，避免空跑消耗 token</td></tr><tr><td><code>ANTHROPIC_MODEL</code></td><td>默认模型，这里指向 <code>model-opus</code>（cc-router 的虚拟别名）</td></tr><tr><td><code>ANTHROPIC_DEFAULT_OPUS_MODEL</code> &#x2F; <code>_SONNET_</code> &#x2F; <code>_HAIKU_</code></td><td>三槽位别名，名字要和 cc-router 里的槽位名严格一致</td></tr></tbody></table><hr><h2 id="步骤五：起-claude，发一条话验证"><a href="#步骤五：起-claude，发一条话验证" class="headerlink" title="步骤五：起 claude，发一条话验证"></a>步骤五：起 claude，发一条话验证</h2><p>如果还没装 Claude Code：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">curl -fsSL https://claude.ai/install.sh | bash</span><br></pre></td></tr></table></figure><p>随便进一个目录，运行：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">claude</span><br></pre></td></tr></table></figure><p>进入对话后随便问一句，比如「写一段 Hello World 的 Python 代码」。</p><p>切回 cc-router 主界面，进<strong>请求日志</strong>页 —— 应该能看到刚刚那条请求的记录：哪个虚拟槽位、被路由到哪家上游 provider、消耗了多少 token、响应耗时多少。如果日志页没动静，说明请求根本没走到 cc-router，回去检查 <code>ANTHROPIC_BASE_URL</code> 的端口对不对。</p><p><img src="/img/cc-router/cc-cli-05-request-log.png" alt="cc-router 请求日志"></p><hr><h2 id="排错速查"><a href="#排错速查" class="headerlink" title="排错速查"></a>排错速查</h2><table><thead><tr><th>现象</th><th>原因</th><th>修法</th></tr></thead><tbody><tr><td><code>401 Unauthorized</code></td><td>token 写错 &#x2F; 用了 <code>ANTHROPIC_API_KEY</code> 字段</td><td>字段名必须是 <code>ANTHROPIC_AUTH_TOKEN</code>，回 cc-router 重新复制 token</td></tr><tr><td><code>connection refused</code></td><td>端口对不上</td><td>回 cc-router 设置页看实际监听端口（可能被自动 +1）</td></tr><tr><td><code>model not found</code></td><td>settings.json 里模型名拼错</td><td>与 cc-router 槽位名严格一致：<code>model-opus</code> &#x2F; <code>model-sonnet</code> &#x2F; <code>model-haiku</code></td></tr><tr><td>请求日志页没记录</td><td>claude 没读到 settings.json</td><td>完整退出 claude 进程再重开；确认文件路径是 <code>~/.claude/settings.json</code> 且 JSON 合法</td></tr><tr><td>某次 5xx &#x2F; 429</td><td>上游 provider 限流或挂了</td><td>同槽位多挂一家，开 Sequential 或 Round-robin，cc-router 自动 fallback</td></tr></tbody></table><hr><h2 id="安全提醒"><a href="#安全提醒" class="headerlink" title="安全提醒"></a>安全提醒</h2><ul><li><strong>cc-router 的 token 是聚合密钥</strong> —— 一旦泄漏，攻击者就能消耗你所有挂上来的上游订阅，比单家 API Key 后果严重得多</li><li><strong>HTTP 监听仅限本机环回</strong> —— 不要把 23456 端口暴露公网。跨机器调用请用 cc-router 自带的 HTTPS 模式 + 自签 CA（具体方式见下方相关阅读）</li><li><strong>各厂商 ToS 自己遵守</strong> —— cc-router 只是透明代理，不替你解除任何 provider 端的限制；高频跨账号轮询有被限速或封号风险</li></ul><hr><h2 id="相关阅读"><a href="#相关阅读" class="headerlink" title="相关阅读"></a>相关阅读</h2><ul><li>想用桌面 GUI 客户端而不是 CLI？参考 <a href="/20260514/cc-router-integrate-claude-desktop/">用 cc-router 接入 Claude Desktop：一个 Token 调度多家模型订阅</a>，那篇用的是 HTTPS Gateway + 自签 CA 方案。</li></ul><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li>GitHub 仓库：<a href="https://github.com/finch-xu/cc-router">finch-xu&#x2F;cc-router</a></li><li>官方主页：<a href="https://ccrouter.app/">ccrouter.app</a></li><li>入门文档：<a href="https://ccrouter.app/docs/getting-started/">Getting Started</a></li><li>下载客户端：<a href="https://github.com/finch-xu/cc-router/releases/latest">GitHub Releases</a></li></ul>]]>
    </content>
    <id>https://pidan.dev/20260520/cc-router-integrate-claude-code/</id>
    <link href="https://pidan.dev/20260520/cc-router-integrate-claude-code/"/>
    <published>2026-05-20T06:00:00.000Z</published>
    <summary>
      <![CDATA[<p>Claude Code 默认只走 Anthropic 官方 API，单订阅一旦打满就只能干瞪眼；想换成 DeepSeek、Kimi、GLM 又要手动改环境变量，每次切都要折腾。cc-router 干的就是把这些零散订阅聚合成一份「虚拟订阅」，在本地起一个 Anthropic 协议网关，Claude Code 一份 <code>settings.json</code> 就接管完毕 —— 不装证书、不进 Developer 菜单、不重启系统，整个过程十分钟以内。</p>]]>
    </summary>
    <title>用 cc-router 接入 Claude Code：一份 settings.json 把多家订阅塞进 CLI</title>
    <updated>2026-05-26T14:45:37.884Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="cc-router" scheme="https://pidan.dev/tags/cc-router/"/>
    <category term="Claude Code" scheme="https://pidan.dev/tags/Claude-Code/"/>
    <category term="AI" scheme="https://pidan.dev/tags/AI/"/>
    <category term="Claude Desktop" scheme="https://pidan.dev/tags/Claude-Desktop/"/>
    <content>
      <![CDATA[<p>如果你同时订阅了 Claude Pro、Kimi、DeepSeek、GLM 等好几家模型服务，每次切换都得换客户端、复制 API key、改环境变量，不如把这些订阅聚合成一个虚拟模型，在 Claude Desktop 里直接选用。cc-router 就是干这件事的本地代理：18 家厂商一站调度、自动故障转移、限流处理、三槽位（opus&#x2F;sonnet&#x2F;haiku）虚拟模型。本文从证书安装到模型验证，按官方推荐的方式把 cc-router 接入 Claude Desktop。</p><span id="more"></span><blockquote><p><strong>项目地址：</strong> <a href="https://github.com/finch-xu/cc-router">GitHub - finch-xu&#x2F;cc-router</a> ｜ <a href="https://github.com/finch-xu/cc-router/releases/latest">下载客户端</a> ｜ <a href="https://ccrouter.app/docs/claude-desktop-integration/">官方文档</a></p></blockquote><h2 id="什么是-cc-router"><a href="#什么是-cc-router" class="headerlink" title="什么是 cc-router"></a>什么是 cc-router</h2><p>cc-router 是一个跑在本地的 Anthropic 协议网关，把多家厂商（DeepSeek、Qwen、Kimi、MiMo、MiniMax、GLM、Claude 官方等共 18 家）的订阅聚合成三槽位的虚拟模型 —— 你在客户端只需要选择 <code>claude-opus-4-7</code>、<code>claude-sonnet-4-6</code>、<code>claude-haiku-4-5</code>，cc-router 在背后根据剩余额度、限流状态、可用性自动路由到具体厂商。</p><p><strong>核心特性：</strong></p><ul><li><strong>一站调度</strong> —— 18 家厂商的订阅合成一个虚拟 Plan</li><li><strong>三槽位映射</strong> —— opus &#x2F; sonnet &#x2F; haiku 三个槽位，每个槽位可挂多家厂商</li><li><strong>自动故障转移</strong> —— 当前 provider 限流或失败时自动切到下一个</li><li><strong>HTTPS 本地网关</strong> —— 通过自签 CA 提供 HTTPS 端口，兼容 Claude Desktop 的「Gateway」接入方式</li><li><strong>请求日志</strong> —— 主界面实时显示路由情况，方便调试</li><li><strong>多平台</strong> —— macOS &#x2F; Windows &#x2F; Linux 桌面应用</li><li><strong>三语界面</strong> —— 简体中文 &#x2F; English &#x2F; 日本語</li></ul><h3 id="工作架构"><a href="#工作架构" class="headerlink" title="工作架构"></a>工作架构</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Claude Desktop              cc-router (本地)                上游 Provider</span><br><span class="line">┌──────────────┐           ┌──────────────────┐           ┌────────────┐</span><br><span class="line">│ Anthropic    │──HTTPS──▶ │ HTTPS 网关        │──────────▶│ Claude     │</span><br><span class="line">│ Gateway      │           │ + 虚拟模型路由     │           │ DeepSeek   │</span><br><span class="line">│ (Bearer)     │           │ + 自签 CA 证书     │           │ Kimi / GLM │</span><br><span class="line">└──────────────┘           └──────────────────┘           │ ...        │</span><br><span class="line">                                                           └────────────┘</span><br></pre></td></tr></table></figure><p>Claude Desktop 通过自带的「第三方推理网关」功能调用 cc-router 的 HTTPS 端口，cc-router 再根据你配置的虚拟模型路由规则，把请求转发到实际的上游 provider。整个链路里 Anthropic 官方服务不参与请求，所有上游调用都从你本机发出。</p><h3 id="接入流程一图速览"><a href="#接入流程一图速览" class="headerlink" title="接入流程一图速览"></a>接入流程一图速览</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">               cc-router              系统钥匙串            Claude Desktop</span><br><span class="line">                   │                      │                       │</span><br><span class="line">1. 启用 HTTPS ────▶│                      │                       │</span><br><span class="line">                   │                      │                       │</span><br><span class="line">2. 导出 CA ───────▶│ cc-router-ca.pem     │                       │</span><br><span class="line">                   │                      │                       │</span><br><span class="line">3. 安装 CA ─────────────────────────────▶ │  受信任根证书           │</span><br><span class="line">                   │                      │                       │</span><br><span class="line">4. 开发者模式 ──────────────────────────────────────────────────▶ │ Developer 菜单</span><br><span class="line">                   │                      │                       │</span><br><span class="line">5. Gateway 配置 ────────────────────────────────────────────────▶ │ base URL + token</span><br><span class="line">                   │                      │                       │</span><br><span class="line">6. 选模型发消息 ◀──────────────────────────────────────────────── │ anthropic/...</span><br><span class="line">                   │                                              │</span><br><span class="line">                   ▼ 路由 ▶ 上游 provider                          ▼</span><br><span class="line">                 (日志页可见)                                  收到响应</span><br></pre></td></tr></table></figure><hr><h2 id="前置准备"><a href="#前置准备" class="headerlink" title="前置准备"></a>前置准备</h2><ul><li>cc-router 已安装并至少配置好一个虚拟模型（opus &#x2F; sonnet &#x2F; haiku 任选其一）</li><li>Claude Desktop 已安装（macOS &#x2F; Windows）</li><li>默认走本机回环 <code>127.0.0.1</code> 即可；跨机器使用见步骤二里的「额外 SAN」配置</li></ul><blockquote><p><strong>下载入口：</strong> cc-router 客户端 → <a href="https://github.com/finch-xu/cc-router/releases/latest">GitHub Releases</a>；Claude Desktop → <a href="https://claude.ai/download">claude.ai&#x2F;download</a></p></blockquote><hr><h2 id="步骤一：启用-HTTPS-监听"><a href="#步骤一：启用-HTTPS-监听" class="headerlink" title="步骤一：启用 HTTPS 监听"></a>步骤一：启用 HTTPS 监听</h2><p>Claude Desktop 的「Gateway」接入只支持 HTTPS，所以第一步要让 cc-router 开启 HTTPS 端口。</p><p>打开 cc-router → <strong>设置</strong> → <strong>代理服务</strong>：</p><ul><li>监听协议：选择 <code>仅 HTTPS</code> 或 <code>HTTP + HTTPS</code></li><li>默认端口：<code>23457</code>（被占用时会自动递增）</li></ul><p>修改完成后 <strong>完整退出并重启</strong> cc-router（不是最小化到托盘，要真正退出）。重启后回到设置页记下实际监听端口，后面要填到 Claude Desktop 里。</p><p><img src="/img/cc-router/01-enable-https.png" alt="cc-router 启用 HTTPS 监听"></p><hr><h2 id="步骤二：导出-CA-证书"><a href="#步骤二：导出-CA-证书" class="headerlink" title="步骤二：导出 CA 证书"></a>步骤二：导出 CA 证书</h2><p>cc-router 启用 HTTPS 时会生成一个本地 CA，需要把这个 CA 导入系统受信任根证书库，否则 Claude Desktop 会因为证书链不被信任而直接拒绝连接。</p><p>设置 → <strong>HTTPS 证书</strong> 区域 → 点击「导出 CA」→ 保存为 <code>cc-router-ca.pem</code>（如果你后面要在 Windows 双击安装，可以改成 <code>.crt</code> 后缀）。建议同时记一下 CA 指纹，导入完成后核对一致再点信任。</p><p><strong>跨机器使用？</strong> 如果你打算让另一台机器（比如笔记本、iPad）的 Claude Desktop 连到这台跑着 cc-router 的主机，需要在「额外 SAN」文本框里加上目标机器访问用的 IP 或主机名（一行一个）。失焦后 cc-router 会自动重签证书，然后再重启应用让新证书生效。</p><p><img src="/img/cc-router/02-export-ca.png" alt="cc-router 导出 CA 证书"></p><hr><h2 id="步骤三：把-CA-装进系统信任库"><a href="#步骤三：把-CA-装进系统信任库" class="headerlink" title="步骤三：把 CA 装进系统信任库"></a>步骤三：把 CA 装进系统信任库</h2><p>为什么要做这一步？因为 cc-router 用的是自签 CA，系统默认不信任。把 CA 装进信任库后，由它签发的所有 HTTPS 证书（比如 <code>127.0.0.1</code>、<code>192.168.x.x</code>）才会被 Claude Desktop、浏览器、curl 等客户端接受。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">未安装 CA：                            安装 CA 后：</span><br><span class="line">                                       </span><br><span class="line">cc-router CA  ✗ 系统不信任             cc-router CA  ✓ 受信任根证书</span><br><span class="line">     │                                       │</span><br><span class="line">     └─ 签发 127.0.0.1 证书 ✗ 拒绝            └─ 签发 127.0.0.1 证书 ✓ 接受</span><br><span class="line">              │                                       │</span><br><span class="line">        Claude Desktop                          Claude Desktop</span><br><span class="line">        &quot;unable to verify...&quot;                   正常握手 → 进入业务请求</span><br></pre></td></tr></table></figure><p>不同平台导入方式不同。</p><h3 id="macOS"><a href="#macOS" class="headerlink" title="macOS"></a>macOS</h3><ol><li>双击 <code>cc-router-ca.pem</code>，钥匙串访问会弹出</li></ol><p><img src="/img/cc-router/03-open-cert-file.png" alt="双击证书文件"></p><ol start="2"><li>「钥匙串」下拉框选择 <strong>系统</strong>（不是「登录」），输入管理员密码完成添加</li></ol><p><img src="/img/cc-router/04-grant-install-permission.png" alt="授权安装到系统钥匙串"></p><ol start="3"><li>在系统钥匙串里找到 <code>cc-router local CA</code>，双击展开</li></ol><p><img src="/img/cc-router/05-keychain-open-cert.png" alt="在钥匙串中找到 CA"></p><ol start="4"><li>展开「信任」 → 「使用此证书时」 → 改为 <strong>始终信任</strong>，关闭窗口时再次输入密码确认</li></ol><p><img src="/img/cc-router/06-trust-cert-always.png" alt="设为始终信任"></p><h3 id="Windows"><a href="#Windows" class="headerlink" title="Windows"></a>Windows</h3><ol><li>双击 <code>.pem</code> 或 <code>.crt</code> 文件 → 「安装证书」</li><li>存储位置：<strong>本地计算机</strong>（需要管理员权限）</li><li>证书存储：<strong>手动选择</strong> → <strong>受信任的根证书颁发机构</strong></li><li>完成后在 <code>certmgr.msc</code> 中能查到这个 CA</li></ol><h3 id="Linux"><a href="#Linux" class="headerlink" title="Linux"></a>Linux</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> <span class="built_in">cp</span> cc-router-ca.pem /usr/local/share/ca-certificates/cc-router-ca.crt</span><br><span class="line"><span class="built_in">sudo</span> update-ca-certificates</span><br></pre></td></tr></table></figure><p>注意 Debian&#x2F;Ubuntu 系列要求扩展名为 <code>.crt</code>，所以拷贝时要顺手改后缀。</p><hr><h2 id="步骤四：在-Claude-Desktop-启用开发者模式"><a href="#步骤四：在-Claude-Desktop-启用开发者模式" class="headerlink" title="步骤四：在 Claude Desktop 启用开发者模式"></a>步骤四：在 Claude Desktop 启用开发者模式</h2><p>「第三方推理网关」是 Claude Desktop 的开发者功能，默认不显示。</p><p>打开 Claude Desktop → 顶部菜单 <strong>Help</strong> → <strong>Troubleshooting</strong> → 勾选开发者模式相关选项 → 完全退出 Claude Desktop（不是关闭窗口）→ 重新打开。</p><p>重启后菜单栏会多出一个 <strong>Developer</strong> 菜单，这就是入口。</p><p><img src="/img/cc-router/07-enable-developer-mode.png" alt="Claude Desktop Developer 菜单"></p><hr><h2 id="步骤五：配置网关连接"><a href="#步骤五：配置网关连接" class="headerlink" title="步骤五：配置网关连接"></a>步骤五：配置网关连接</h2><p>Developer 菜单 → <strong>Configure Third-Party Inference</strong>（部分版本启用开发者模式后会自动弹出该窗口）→ <strong>Connection</strong> 标签 → 选择 <strong>Gateway (Anthropic-compatible)</strong>。</p><p><img src="/img/cc-router/09-open-config-from-menu.png" alt="从 Developer 菜单打开配置窗口"></p><p>填写如下字段：</p><table><thead><tr><th>字段</th><th>值</th></tr></thead><tbody><tr><td><strong>Gateway base URL</strong></td><td><code>https://127.0.0.1:23457</code>（本机）或 <code>https://192.168.x.x:23457</code>（局域网）</td></tr><tr><td><strong>Gateway API key</strong></td><td>从 cc-router 设置页复制的 token</td></tr><tr><td><strong>Gateway auth scheme</strong></td><td><code>bearer</code></td></tr></tbody></table><p>填完点击 <strong>Apply locally</strong> 保存。</p><blockquote><p><strong>取 token：</strong> 回到 cc-router → 设置 → 代理服务 → 找到 API Key &#x2F; Token 字段，点击复制按钮。这个 token 等同于访问你所有上游 provider 的凭据，妥善保管。</p></blockquote><p><img src="/img/cc-router/08-configure-gateway.png" alt="Claude Desktop 网关配置"></p><hr><h2 id="步骤六：选择模型并验证"><a href="#步骤六：选择模型并验证" class="headerlink" title="步骤六：选择模型并验证"></a>步骤六：选择模型并验证</h2><p>回到 Claude Desktop 的对话窗口，点击模型选择器（通常在输入框附近），应该能看到带 <code>anthropic/</code> 前缀的虚拟模型：</p><ul><li><code>anthropic/claude-opus-4-7</code></li><li><code>anthropic/claude-sonnet-4-6</code></li><li><code>anthropic/claude-haiku-4-5</code></li></ul><p>任选一个，发一条「你好，请简单介绍下自己」之类的测试消息。</p><p><strong>验证路由是否生效：</strong> 切回 cc-router 主界面，进入「请求日志」页，应该能看到刚刚那条请求被路由到了某个上游 provider（比如 DeepSeek 或 Kimi），并显示了响应耗时、token 数和命中的路由规则。如果日志里没有新条目，说明请求根本没走到 cc-router，回头检查 Claude Desktop 里的 base URL 和端口是不是和 cc-router 实际监听端口一致。</p><p><img src="/img/cc-router/10-model-selector.png" alt="Claude Desktop 模型选择器"></p><p>发完消息后，整条链路是这样跑的 ——</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">Claude Desktop                   cc-router                       上游 provider</span><br><span class="line">     │                              │                                  │</span><br><span class="line">     │  POST /v1/messages           │                                  │</span><br><span class="line">     │  Bearer &lt;token&gt;              │                                  │</span><br><span class="line">     │  model: anthropic/opus-4-7   │                                  │</span><br><span class="line">     ├─────────────────────────────▶│                                  │</span><br><span class="line">     │                              │  匹配虚拟模型 opus → 选 provider  │</span><br><span class="line">     │                              │  （按权重 / 限流状态 / 健康度）   │</span><br><span class="line">     │                              │                                  │</span><br><span class="line">     │                              │  转换为上游协议                   │</span><br><span class="line">     │                              ├─────────────────────────────────▶│</span><br><span class="line">     │                              │                                  │</span><br><span class="line">     │                              │◀─────── stream chunks ──────────│</span><br><span class="line">     │◀─────── stream chunks ──────│                                  │</span><br><span class="line">     │                              │                                  │</span><br><span class="line">     │                              │  写日志：provider / tokens / 耗时 │</span><br></pre></td></tr></table></figure><p>如果某个 provider 返回 429 或 5xx，cc-router 会自动 fallback 到同槽位的下一家，整个过程对 Claude Desktop 透明。</p><hr><h2 id="排错速查"><a href="#排错速查" class="headerlink" title="排错速查"></a>排错速查</h2><table><thead><tr><th>报错信息</th><th>原因</th><th>解决办法</th></tr></thead><tbody><tr><td><code>unable to verify the first certificate</code></td><td>CA 没装好</td><td>重做步骤三；macOS 要确认装到「系统」钥匙串并设为「始终信任」</td></tr><tr><td><code>connection refused</code></td><td>HTTPS 没开 &#x2F; 端口对不上</td><td>cc-router 设置里确认监听协议是 HTTPS 且端口与 base URL 一致</td></tr><tr><td><code>Hostname/IP doesn&#39;t match certificate</code></td><td>用的 IP 不在证书 SAN 列表里</td><td>在「额外 SAN」里加上该 IP，重签证书后重启应用</td></tr><tr><td><code>401 Unauthorized</code></td><td>token 过期或复制错位</td><td>回 cc-router 重新复制最新 API key 粘贴回 Claude Desktop</td></tr><tr><td>模型列表里没有 <code>anthropic/...</code></td><td>网关配置没保存 &#x2F; Claude Desktop 没重启</td><td>检查 Apply locally 是否点了；必要时彻底退出 Claude Desktop 再重开</td></tr><tr><td>日志里没记录请求</td><td>请求没走到 cc-router</td><td>检查 base URL 协议是 <code>https://</code>、IP 端口正确、CA 已信任</td></tr></tbody></table><hr><h2 id="安全提醒"><a href="#安全提醒" class="headerlink" title="安全提醒"></a>安全提醒</h2><ul><li><strong>Gateway API key 等同于你所有上游 provider 的访问权</strong> —— 一旦泄漏，攻击者就能消耗你所有厂商的额度，请勿截图、勿提交到 git、勿粘贴到聊天群</li><li><strong>公网暴露需慎重</strong> —— cc-router 默认监听本机，跨机器使用尽量限制在受信任的局域网；如果非要走公网，请配合反向代理 + 鉴权 + IP 白名单</li><li><strong>CA 是机器级信任</strong> —— 安装到「受信任根证书颁发机构」意味着这个 CA 能为任何域名签证书，所以 CA 文件本身要妥善保管，不要随便发给别人</li></ul><hr><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li>GitHub 仓库：<a href="https://github.com/finch-xu/cc-router">finch-xu&#x2F;cc-router</a></li><li>下载客户端：<a href="https://github.com/finch-xu/cc-router/releases/latest">GitHub Releases</a></li><li>官方主页：<a href="https://ccrouter.app/">ccrouter.app</a></li><li>官方文档：<a href="https://ccrouter.app/docs/claude-desktop-integration/">Claude Desktop 集成指南</a></li></ul>]]>
    </content>
    <id>https://pidan.dev/20260514/cc-router-integrate-claude-desktop/</id>
    <link href="https://pidan.dev/20260514/cc-router-integrate-claude-desktop/"/>
    <published>2026-05-14T12:00:00.000Z</published>
    <summary>
      <![CDATA[<p>如果你同时订阅了 Claude Pro、Kimi、DeepSeek、GLM 等好几家模型服务，每次切换都得换客户端、复制 API key、改环境变量，不如把这些订阅聚合成一个虚拟模型，在 Claude Desktop 里直接选用。cc-router 就是干这件事的本地代理：18 家厂商一站调度、自动故障转移、限流处理、三槽位（opus&#x2F;sonnet&#x2F;haiku）虚拟模型。本文从证书安装到模型验证，按官方推荐的方式把 cc-router 接入 Claude Desktop。</p>]]>
    </summary>
    <title>用 cc-router 接入 Claude Desktop：一个 Token 调度多家模型订阅</title>
    <updated>2026-05-26T14:45:37.884Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="Claude Code" scheme="https://pidan.dev/tags/Claude-Code/"/>
    <category term="远程终端" scheme="https://pidan.dev/tags/%E8%BF%9C%E7%A8%8B%E7%BB%88%E7%AB%AF/"/>
    <category term="Docker" scheme="https://pidan.dev/tags/Docker/"/>
    <content>
      <![CDATA[<p>想在咖啡厅、办公室或手机上用 Claude Code、vim 操作家里的 Mac，但 Mac 在 NAT 后面没有公网 IP？RemoteTTYs 是一个基于 WebSocket 中继的远程终端工具，Agent 主动外连服务器，无需内网穿透、无需开放端口，终端内容端到端加密。本文介绍三种服务端部署方式（公网 HTTPS、局域网、自带反向代理）以及客户端 Agent 的安装配置，帮你在 10 分钟内搭建完成。</p><span id="more"></span><h2 id="什么是-RemoteTTYs"><a href="#什么是-RemoteTTYs" class="headerlink" title="什么是 RemoteTTYs"></a>什么是 RemoteTTYs</h2><p>RemoteTTYs 由三个组件构成：运行在本地 Mac&#x2F;Linux 上的 <strong>Agent</strong>（Go 单文件）主动向远端的 <strong>Relay</strong> 服务器发起 WebSocket 连接，浏览器通过 <strong>Web UI</strong> 打开终端会话。由于连接方向是从内网向外发起的，所以不需要公网 IP、不需要端口映射、不需要 frp&#x2F;Tailscale 等穿透工具。</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">本地机器                       远端服务器                   浏览器</span><br><span class="line">┌──────────────┐             ┌──────────────┐            ┌──────────┐</span><br><span class="line">│  rttys-agent │──outbound──▶│  rttys-relay │◀───HTTPS───│ Web UI   │</span><br><span class="line">│  (Go binary, │   WSS       │  (Node.js)   │   + WSS    │ ghostty  │</span><br><span class="line">│   no open    │◀────────────│              │───────────▶│  -web    │</span><br><span class="line">│   ports)     │             └──────────────┘            └──────────┘</span><br><span class="line">└──────────────┘</span><br></pre></td></tr></table></figure><p><strong>核心特性：</strong></p><ul><li>无需内网穿透 —— Agent 主动外连 Relay，本地无需开放任何端口</li><li>端到端加密（ECDH P-256 + AES-256-GCM）—— Relay 服务器无法读取终端内容</li><li>Ed25519 质询-响应认证 + 机器指纹绑定，防止 Token 被盗用</li><li>Agent 身份密钥 + TOFU 信任模型（类似 SSH），防止中间人攻击</li><li><a href="https://github.com/coder/ghostty-web">ghostty-web</a> 驱动的浏览器终端 —— 真实终端体验，支持颜色、滚动回放、鼠标事件</li><li>多机器仪表盘 + 多标签终端会话</li><li>Go 单文件 Agent，零依赖，守护进程模式自动重连</li><li>JWT 多用户认证，审计日志记录所有操作</li><li>MIT 开源协议，完全自托管</li></ul><blockquote><p><strong>项目地址：</strong> <a href="https://github.com/finch-xu/RemoteTTYs">GitHub - finch-xu&#x2F;RemoteTTYs</a> ｜ <a href="https://docs.pidan.dev/zh/remotettys/">官方文档</a></p></blockquote><hr><h2 id="方式一：公网部署（推荐）"><a href="#方式一：公网部署（推荐）" class="headerlink" title="方式一：公网部署（推荐）"></a>方式一：公网部署（推荐）</h2><p>适合需要从任意网络访问家里机器的场景。Relay 和 Caddy 反向代理一起部署，Caddy 自动签发 HTTPS 证书。</p><h3 id="前置要求"><a href="#前置要求" class="headerlink" title="前置要求"></a>前置要求</h3><ul><li>一台有公网 IP 的服务器，已安装 Docker</li><li>一个域名，DNS 解析指向该服务器</li></ul><h3 id="1-克隆项目"><a href="#1-克隆项目" class="headerlink" title="1. 克隆项目"></a>1. 克隆项目</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/finch-xu/RemoteTTYs.git</span><br><span class="line"><span class="built_in">cd</span> RemoteTTYs</span><br></pre></td></tr></table></figure><h3 id="2-配置-Caddy"><a href="#2-配置-Caddy" class="headerlink" title="2. 配置 Caddy"></a>2. 配置 Caddy</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cp</span> Caddyfile.example Caddyfile</span><br></pre></td></tr></table></figure><p>编辑 <code>Caddyfile</code>，将 <code>rttys.example.com</code> 替换为你的域名：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line">rttys.example.com &#123;</span><br><span class="line">encode gzip zstd</span><br><span class="line"></span><br><span class="line"># deny robots</span><br><span class="line">handle /robots.txt &#123;</span><br><span class="line">                respond `User-agent: *</span><br><span class="line">                Disallow: /` 200</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line"># Security headers</span><br><span class="line">header &#123;</span><br><span class="line">Strict-Transport-Security &quot;max-age=31536000; includeSubDomains; preload&quot;</span><br><span class="line">X-Frame-Options &quot;DENY&quot;</span><br><span class="line">Referrer-Policy &quot;strict-origin-when-cross-origin&quot;</span><br><span class="line">Permissions-Policy &quot;camera=(), microphone=(), geolocation=(), usb=()&quot;</span><br><span class="line">X-Robots-Tag &quot;noindex, nofollow, noarchive&quot;</span><br><span class="line">-Server</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"># Limit request body size (WebSocket upgrades are exempt)</span><br><span class="line">request_body &#123;</span><br><span class="line">max_size 1MB</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">reverse_proxy 172.17.0.1:8080 &#123;</span><br><span class="line"># Pass real client IP to backend for rate limiting</span><br><span class="line">header_up X-Real-IP &#123;remote_host&#125;</span><br><span class="line">header_up X-Forwarded-For &#123;remote_host&#125;</span><br><span class="line">header_up X-Forwarded-Proto &#123;scheme&#125;</span><br><span class="line"></span><br><span class="line"># Disable response buffering for real-time terminal I/O</span><br><span class="line">flush_interval -1</span><br><span class="line"></span><br><span class="line"># WebSocket: max session duration (terminal sessions can reconnect)</span><br><span class="line">stream_timeout 24h</span><br><span class="line"></span><br><span class="line"># Graceful delay before closing WebSocket on config reload</span><br><span class="line">stream_close_delay 5s</span><br><span class="line"></span><br><span class="line"># Upstream connection tuning</span><br><span class="line">transport http &#123;</span><br><span class="line">keepalive        30s</span><br><span class="line">keepalive_interval 15s</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h3 id="3-启动服务"><a href="#3-启动服务" class="headerlink" title="3. 启动服务"></a>3. 启动服务</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose up -d</span><br></pre></td></tr></table></figure><p><code>docker-compose.yml</code> 包含 Relay 和 Caddy 两个服务：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">remotettys:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">ghcr.io/finch-xu/remotettys:latest</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;8080:8080&quot;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./data:/app/data</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line"></span><br><span class="line">  <span class="attr">remotettys-caddy:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">caddy:2-alpine</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;80:80&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;443:443&quot;</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;443:443/udp&quot;</span>   <span class="comment"># HTTP/3 (QUIC)</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./Caddyfile:/etc/caddy/Caddyfile:ro</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">caddy-data:/data</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">caddy-config:/config</span></span><br><span class="line">    <span class="attr">depends_on:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">remotettys</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line"></span><br><span class="line"><span class="attr">volumes:</span></span><br><span class="line">  <span class="attr">caddy-data:</span></span><br><span class="line">  <span class="attr">caddy-config:</span></span><br></pre></td></tr></table></figure><p>Caddy 会自动通过 Let’s Encrypt 签发 TLS 证书，无需额外配置。启动后访问 <code>https://rttys.你的域名.com</code> 即可进入初始设置页面。</p><hr><h2 id="方式二：局域网部署"><a href="#方式二：局域网部署" class="headerlink" title="方式二：局域网部署"></a>方式二：局域网部署</h2><p>适合仅在家庭或办公局域网内使用的场景，无需域名和 HTTPS。</p><h3 id="1-克隆项目-1"><a href="#1-克隆项目-1" class="headerlink" title="1. 克隆项目"></a>1. 克隆项目</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/finch-xu/RemoteTTYs.git</span><br><span class="line"><span class="built_in">cd</span> RemoteTTYs</span><br></pre></td></tr></table></figure><h3 id="2-配置环境变量"><a href="#2-配置环境变量" class="headerlink" title="2. 配置环境变量"></a>2. 配置环境变量</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cp</span> .env.example .<span class="built_in">env</span></span><br></pre></td></tr></table></figure><p>编辑 <code>.env</code>：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">JWT_SECRET=change-me-to-a-random-secret</span><br><span class="line"><span class="comment"># PORT=8080</span></span><br></pre></td></tr></table></figure><blockquote><p><strong>提示：</strong> Docker 镜像默认设置 <code>NODE_ENV=production</code>，这会启用 Cookie 的 <code>Secure</code> 标志，导致浏览器在 HTTP 下不发送 Cookie。局域网部署时，<code>docker-compose-lan.yml</code> 已经自动处理了这个问题。<code>JWT_SECRET</code> 必须设置，否则每次容器重启都会生成随机密钥，导致所有用户被登出。</p></blockquote><h3 id="3-启动服务-1"><a href="#3-启动服务-1" class="headerlink" title="3. 启动服务"></a>3. 启动服务</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose -f docker-compose-lan.yml up -d</span><br></pre></td></tr></table></figure><p><code>docker-compose-lan.yml</code> 仅包含 Relay 服务：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">remotettys:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">ghcr.io/finch-xu/remotettys:latest</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;8080:8080&quot;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./data:/app/data</span></span><br><span class="line">    <span class="attr">env_file:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">path:</span> <span class="string">.env</span></span><br><span class="line">        <span class="attr">required:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br></pre></td></tr></table></figure><p>启动后访问 <code>http://服务器IP:8080</code> 进入初始设置。</p><blockquote><p><strong>提示：</strong> 局域网模式下 Agent 的 relay 地址应使用 <code>ws://</code> 而非 <code>wss://</code>，例如 <code>ws://192.168.1.100:8080/ws/agent</code>。</p></blockquote><hr><h2 id="方式三：自带反向代理"><a href="#方式三：自带反向代理" class="headerlink" title="方式三：自带反向代理"></a>方式三：自带反向代理</h2><p>如果你已经有 nginx、Caddy 或其他反向代理，可以只部署 Relay 后端，自行配置反向代理转发到 8080 端口。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose -f docker-compose-only-backend.yml up -d</span><br></pre></td></tr></table></figure><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">remotettys:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">ghcr.io/finch-xu/remotettys:latest</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;8080:8080&quot;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./data:/app/data</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br></pre></td></tr></table></figure><p>反向代理配置要点：</p><ul><li>WebSocket 支持（<code>/ws/</code> 路径需要升级为 WebSocket 连接）</li><li>禁用响应缓冲（对应 Caddy 的 <code>flush_interval -1</code> &#x2F; nginx 的 <code>proxy_buffering off</code>）</li><li>传递真实客户端 IP（<code>X-Real-IP</code>、<code>X-Forwarded-For</code>、<code>X-Forwarded-Proto</code>）</li></ul><hr><h2 id="三种方式对比"><a href="#三种方式对比" class="headerlink" title="三种方式对比"></a>三种方式对比</h2><table><thead><tr><th>维度</th><th>公网部署</th><th>局域网部署</th><th>自带反向代理</th></tr></thead><tbody><tr><td>适用场景</td><td>任意网络远程访问</td><td>仅局域网内使用</td><td>已有反向代理基础设施</td></tr><tr><td>HTTPS</td><td>Caddy 自动签发</td><td>不需要</td><td>自行配置</td></tr><tr><td>域名</td><td>需要</td><td>不需要</td><td>视情况</td></tr><tr><td>复杂度</td><td>最简单</td><td>最简单</td><td>需要额外配置</td></tr></tbody></table><hr><h2 id="初始设置"><a href="#初始设置" class="headerlink" title="初始设置"></a>初始设置</h2><p>三种部署方式启动后，首次访问 Web UI 都会进入初始设置页面。</p><h3 id="1-创建管理员账号"><a href="#1-创建管理员账号" class="headerlink" title="1. 创建管理员账号"></a>1. 创建管理员账号</h3><p>打开浏览器访问你的 Relay 地址，按提示创建管理员用户名和密码。</p><h3 id="2-获取-Server-Key"><a href="#2-获取-Server-Key" class="headerlink" title="2. 获取 Server Key"></a>2. 获取 Server Key</h3><p>登录后进入 <strong>Settings</strong> 页面，复制 <strong>Server Public Key</strong>（Ed25519 公钥）。Agent 用它来验证服务器身份，防止连接到伪造的 Relay。</p><h3 id="3-创建-Agent-Token"><a href="#3-创建-Agent-Token" class="headerlink" title="3. 创建 Agent Token"></a>3. 创建 Agent Token</h3><p>在 Settings 页面点击创建新的 Agent Token，为你的机器设置一个标签（如 “Home Mac”）。复制生成的 Token，稍后配置 Agent 时使用。</p><hr><h2 id="安装-Agent"><a href="#安装-Agent" class="headerlink" title="安装 Agent"></a>安装 Agent</h2><p>Agent 是运行在你本地 Mac 或 Linux 上的 Go 单文件程序，零依赖。</p><h3 id="1-下载"><a href="#1-下载" class="headerlink" title="1. 下载"></a>1. 下载</h3><p>访问 <a href="https://github.com/finch-xu/RemoteTTYs/releases/latest">Releases 页面</a>，根据你的平台下载对应的二进制文件：</p><table><thead><tr><th>平台</th><th>文件名</th></tr></thead><tbody><tr><td>macOS (Apple Silicon)</td><td><code>rttys-agent-macOS-arm64</code></td></tr><tr><td>macOS (Intel)</td><td><code>rttys-agent-macOS-x64</code></td></tr><tr><td>Linux (x86_64)</td><td><code>rttys-agent-Linux-x64</code></td></tr><tr><td>Linux (ARM64)</td><td><code>rttys-agent-Linux-arm64</code></td></tr></tbody></table><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x rttys-agent-*</span><br><span class="line"><span class="built_in">mv</span> rttys-agent-* rttys-agent</span><br></pre></td></tr></table></figure><h3 id="2-初始化配置"><a href="#2-初始化配置" class="headerlink" title="2. 初始化配置"></a>2. 初始化配置</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./rttys-agent init</span><br></pre></td></tr></table></figure><p>这会在同目录下生成 <code>config.yaml</code>：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">relay:</span> <span class="string">wss://your-server.com/ws/agent</span></span><br><span class="line"><span class="attr">token:</span> <span class="string">your-agent-token</span></span><br><span class="line"><span class="attr">server_key:</span> <span class="string">&lt;base64-encoded-server-public-key&gt;</span></span><br><span class="line"><span class="attr">name:</span> <span class="string">my-machine</span></span><br><span class="line"><span class="attr">shell:</span> <span class="string">/bin/zsh</span></span><br></pre></td></tr></table></figure><p>将 <code>relay</code>、<code>token</code>、<code>server_key</code> 替换为你在上一步中获取的值：</p><ul><li><strong>relay</strong>：你的 Relay 地址（公网用 <code>wss://你的域名/ws/agent</code>，局域网用 <code>ws://IP:8080/ws/agent</code>）</li><li><strong>token</strong>：从 Web UI Settings 页面创建的 Agent Token</li><li><strong>server_key</strong>：从 Web UI Settings 页面复制的 Server Public Key</li></ul><h3 id="3-启动"><a href="#3-启动" class="headerlink" title="3. 启动"></a>3. 启动</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 前台运行（调试用）</span></span><br><span class="line">./rttys-agent</span><br><span class="line"></span><br><span class="line"><span class="comment"># 后台守护进程模式</span></span><br><span class="line">./rttys-agent -d</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看运行状态</span></span><br><span class="line">./rttys-agent status</span><br><span class="line"></span><br><span class="line"><span class="comment"># 停止守护进程</span></span><br><span class="line">./rttys-agent stop</span><br></pre></td></tr></table></figure><p>Agent 会自动重连，退避间隔从 1 秒递增到最大 30 秒。</p><hr><h2 id="开始使用"><a href="#开始使用" class="headerlink" title="开始使用"></a>开始使用</h2><p>Agent 启动并连接成功后，打开浏览器访问你的 Relay Web UI，就能在设备列表中看到你的机器显示为在线状态。点击机器名称即可打开一个终端会话。</p><p>终端由 <a href="https://github.com/coder/ghostty-web">ghostty-web</a>（Ghostty 的 VT100 解析器编译为 WebAssembly）驱动，支持完整的终端特性：256 色、滚动回放、鼠标事件。你可以直接运行：</p><ul><li><code>claude</code> —— 远程使用 Claude Code</li><li><code>vim</code> &#x2F; <code>nvim</code> —— 编辑代码</li><li><code>htop</code> —— 监控系统资源</li><li><code>ssh</code> —— 跳板到其他机器</li></ul><p>支持同时打开多个终端标签页，浏览器断开重连后自动恢复滚动缓冲区（每个会话 1MB）。</p><hr><h2 id="安全模型"><a href="#安全模型" class="headerlink" title="安全模型"></a>安全模型</h2><p>RemoteTTYs 在 Agent 与 Relay 之间建立了三层安全防护：</p><ol><li><strong>HTTP Token 认证</strong> —— Agent 在 WebSocket 升级请求中通过 <code>X-Token</code> 头发送 Token，无效 Token 在连接建立前即被拒绝</li><li><strong>Ed25519 质询-响应</strong> —— WebSocket 建立后，服务器用私钥签名 Agent Token 作为质询，Agent 用预配置的服务器公钥验签，通过后才发送数据</li><li><strong>机器指纹绑定</strong> —— Agent 上报机器唯一 ID 的 SHA-256 哈希，服务器在首次连接时记录，后续连接若不匹配则拒绝，防止 Token 在其他机器上被盗用</li></ol><p>在此基础上，所有终端内容（击键和输出）都经过端到端加密：</p><ul><li><strong>密钥交换</strong>：每个会话使用 ECDH P-256 临时密钥对，提供前向保密</li><li><strong>对称加密</strong>：AES-256-GCM，基于计数器的 nonce 防重放</li><li><strong>MITM 防护</strong>：每个 Agent 有一个 Ed25519 身份密钥，浏览器在首次连接时存储（TOFU 模型，类似 SSH），密钥变化时会弹出警告</li></ul><blockquote><p><strong>建议：</strong> 公网部署务必使用方式一（含 Caddy HTTPS），确保浏览器到 Relay 的连接也被加密。</p></blockquote><hr><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><ul><li>GitHub 仓库：<a href="https://github.com/finch-xu/RemoteTTYs">finch-xu&#x2F;RemoteTTYs</a></li><li>官方文档：<a href="https://docs.pidan.dev/zh/remotettys/">docs.pidan.dev&#x2F;zh&#x2F;remotettys</a></li></ul>]]>
    </content>
    <id>https://pidan.dev/20260413/deploy-remotettys/</id>
    <link href="https://pidan.dev/20260413/deploy-remotettys/"/>
    <published>2026-04-13T12:00:00.000Z</published>
    <summary>
      <![CDATA[<p>想在咖啡厅、办公室或手机上用 Claude Code、vim 操作家里的 Mac，但 Mac 在 NAT 后面没有公网 IP？RemoteTTYs 是一个基于 WebSocket 中继的远程终端工具，Agent 主动外连服务器，无需内网穿透、无需开放端口，终端内容端到端加密。本文介绍三种服务端部署方式（公网 HTTPS、局域网、自带反向代理）以及客户端 Agent 的安装配置，帮你在 10 分钟内搭建完成。</p>]]>
    </summary>
    <title>从浏览器远程访问家里 Mac 终端：RemoteTTYs 部署指南</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <content>
      <![CDATA[<p>本文介绍如何对 FileHunter 的三种搜索模式（sequential、concurrent、latest_modified）进行性能基准测试。使用 wrk 和 curl 工具，从吞吐量、延迟、并发表现三个维度评估各模式在本地磁盘和多目录场景下的性能差异。附完整测试脚本和结果分析方法，帮助你根据实际存储架构选择最优搜索模式。</p><span id="more"></span><h2 id="测试环境准备"><a href="#测试环境准备" class="headerlink" title="测试环境准备"></a>测试环境准备</h2><p>git拉代码</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/finch-xu/filehunter.git</span><br></pre></td></tr></table></figure><h3 id="1-编译-Release-版本"><a href="#1-编译-Release-版本" class="headerlink" title="1. 编译 Release 版本"></a>1. 编译 Release 版本</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">cargo build --release</span><br></pre></td></tr></table></figure><p>Release 模式启用 LTO + strip，性能远优于 debug 构建。</p><blockquote><p>你也可以直接下载release版本，不需要自己编译。</p></blockquote><h3 id="2-准备测试数据"><a href="#2-准备测试数据" class="headerlink" title="2. 准备测试数据"></a>2. 准备测试数据</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 创建测试目录结构</span></span><br><span class="line"><span class="built_in">mkdir</span> -p /tmp/fh-bench/&#123;root-a,root-b,root-c&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成不同大小的测试文件</span></span><br><span class="line"><span class="built_in">dd</span> <span class="keyword">if</span>=/dev/urandom of=/tmp/fh-bench/root-a/small.bin bs=1K count=10</span><br><span class="line"><span class="built_in">dd</span> <span class="keyword">if</span>=/dev/urandom of=/tmp/fh-bench/root-a/medium.bin bs=1K count=500</span><br><span class="line"><span class="built_in">dd</span> <span class="keyword">if</span>=/dev/urandom of=/tmp/fh-bench/root-a/large.bin bs=1M count=5</span><br><span class="line"></span><br><span class="line"><span class="comment"># 在多个目录中放置同名文件（用于测试 concurrent 和 latest_modified）</span></span><br><span class="line"><span class="built_in">cp</span> /tmp/fh-bench/root-a/small.bin /tmp/fh-bench/root-b/small.bin</span><br><span class="line"><span class="built_in">cp</span> /tmp/fh-bench/root-a/small.bin /tmp/fh-bench/root-c/small.bin</span><br><span class="line"></span><br><span class="line"><span class="comment"># 让 root-b 的文件更新（用于验证 latest_modified）</span></span><br><span class="line"><span class="built_in">sleep</span> 1</span><br><span class="line"><span class="built_in">touch</span> /tmp/fh-bench/root-b/small.bin</span><br></pre></td></tr></table></figure><h3 id="3-安装测试工具"><a href="#3-安装测试工具" class="headerlink" title="3. 安装测试工具"></a>3. 安装测试工具</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install wrk</span><br><span class="line"></span><br><span class="line"><span class="comment"># Ubuntu/Debian</span></span><br><span class="line">apt-get install wrk</span><br></pre></td></tr></table></figure><hr><h2 id="三种模式的测试配置"><a href="#三种模式的测试配置" class="headerlink" title="三种模式的测试配置"></a>三种模式的测试配置</h2><p>为每种搜索模式编写独立配置文件：</p><p><strong>config-sequential.toml：</strong></p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;sequential&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-a&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-b&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-c&quot;</span></span><br></pre></td></tr></table></figure><p><strong>config-concurrent.toml：</strong></p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;concurrent&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-a&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-b&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-c&quot;</span></span><br></pre></td></tr></table></figure><p><strong>config-latest.toml：</strong></p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;latest_modified&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-a&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-b&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/tmp/fh-bench/root-c&quot;</span></span><br></pre></td></tr></table></figure><hr><h2 id="执行基准测试"><a href="#执行基准测试" class="headerlink" title="执行基准测试"></a>执行基准测试</h2><h3 id="测试脚本"><a href="#测试脚本" class="headerlink" title="测试脚本"></a>测试脚本</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#!/bin/bash</span></span><br><span class="line"><span class="comment"># bench.sh — FileHunter 三模式基准测试</span></span><br><span class="line"></span><br><span class="line">DURATION=10        <span class="comment"># 每轮测试持续秒数</span></span><br><span class="line">THREADS=4          <span class="comment"># wrk 线程数</span></span><br><span class="line">CONNECTIONS=100    <span class="comment"># 并发连接数</span></span><br><span class="line">FILE=<span class="string">&quot;small.bin&quot;</span>   <span class="comment"># 测试文件名</span></span><br><span class="line">RESULTS=<span class="string">&quot;bench-results.md&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;# FileHunter Benchmark Results&quot;</span> &gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;&quot;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;- Date: <span class="subst">$(date)</span>&quot;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;- Duration: <span class="variable">$&#123;DURATION&#125;</span>s per mode&quot;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;- Threads: <span class="variable">$THREADS</span>, Connections: <span class="variable">$CONNECTIONS</span>&quot;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;&quot;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> MODE <span class="keyword">in</span> sequential concurrent latest_modified; <span class="keyword">do</span></span><br><span class="line">  CONFIG=<span class="string">&quot;config-<span class="variable">$&#123;MODE//_/-&#125;</span>.toml&quot;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 替换 latest_modified 配置文件名的连字符</span></span><br><span class="line">  <span class="keyword">if</span> [ <span class="string">&quot;<span class="variable">$MODE</span>&quot;</span> = <span class="string">&quot;latest_modified&quot;</span> ]; <span class="keyword">then</span></span><br><span class="line">    CONFIG=<span class="string">&quot;config-latest.toml&quot;</span></span><br><span class="line">  <span class="keyword">fi</span></span><br><span class="line"></span><br><span class="line">  <span class="built_in">echo</span> <span class="string">&quot;=== Testing <span class="variable">$MODE</span> ===&quot;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 启动 FileHunter</span></span><br><span class="line">  ./target/release/filehunter --config <span class="string">&quot;<span class="variable">$CONFIG</span>&quot;</span> &amp;</span><br><span class="line">  PID=$!</span><br><span class="line">  <span class="built_in">sleep</span> 1</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 验证服务正常</span></span><br><span class="line">  curl -s http://localhost:8080/health &gt; /dev/null</span><br><span class="line"></span><br><span class="line">  <span class="comment"># 运行 wrk 基准测试</span></span><br><span class="line">  <span class="built_in">echo</span> <span class="string">&quot;## <span class="variable">$MODE</span>&quot;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line">  <span class="built_in">echo</span> <span class="string">&#x27;```&#x27;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line">  wrk -t<span class="variable">$THREADS</span> -c<span class="variable">$CONNECTIONS</span> -d<span class="variable">$&#123;DURATION&#125;</span>s \</span><br><span class="line">    http://localhost:8080/<span class="variable">$FILE</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span> 2&gt;&amp;1</span><br><span class="line">  <span class="built_in">echo</span> <span class="string">&#x27;```&#x27;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line">  <span class="built_in">echo</span> <span class="string">&quot;&quot;</span> &gt;&gt; <span class="string">&quot;<span class="variable">$RESULTS</span>&quot;</span></span><br><span class="line"></span><br><span class="line">  <span class="comment"># 停止服务</span></span><br><span class="line">  <span class="built_in">kill</span> <span class="variable">$PID</span></span><br><span class="line">  <span class="built_in">wait</span> <span class="variable">$PID</span> 2&gt;/dev/null</span><br><span class="line">  <span class="built_in">sleep</span> 1</span><br><span class="line"><span class="keyword">done</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;Results saved to <span class="variable">$RESULTS</span>&quot;</span></span><br></pre></td></tr></table></figure><h3 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">chmod</span> +x bench.sh</span><br><span class="line">./bench.sh</span><br></pre></td></tr></table></figure><hr><h2 id="不同文件大小的测试"><a href="#不同文件大小的测试" class="headerlink" title="不同文件大小的测试"></a>不同文件大小的测试</h2><p>除了对比三种模式，还应测试不同文件大小对吞吐量的影响：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 小文件 (10KB) — 测试请求处理开销</span></span><br><span class="line">wrk -t4 -c100 -d10s http://localhost:8080/small.bin</span><br><span class="line"></span><br><span class="line"><span class="comment"># 中等文件 (500KB) — 平衡场景</span></span><br><span class="line">wrk -t4 -c100 -d10s http://localhost:8080/medium.bin</span><br><span class="line"></span><br><span class="line"><span class="comment"># 大文件 (5MB) — 测试流式传输性能</span></span><br><span class="line">wrk -t4 -c100 -d10s http://localhost:8080/large.bin</span><br></pre></td></tr></table></figure><hr><h2 id="延迟分析"><a href="#延迟分析" class="headerlink" title="延迟分析"></a>延迟分析</h2><p>使用 wrk 的 <code>--latency</code> 参数查看延迟分布：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">wrk -t4 -c100 -d10s --latency http://localhost:8080/small.bin</span><br></pre></td></tr></table></figure><p>输出示例：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Latency Distribution</span><br><span class="line">   50%    1.20ms</span><br><span class="line">   75%    2.10ms</span><br><span class="line">   90%    3.50ms</span><br><span class="line">   99%    8.20ms</span><br></pre></td></tr></table></figure><p>关注 P99 延迟——它反映尾部请求的真实体验。</p><hr><h2 id="预期性能特征"><a href="#预期性能特征" class="headerlink" title="预期性能特征"></a>预期性能特征</h2><p>基于 FileHunter 的架构设计，各模式的预期表现：</p><table><thead><tr><th>指标</th><th>sequential</th><th>concurrent</th><th>latest_modified</th></tr></thead><tbody><tr><td>本地磁盘吞吐</td><td>最高</td><td>略低（spawn 开销）</td><td>略低于 sequential</td></tr><tr><td>本地磁盘延迟</td><td>最低</td><td>略高</td><td>略高</td></tr><tr><td>多目录命中首个</td><td>1 次 I&#x2F;O</td><td>1 次 I&#x2F;O（并行）</td><td>N 次 I&#x2F;O（全部检查）</td></tr><tr><td>多目录全未命中</td><td>N 次 I&#x2F;O</td><td>N 次 I&#x2F;O（并行）</td><td>N 次 I&#x2F;O</td></tr><tr><td>NFS 场景</td><td>延迟叠加</td><td>最优（并行 I&#x2F;O）</td><td>延迟叠加</td></tr></tbody></table><p><strong>关键结论：</strong></p><ul><li><strong>本地磁盘 + 单目录：</strong> 三种模式性能几乎无差异</li><li><strong>本地磁盘 + 多目录：</strong> <code>sequential</code> 开销最小，优先选择</li><li><strong>网络存储 + 多目录：</strong> <code>concurrent</code> 显著减少尾部延迟</li><li><strong>需要最新版本：</strong> <code>latest_modified</code> 是唯一选择，代价是始终扫描所有目录</li></ul><hr><h2 id="调优建议"><a href="#调优建议" class="headerlink" title="调优建议"></a>调优建议</h2><ol><li><strong>增大 <code>stream_buffer_size</code>：</strong> 大文件场景从默认 64KB 提升到 128KB 或 256KB，提高流式传输效率</li></ol><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">stream_buffer_size</span> = <span class="string">&quot;128KB&quot;</span></span><br></pre></td></tr></table></figure><ol start="2"><li><p><strong>启用 HTTP&#x2F;2：</strong> 高并发小文件场景下，HTTP&#x2F;2 多路复用可减少连接开销</p></li><li><p><strong>关闭不需要的功能：</strong> 压缩、CORS 等中间件有 CPU 开销，不需要时保持关闭</p></li><li><p><strong>合理设置 <code>max_file_size</code>：</strong> 避免意外服务超大文件消耗带宽</p></li></ol><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p>配置文件的各字段含义和高级功能（CORS、速率限制、压缩等），请参考 <a href="https://github.com/finch-xu/filehunter/wiki">FileHunter Wiki</a>。</p>]]>
    </content>
    <id>https://pidan.dev/20260228/filehunter-03-performance-testing/</id>
    <link href="https://pidan.dev/20260228/filehunter-03-performance-testing/"/>
    <published>2026-02-28T08:52:12.000Z</published>
    <summary>
      <![CDATA[<p>本文介绍如何对 FileHunter 的三种搜索模式（sequential、concurrent、latest_modified）进行性能基准测试。使用 wrk 和 curl 工具，从吞吐量、延迟、并发表现三个维度评估各模式在本地磁盘和多目录场景下的性能差异。附完整测试脚本和结果分析方法，帮助你根据实际存储架构选择最优搜索模式。</p>]]>
    </summary>
    <title>FileHunter 性能测试：三种搜索模式基准测试实战</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <content>
      <![CDATA[<p>本文通过 5 个真实场景演示 FileHunter 的配置方法：静态资源分发服务、NFS 多节点并发搜索、版本化资产分级存储、内部文件服务器认证保护、公网部署安全加固。每个场景附完整 TOML 配置文件，可直接复制使用。帮助你根据实际业务需求选择合适的搜索模式和安全策略，快速搭建高性能文件服务。</p><table><thead><tr><th>模式</th><th>行为</th><th>最佳场景</th></tr></thead><tbody><tr><td><code>sequential</code></td><td>按配置顺序逐个检查，首次命中即返回</td><td>本地磁盘，需要优先级控制</td></tr><tr><td><code>concurrent</code></td><td>并行探测所有目录，最快响应胜出</td><td>NFS&#x2F;网络存储，延迟不可控</td></tr><tr><td><code>latest_modified</code></td><td>检查所有目录，返回 mtime 最新的文件</td><td>镜像存储，分级部署</td></tr></tbody></table><span id="more"></span><h2 id="场景一：静态资源分发服务"><a href="#场景一：静态资源分发服务" class="headerlink" title="场景一：静态资源分发服务"></a>场景一：静态资源分发服务</h2><p><strong>需求：</strong> Web 应用的图片、文档、视频分目录存放，通过不同 URL 前缀对外提供服务。</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"><span class="attr">max_file_size</span> = <span class="string">&quot;50MB&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[server.cors]</span></span><br><span class="line"><span class="attr">enabled</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">allow_origins</span> = [<span class="string">&quot;https://app.example.com&quot;</span>]</span><br><span class="line"><span class="attr">allow_methods</span> = [<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;HEAD&quot;</span>]</span><br><span class="line"><span class="attr">max_age</span> = <span class="number">3600</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/images&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;sequential&quot;</span></span><br><span class="line"><span class="attr">max_file_size</span> = <span class="string">&quot;20MB&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/images&quot;</span></span><br><span class="line"><span class="attr">extensions</span> = [<span class="string">&quot;jpg&quot;</span>, <span class="string">&quot;jpeg&quot;</span>, <span class="string">&quot;png&quot;</span>, <span class="string">&quot;gif&quot;</span>, <span class="string">&quot;webp&quot;</span>, <span class="string">&quot;svg&quot;</span>]</span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/docs&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;sequential&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/documents&quot;</span></span><br><span class="line"><span class="attr">extensions</span> = [<span class="string">&quot;pdf&quot;</span>, <span class="string">&quot;docx&quot;</span>, <span class="string">&quot;xlsx&quot;</span>]</span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/videos&quot;</span></span><br><span class="line"><span class="attr">max_file_size</span> = <span class="string">&quot;500MB&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/videos&quot;</span></span><br><span class="line"><span class="attr">extensions</span> = [<span class="string">&quot;mp4&quot;</span>, <span class="string">&quot;mkv&quot;</span>, <span class="string">&quot;webm&quot;</span>]</span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li>三个前缀各自限定文件类型，防止越权访问</li><li>每个 location 可独立设置 <code>max_file_size</code>，视频允许更大文件</li><li>CORS 配置允许前端跨域请求文件</li><li>请求 <code>GET /images/logo.png</code> → 在 <code>/data/images</code> 中搜索 <code>logo.png</code></li></ul><hr><h2 id="场景二：NFS-多节点并发搜索"><a href="#场景二：NFS-多节点并发搜索" class="headerlink" title="场景二：NFS 多节点并发搜索"></a>场景二：NFS 多节点并发搜索</h2><p><strong>需求：</strong> 文件分布在多台 NFS 服务器上，延迟不可预测，需要最快响应。</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"><span class="attr">connection_timeout</span> = <span class="number">600</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/shared&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;concurrent&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/mnt/nfs-node-a/files&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/mnt/nfs-node-b/files&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/mnt/nfs-node-c/files&quot;</span></span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li><code>concurrent</code> 模式同时探测所有 NFS 节点，第一个响应的胜出</li><li>剩余探测任务立即取消，避免资源浪费</li><li><code>connection_timeout = 600</code> 适应慢速网络存储</li><li>适用于网络延迟高、节点性能不均的环境</li><li>注意：结果不确定性——同一文件在多个节点上存在时，不同请求可能返回不同节点的副本</li></ul><hr><h2 id="场景三：版本化资产的分级存储"><a href="#场景三：版本化资产的分级存储" class="headerlink" title="场景三：版本化资产的分级存储"></a>场景三：版本化资产的分级存储</h2><p><strong>需求：</strong> 同一文件在生产、预发布、归档目录中可能有不同版本，始终提供最新版本。</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/assets&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;latest_modified&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/production&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/staging&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/archive&quot;</span></span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li><code>latest_modified</code> 模式检查所有目录，返回修改时间（mtime）最新的文件</li><li>推送新版本到 staging 目录后立即生效，无需操作 production 目录</li><li>该模式无法提前退出，必须扫描所有 root 后才能决定返回哪个文件</li><li>适合灰度发布、分级部署等需要版本管理的场景</li></ul><hr><h2 id="场景四：内部文件服务器-Basic-Auth"><a href="#场景四：内部文件服务器-Basic-Auth" class="headerlink" title="场景四：内部文件服务器 + Basic Auth"></a>场景四：内部文件服务器 + Basic Auth</h2><p><strong>需求：</strong> 团队内部文件共享，需要密码保护，但健康检查接口不受限。</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[server.basic_auth]</span></span><br><span class="line"><span class="attr">enabled</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">username</span> = <span class="string">&quot;team&quot;</span></span><br><span class="line"><span class="attr">password</span> = <span class="string">&quot;your-strong-password&quot;</span></span><br><span class="line"><span class="attr">realm</span> = <span class="string">&quot;internal-docs&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[server.rate_limit]</span></span><br><span class="line"><span class="attr">enabled</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">requests_per_second</span> = <span class="number">20</span></span><br><span class="line"><span class="attr">burst_size</span> = <span class="number">50</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/internal&quot;</span></span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li>Basic Auth 使用常量时间比较防止计时攻击</li><li><code>/health</code> 和 <code>/ready</code> 端点免认证，方便 K8s 探针和负载均衡器</li><li>速率限制防止暴力破解：每 IP 每秒 20 请求，允许 50 的突发</li><li>生产环境建议配合反向代理（Nginx）启用 TLS 保护传输中的凭据</li></ul><hr><h2 id="场景五：公网部署全面安全加固"><a href="#场景五：公网部署全面安全加固" class="headerlink" title="场景五：公网部署全面安全加固"></a>场景五：公网部署全面安全加固</h2><p><strong>需求：</strong> 直接面向公网提供文件下载，需要完整的安全防护。</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"><span class="attr">keepalive</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">connection_timeout</span> = <span class="number">300</span></span><br><span class="line"><span class="attr">max_header_size</span> = <span class="string">&quot;16KB&quot;</span></span><br><span class="line"><span class="attr">max_headers</span> = <span class="number">100</span></span><br><span class="line"><span class="attr">max_body_size</span> = <span class="string">&quot;1MB&quot;</span></span><br><span class="line"><span class="attr">max_file_size</span> = <span class="string">&quot;50MB&quot;</span></span><br><span class="line"><span class="attr">stream_buffer_size</span> = <span class="string">&quot;128KB&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[server.cors]</span></span><br><span class="line"><span class="attr">enabled</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">allow_origins</span> = [<span class="string">&quot;*&quot;</span>]</span><br><span class="line"><span class="attr">allow_methods</span> = [<span class="string">&quot;GET&quot;</span>, <span class="string">&quot;HEAD&quot;</span>]</span><br><span class="line"><span class="attr">max_age</span> = <span class="number">86400</span></span><br><span class="line"></span><br><span class="line"><span class="section">[server.rate_limit]</span></span><br><span class="line"><span class="attr">enabled</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">requests_per_second</span> = <span class="number">50</span></span><br><span class="line"><span class="attr">burst_size</span> = <span class="number">100</span></span><br><span class="line"><span class="attr">cleanup_interval</span> = <span class="number">300</span></span><br><span class="line"></span><br><span class="line"><span class="section">[server.compression]</span></span><br><span class="line"><span class="attr">enabled</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">algorithms</span> = [<span class="string">&quot;gzip&quot;</span>, <span class="string">&quot;br&quot;</span>]</span><br><span class="line"><span class="attr">min_size</span> = <span class="string">&quot;1KB&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/public&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;sequential&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/public-assets&quot;</span></span><br><span class="line"><span class="attr">extensions</span> = [<span class="string">&quot;jpg&quot;</span>, <span class="string">&quot;png&quot;</span>, <span class="string">&quot;webp&quot;</span>, <span class="string">&quot;pdf&quot;</span>, <span class="string">&quot;csv&quot;</span>, <span class="string">&quot;json&quot;</span>]</span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;sequential&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/general&quot;</span></span><br></pre></td></tr></table></figure><p><strong>要点：</strong></p><ul><li><code>connection_timeout</code> 防御慢速连接（Slowloris）攻击</li><li><code>max_header_size</code> &#x2F; <code>max_body_size</code> 限制请求大小</li><li>速率限制防止 DDoS 滥用，超限返回 429</li><li>gzip + Brotli 压缩减小文本类文件传输体积</li><li><code>extensions</code> 白名单确保只暴露预期的文件类型</li><li>FileHunter 内置 <code>X-Content-Type-Options: nosniff</code>、路径遍历防护、dotfile 屏蔽等安全机制</li></ul><hr><h2 id="三种搜索模式速查"><a href="#三种搜索模式速查" class="headerlink" title="三种搜索模式速查"></a>三种搜索模式速查</h2><table><thead><tr><th>模式</th><th>行为</th><th>最佳场景</th></tr></thead><tbody><tr><td><code>sequential</code></td><td>按配置顺序逐个检查，首次命中即返回</td><td>本地磁盘，需要优先级控制</td></tr><tr><td><code>concurrent</code></td><td>并行探测所有目录，最快响应胜出</td><td>NFS&#x2F;网络存储，延迟不可控</td></tr><tr><td><code>latest_modified</code></td><td>检查所有目录，返回 mtime 最新的文件</td><td>镜像存储，分级部署</td></tr></tbody></table><blockquote><p>单目录场景下三种模式行为完全一致，使用默认的 <code>sequential</code> 即可。</p></blockquote><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p>配置文件的各字段含义和高级功能（CORS、速率限制、压缩等），请参考 <a href="https://github.com/finch-xu/filehunter/wiki">FileHunter Wiki</a>。</p>]]>
    </content>
    <id>https://pidan.dev/20260227/filehunter-02-usage-scenarios/</id>
    <link href="https://pidan.dev/20260227/filehunter-02-usage-scenarios/"/>
    <published>2026-02-27T04:16:30.000Z</published>
    <summary>
      <![CDATA[<p>本文通过 5 个真实场景演示 FileHunter 的配置方法：静态资源分发服务、NFS 多节点并发搜索、版本化资产分级存储、内部文件服务器认证保护、公网部署安全加固。每个场景附完整 TOML 配置文件，可直接复制使用。帮助你根据实际业务需求选择合适的搜索模式和安全策略，快速搭建高性能文件服务。</p>
<table>
<thead>
<tr>
<th>模式</th>
<th>行为</th>
<th>最佳场景</th>
</tr>
</thead>
<tbody><tr>
<td><code>sequential</code></td>
<td>按配置顺序逐个检查，首次命中即返回</td>
<td>本地磁盘，需要优先级控制</td>
</tr>
<tr>
<td><code>concurrent</code></td>
<td>并行探测所有目录，最快响应胜出</td>
<td>NFS&#x2F;网络存储，延迟不可控</td>
</tr>
<tr>
<td><code>latest_modified</code></td>
<td>检查所有目录，返回 mtime 最新的文件</td>
<td>镜像存储，分级部署</td>
</tr>
</tbody></table>]]>
    </summary>
    <title>FileHunter 实战：5 个场景配置详解</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <content>
      <![CDATA[<p>FileHunter 是一款用 Rust 编写的高性能多路径文件搜索 HTTP 服务器，编译后仅约 3MB。本文介绍三种部署方式：从 GitHub Release 下载预构建二进制文件、Docker 容器化部署、从源码编译。涵盖配置文件编写、Docker Compose 编排、systemd 服务管理的完整流程，帮助你在 5 分钟内将 FileHunter 部署到生产环境。适合需要跨目录文件服务、静态资源分发的运维和后端开发者。</p><span id="more"></span><h2 id="什么是-FileHunter"><a href="#什么是-FileHunter" class="headerlink" title="什么是 FileHunter"></a>什么是 FileHunter</h2><p>FileHunter 通过 URL 前缀路由请求到不同的文件搜索目录组，找到文件后以 chunked streaming 方式返回，找不到则返回 404。典型场景：文件分散在多个存储路径，需要通过统一的 HTTP 接口对外提供服务。</p><p><strong>核心特性：</strong></p><ul><li>多前缀 URL 路由，按 location 隔离不同类型文件</li><li>三种搜索模式：顺序、并发、最新修改时间</li><li>自动协商 HTTP&#x2F;1.1 &amp; HTTP&#x2F;2</li><li>路径遍历防护、dotfile 屏蔽等安全加固</li><li>可选 Basic Auth、CORS、速率限制、响应压缩</li></ul><hr><h2 id="方式一：从-GitHub-Release-下载二进制文件"><a href="#方式一：从-GitHub-Release-下载二进制文件" class="headerlink" title="方式一：从 GitHub Release 下载二进制文件"></a>方式一：从 GitHub Release 下载二进制文件</h2><p>最快的上手方式——直接下载预构建的二进制文件，无需安装 Rust 工具链。</p><h3 id="1-下载"><a href="#1-下载" class="headerlink" title="1. 下载"></a>1. 下载</h3><p>访问 <a href="https://github.com/finch-xu/filehunter/releases/latest">Releases 页面</a>，根据你的系统架构选择对应的压缩包：</p><table><thead><tr><th>平台</th><th>文件名</th></tr></thead><tbody><tr><td>Linux x86_64 (glibc)</td><td><code>filehunter-x86_64-unknown-linux-gnu.tar.gz</code></td></tr><tr><td>Linux x86_64 (musl&#x2F;Alpine)</td><td><code>filehunter-x86_64-unknown-linux-musl.tar.gz</code></td></tr><tr><td>Linux ARM64 (glibc)</td><td><code>filehunter-aarch64-unknown-linux-gnu.tar.gz</code></td></tr><tr><td>Linux ARM64 (musl&#x2F;Alpine)</td><td><code>filehunter-aarch64-unknown-linux-musl.tar.gz</code></td></tr><tr><td>macOS x86_64 (Intel)</td><td><code>filehunter-x86_64-apple-darwin.tar.gz</code></td></tr><tr><td>macOS ARM64 (Apple Silicon)</td><td><code>filehunter-aarch64-apple-darwin.tar.gz</code></td></tr></tbody></table><p>命令行下载示例（以 Linux x86_64 为例）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 下载最新版本</span></span><br><span class="line">curl -LO https://github.com/finch-xu/filehunter/releases/latest/download/filehunter-x86_64-unknown-linux-gnu.tar.gz</span><br><span class="line"></span><br><span class="line"><span class="comment"># 校验完整性（可选）</span></span><br><span class="line">curl -LO https://github.com/finch-xu/filehunter/releases/latest/download/checksums-sha256.txt</span><br><span class="line"><span class="built_in">sha256sum</span> -c checksums-sha256.txt --ignore-missing</span><br><span class="line"></span><br><span class="line"><span class="comment"># 解压</span></span><br><span class="line">tar xzf filehunter-x86_64-unknown-linux-gnu.tar.gz</span><br><span class="line"></span><br><span class="line"><span class="comment"># 移动到系统路径（可选）</span></span><br><span class="line"><span class="built_in">sudo</span> <span class="built_in">mv</span> filehunter /usr/local/bin/</span><br></pre></td></tr></table></figure><blockquote><p><strong>提示：</strong> musl 版本为静态链接，适合 Alpine Linux 或无 glibc 的极简环境。</p></blockquote><h3 id="2-编写配置文件"><a href="#2-编写配置文件" class="headerlink" title="2. 编写配置文件"></a>2. 编写配置文件</h3><p>创建 <code>config.toml</code>：</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"><span class="attr">max_file_size</span> = <span class="string">&quot;10MB&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/files&quot;</span></span><br></pre></td></tr></table></figure><p>这是最简配置：监听 8080 端口，所有请求路由到 <code>/data/files</code> 目录。</p><h3 id="3-启动"><a href="#3-启动" class="headerlink" title="3. 启动"></a>3. 启动</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">filehunter --config config.toml</span><br></pre></td></tr></table></figure><p>开启 debug 日志查看请求详情：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">RUST_LOG=filehunter=debug filehunter --config config.toml</span><br></pre></td></tr></table></figure><h3 id="4-验证"><a href="#4-验证" class="headerlink" title="4. 验证"></a>4. 验证</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 健康检查</span></span><br><span class="line">curl http://localhost:8080/health</span><br><span class="line"></span><br><span class="line"><span class="comment"># 请求文件（假设 /data/files/photo.jpg 存在）</span></span><br><span class="line">curl -I http://localhost:8080/photo.jpg</span><br></pre></td></tr></table></figure><h3 id="5-注册为-systemd-服务（可选）"><a href="#5-注册为-systemd-服务（可选）" class="headerlink" title="5. 注册为 systemd 服务（可选）"></a>5. 注册为 systemd 服务（可选）</h3><p>创建 <code>/etc/systemd/system/filehunter.service</code>：</p><figure class="highlight ini"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[Unit]</span></span><br><span class="line"><span class="attr">Description</span>=FileHunter File Search Server</span><br><span class="line"><span class="attr">After</span>=network.target</span><br><span class="line"></span><br><span class="line"><span class="section">[Service]</span></span><br><span class="line"><span class="attr">Type</span>=simple</span><br><span class="line"><span class="attr">ExecStart</span>=/usr/local/bin/filehunter --config /etc/filehunter/config.toml</span><br><span class="line"><span class="attr">Environment</span>=RUST_LOG=filehunter=info</span><br><span class="line"><span class="attr">Restart</span>=<span class="literal">on</span>-failure</span><br><span class="line"><span class="attr">User</span>=filehunter</span><br><span class="line"><span class="attr">Group</span>=filehunter</span><br><span class="line"><span class="attr">NoNewPrivileges</span>=<span class="literal">true</span></span><br><span class="line"><span class="attr">ProtectSystem</span>=strict</span><br><span class="line"><span class="attr">ReadOnlyPaths</span>=/data</span><br><span class="line"></span><br><span class="line"><span class="section">[Install]</span></span><br><span class="line"><span class="attr">WantedBy</span>=multi-user.target</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">sudo</span> systemctl daemon-reload</span><br><span class="line"><span class="built_in">sudo</span> systemctl <span class="built_in">enable</span> --now filehunter</span><br></pre></td></tr></table></figure><hr><h2 id="方式二：Docker-部署"><a href="#方式二：Docker-部署" class="headerlink" title="方式二：Docker 部署"></a>方式二：Docker 部署</h2><h3 id="1-准备配置文件"><a href="#1-准备配置文件" class="headerlink" title="1. 准备配置文件"></a>1. 准备配置文件</h3><p><code>config.toml</code>（路径必须与容器内 volume 挂载路径一致）：</p><figure class="highlight toml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[server]</span></span><br><span class="line"><span class="attr">bind</span> = <span class="string">&quot;0.0.0.0:8080&quot;</span></span><br><span class="line"><span class="attr">max_file_size</span> = <span class="string">&quot;50MB&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/images&quot;</span></span><br><span class="line"><span class="attr">mode</span> = <span class="string">&quot;sequential&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/images&quot;</span></span><br><span class="line"><span class="attr">extensions</span> = [<span class="string">&quot;jpg&quot;</span>, <span class="string">&quot;png&quot;</span>, <span class="string">&quot;webp&quot;</span>]</span><br><span class="line"></span><br><span class="line"><span class="section">[[locations]]</span></span><br><span class="line"><span class="attr">prefix</span> = <span class="string">&quot;/&quot;</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[locations.paths]]</span></span><br><span class="line"><span class="attr">root</span> = <span class="string">&quot;/data/general&quot;</span></span><br></pre></td></tr></table></figure><h3 id="2-使用-GHCR-预构建镜像（推荐）"><a href="#2-使用-GHCR-预构建镜像（推荐）" class="headerlink" title="2. 使用 GHCR 预构建镜像（推荐）"></a>2. 使用 GHCR 预构建镜像（推荐）</h3><p>无需本地编译，直接拉取官方镜像（支持 amd64 和 arm64）：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">docker run -d \</span><br><span class="line">  --name filehunter \</span><br><span class="line">  -p 8080:8080 \</span><br><span class="line">  --read-only \</span><br><span class="line">  --security-opt no-new-privileges:<span class="literal">true</span> \</span><br><span class="line">  --cap-drop ALL \</span><br><span class="line">  -v ./config.toml:/etc/filehunter/config.toml:ro \</span><br><span class="line">  -v /data/images:/data/images:ro \</span><br><span class="line">  -v /data/general:/data/general:ro \</span><br><span class="line">  ghcr.io/finch-xu/filehunter:latest</span><br></pre></td></tr></table></figure><h3 id="3-Docker-Compose（推荐）"><a href="#3-Docker-Compose（推荐）" class="headerlink" title="3. Docker Compose（推荐）"></a>3. Docker Compose（推荐）</h3><p>创建 <code>docker-compose.yml</code>：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">filehunter:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">ghcr.io/finch-xu/filehunter:latest</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;8080:8080&quot;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./config.toml:/etc/filehunter/config.toml:ro</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">/data/images:/data/images:ro</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">/data/general:/data/general:ro</span></span><br><span class="line">    <span class="attr">read_only:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">security_opt:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="literal">no</span><span class="string">-new-privileges:true</span></span><br><span class="line">    <span class="attr">cap_drop:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">ALL</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker compose up -d</span><br></pre></td></tr></table></figure><blockquote><p><strong>提示：</strong> 每个 <code>config.toml</code> 中的 <code>root</code> 路径都需要对应一条 volume 挂载。增减 location 时同步更新 <code>volumes</code> 列表。</p></blockquote><p>安全加固说明：</p><ul><li><code>read_only: true</code>：容器根文件系统只读</li><li><code>cap_drop: ALL</code>：移除所有 Linux capabilities</li><li><code>no-new-privileges</code>：禁止提权</li><li>所有 volume 均以 <code>:ro</code> 只读挂载</li></ul><h3 id="4-本地构建镜像（可选）"><a href="#4-本地构建镜像（可选）" class="headerlink" title="4. 本地构建镜像（可选）"></a>4. 本地构建镜像（可选）</h3><p>如果需要自定义 Dockerfile：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">docker build -t filehunter .</span><br><span class="line">docker run -d -p 8080:8080 \</span><br><span class="line">  -v ./config.toml:/etc/filehunter/config.toml:ro \</span><br><span class="line">  -v /data/files:/data/files:ro \</span><br><span class="line">  filehunter:latest</span><br></pre></td></tr></table></figure><hr><h2 id="方式三：从源码编译"><a href="#方式三：从源码编译" class="headerlink" title="方式三：从源码编译"></a>方式三：从源码编译</h2><p>适合需要自定义修改或贡献代码的开发者。</p><h3 id="1-前置要求"><a href="#1-前置要求" class="headerlink" title="1. 前置要求"></a>1. 前置要求</h3><ul><li>Rust 1.93+（edition 2024）</li></ul><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装 Rust（如未安装）</span></span><br><span class="line">curl --proto <span class="string">&#x27;=https&#x27;</span> --tlsv1.2 -sSf https://sh.rustup.rs | sh</span><br></pre></td></tr></table></figure><h3 id="2-编译"><a href="#2-编译" class="headerlink" title="2. 编译"></a>2. 编译</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/finch-xu/filehunter.git</span><br><span class="line"><span class="built_in">cd</span> filehunter</span><br><span class="line"></span><br><span class="line"><span class="comment"># Release 编译，启用 LTO + strip，产物约 3MB</span></span><br><span class="line">cargo build --release</span><br></pre></td></tr></table></figure><p>编译产物位于 <code>./target/release/filehunter</code>。</p><h3 id="3-运行"><a href="#3-运行" class="headerlink" title="3. 运行"></a>3. 运行</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./target/release/filehunter --config config.toml</span><br></pre></td></tr></table></figure><p>后续的配置文件编写、验证、systemd 注册步骤与方式一相同。</p><hr><h2 id="三种方式对比"><a href="#三种方式对比" class="headerlink" title="三种方式对比"></a>三种方式对比</h2><table><thead><tr><th>维度</th><th>Release 二进制</th><th>Docker 部署</th><th>源码编译</th></tr></thead><tbody><tr><td>上手速度</td><td>最快，下载即用</td><td>快，需容器运行时</td><td>最慢，需 Rust 工具链</td></tr><tr><td>资源占用</td><td>最小（~3MB）</td><td>多一层容器开销</td><td>编译时占用较多</td></tr><tr><td>隔离性</td><td>依赖 systemd 加固</td><td>天然容器隔离</td><td>同 Release 二进制</td></tr><tr><td>自定义灵活性</td><td>无法修改源码</td><td>可自定义 Dockerfile</td><td>完全自定义</td></tr><tr><td>适用场景</td><td>大多数生产环境</td><td>K8s&#x2F;容器编排环境</td><td>开发者&#x2F;贡献者</td></tr></tbody></table><hr><h2 id="下一步"><a href="#下一步" class="headerlink" title="下一步"></a>下一步</h2><p>配置文件的各字段含义和高级功能（CORS、速率限制、压缩等），请参考 <a href="https://github.com/finch-xu/filehunter/wiki">FileHunter Wiki</a>。</p>]]>
    </content>
    <id>https://pidan.dev/20260226/filehunter-01-deploy-filehunter/</id>
    <link href="https://pidan.dev/20260226/filehunter-01-deploy-filehunter/"/>
    <published>2026-02-26T08:04:33.000Z</published>
    <summary>
      <![CDATA[<p>FileHunter 是一款用 Rust 编写的高性能多路径文件搜索 HTTP 服务器，编译后仅约 3MB。本文介绍三种部署方式：从 GitHub Release 下载预构建二进制文件、Docker 容器化部署、从源码编译。涵盖配置文件编写、Docker Compose 编排、systemd 服务管理的完整流程，帮助你在 5 分钟内将 FileHunter 部署到生产环境。适合需要跨目录文件服务、静态资源分发的运维和后端开发者。</p>]]>
    </summary>
    <title>FileHunter 部署指南：三种方式快速上手</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="评测" scheme="https://pidan.dev/categories/%E8%AF%84%E6%B5%8B/"/>
    <category term="爪云" scheme="https://pidan.dev/tags/%E7%88%AA%E4%BA%91/"/>
    <category term="Claw Cloud" scheme="https://pidan.dev/tags/Claw-Cloud/"/>
    <category term="vps" scheme="https://pidan.dev/tags/vps/"/>
    <category term="云主机" scheme="https://pidan.dev/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA/"/>
    <category term="评测" scheme="https://pidan.dev/tags/%E8%AF%84%E6%B5%8B/"/>
    <content>
      <![CDATA[<p>测评一下爪云Claw Cloud <a href="https://claw.cloud/">https://claw.cloud</a> 日本东京小机，阿里云机房，2C2G，40G硬盘，1G带宽。<br>先说结论：阿里云东京机房，路由线路很好。    </p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E4%B8%89%E7%BD%91%E5%9B%9E%E7%A8%8B%E8%B7%AF%E7%94%B1%E6%A3%80%E6%B5%8B.webp" alt="三网回程路由线路测试"></p><span id="more"></span><h2 id="CPU内存测试"><a href="#CPU内存测试" class="headerlink" title="CPU内存测试"></a>CPU内存测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/CPU%E5%86%85%E5%AD%98%E6%B5%8B%E8%AF%95.webp" alt="CPU内存测试"></p><h2 id="磁盘性能测试"><a href="#磁盘性能测试" class="headerlink" title="磁盘性能测试"></a>磁盘性能测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E7%A1%AC%E7%9B%98%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95.webp" alt="磁盘性能测试"></p><h2 id="北京去程路由线路测试"><a href="#北京去程路由线路测试" class="headerlink" title="北京去程路由线路测试"></a>北京去程路由线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E5%8C%97%E4%BA%AC%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1%E6%B5%8B%E8%AF%95.webp" alt="北京去程路由线路测试"></p><h2 id="三网回程路由线路测试"><a href="#三网回程路由线路测试" class="headerlink" title="三网回程路由线路测试"></a>三网回程路由线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E4%B8%89%E7%BD%91%E5%9B%9E%E7%A8%8B%E8%B7%AF%E7%94%B1%E6%A3%80%E6%B5%8B.webp" alt="三网回程路由线路测试"></p><h2 id="上游及回程线路测试"><a href="#上游及回程线路测试" class="headerlink" title="上游及回程线路测试"></a>上游及回程线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E4%B8%8A%E6%B8%B8%E5%8F%8A%E5%9B%9E%E7%A8%8B%E7%BA%BF%E8%B7%AF%E6%A3%80%E6%B5%8B.webp" alt="上游及回程线路测试"></p><h2 id="全国Ping"><a href="#全国Ping" class="headerlink" title="全国Ping"></a>全国Ping</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E5%85%A8%E5%9B%BDping.webp" alt="全国Ping"></p><h2 id="Ping各大服务商"><a href="#Ping各大服务商" class="headerlink" title="Ping各大服务商"></a>Ping各大服务商</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/PING%E5%90%84%E5%A4%A7%E6%9C%8D%E5%8A%A1%E5%95%86.webp" alt="Ping各大服务商"></p><h2 id="网络带宽上传下载测速"><a href="#网络带宽上传下载测速" class="headerlink" title="网络带宽上传下载测速"></a>网络带宽上传下载测速</h2><p>入站带宽1G，出站带宽1G。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E7%BD%91%E7%BB%9C%E5%B8%A6%E5%AE%BD%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E6%B5%8B%E9%80%9F.webp" alt="网络带宽上传下载测速"></p><h2 id="跨国平台解锁"><a href="#跨国平台解锁" class="headerlink" title="跨国平台解锁"></a>跨国平台解锁</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E8%B7%A8%E5%9B%BD%E5%B9%B3%E5%8F%B0%E8%A7%A3%E9%94%81.webp" alt="跨国平台解锁"></p><h2 id="IP质量检测-IPV4"><a href="#IP质量检测-IPV4" class="headerlink" title="IP质量检测-IPV4"></a>IP质量检测-IPV4</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/IP%E8%B4%A8%E9%87%8F%E6%A3%80%E6%B5%8B.webp" alt="IP质量检测-IPV4"></p><h2 id="测试脚本"><a href="#测试脚本" class="headerlink" title="测试脚本"></a>测试脚本</h2><p>使用 <a href="https://github.com/oneclickvirt/ecs">https://github.com/oneclickvirt/ecs</a> 开源项目</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> noninteractive=<span class="literal">true</span> &amp;&amp; curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh &amp;&amp; <span class="built_in">chmod</span> +x goecs.sh &amp;&amp; ./goecs.sh <span class="built_in">env</span> &amp;&amp; ./goecs.sh install &amp;&amp; goecs</span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://pidan.dev/20251129/test-claw-cloud-vps-jp-tokoy-alibaba/</id>
    <link href="https://pidan.dev/20251129/test-claw-cloud-vps-jp-tokoy-alibaba/"/>
    <published>2025-11-29T08:56:36.000Z</published>
    <summary>
      <![CDATA[<p>测评一下爪云Claw Cloud <a href="https://claw.cloud/">https://claw.cloud</a> 日本东京小机，阿里云机房，2C2G，40G硬盘，1G带宽。<br>先说结论：阿里云东京机房，路由线路很好。    </p>
<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/2025112916351013/%E4%B8%89%E7%BD%91%E5%9B%9E%E7%A8%8B%E8%B7%AF%E7%94%B1%E6%A3%80%E6%B5%8B.webp" alt="三网回程路由线路测试"></p>]]>
    </summary>
    <title>测评VPS 爪云Claw cloud日本东京阿里云机房</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="评测" scheme="https://pidan.dev/categories/%E8%AF%84%E6%B5%8B/"/>
    <category term="vps" scheme="https://pidan.dev/tags/vps/"/>
    <category term="云主机" scheme="https://pidan.dev/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA/"/>
    <category term="评测" scheme="https://pidan.dev/tags/%E8%AF%84%E6%B5%8B/"/>
    <category term="谷歌云" scheme="https://pidan.dev/tags/%E8%B0%B7%E6%AD%8C%E4%BA%91/"/>
    <category term="Google Cloud" scheme="https://pidan.dev/tags/Google-Cloud/"/>
    <content>
      <![CDATA[<p>谷歌永久免费小机，配置2C1G，带宽没写实测1G到10G之间，每月200G标准流量免费，免费30G标准存储，选了美国西海岸俄勒冈us-west1-a机房。<br>先说结论：回国网络延时较差，国际网络状况非常好，硬盘性能太差。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E5%8C%97%E4%BA%AC%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1-%E5%B1%80%E9%83%A8%E6%94%BE%E5%A4%A7.webp" alt="北京去程路由-局部放大"></p><span id="more"></span><h2 id="CPU内存测试"><a href="#CPU内存测试" class="headerlink" title="CPU内存测试"></a>CPU内存测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/cpu%E5%92%8C%E5%86%85%E5%AD%98%E6%B5%8B%E8%AF%95.webp" alt="CPU内存测试"></p><h2 id="磁盘性能测试"><a href="#磁盘性能测试" class="headerlink" title="磁盘性能测试"></a>磁盘性能测试</h2><p>硬盘性能太差。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E7%A1%AC%E7%9B%98%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95.webp" alt="磁盘性能测试"></p><h2 id="北京去程路由线路测试"><a href="#北京去程路由线路测试" class="headerlink" title="北京去程路由线路测试"></a>北京去程路由线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E5%8C%97%E4%BA%AC%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1.webp" alt="北京去程路由线路测试"></p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E5%8C%97%E4%BA%AC%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1-%E5%B1%80%E9%83%A8%E6%94%BE%E5%A4%A7.webp" alt="北京去程路由-局部放大-路由线路测试"></p><h2 id="三网回程路由线路测试"><a href="#三网回程路由线路测试" class="headerlink" title="三网回程路由线路测试"></a>三网回程路由线路测试</h2><p>不绕路，但是线路比较普通比较慢。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E4%B8%89%E7%BD%91%E5%9B%9E%E7%A8%8B%E8%B7%AF%E7%94%B1%E6%A3%80%E6%B5%8B.webp" alt="三网回程路由线路测试"></p><h2 id="上游及回程线路测试"><a href="#上游及回程线路测试" class="headerlink" title="上游及回程线路测试"></a>上游及回程线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E4%B8%8A%E6%B8%B8%E5%8F%8A%E5%9B%9E%E7%A8%8B%E7%BA%BF%E8%B7%AF%E6%A3%80%E6%B5%8B.webp" alt="上游及回程线路测试"></p><h2 id="全国Ping"><a href="#全国Ping" class="headerlink" title="全国Ping"></a>全国Ping</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E5%85%A8%E5%9B%BDping.webp" alt="全国Ping"></p><h2 id="Ping各大服务商"><a href="#Ping各大服务商" class="headerlink" title="Ping各大服务商"></a>Ping各大服务商</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/PING%E5%90%84%E5%A4%A7%E6%9C%8D%E5%8A%A1-%E8%BD%AC%E6%8D%A2%E8%87%AA-png.webp" alt="Ping各大服务商"></p><h2 id="网络带宽上传下载测速"><a href="#网络带宽上传下载测速" class="headerlink" title="网络带宽上传下载测速"></a>网络带宽上传下载测速</h2><p>入站带宽1G以内，出站带宽在2G、3G、甚至10G左右，谷歌网络估计对很多国外的机房都有优化。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E7%BD%91%E7%BB%9C%E5%B8%A6%E5%AE%BD%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E6%B5%8B%E8%AF%95.webp" alt="网络带宽上传下载测速"></p><h2 id="跨国平台解锁"><a href="#跨国平台解锁" class="headerlink" title="跨国平台解锁"></a>跨国平台解锁</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E8%B7%A8%E5%9B%BD%E5%B9%B3%E5%8F%B0%E8%A7%A3%E9%94%81.webp" alt="跨国平台解锁"></p><h2 id="IP质量检测-IPV4"><a href="#IP质量检测-IPV4" class="headerlink" title="IP质量检测-IPV4"></a>IP质量检测-IPV4</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/IP%E8%B4%A8%E9%87%8F%E6%A3%80%E6%B5%8B-%E8%BD%AC%E6%8D%A2%E8%87%AA-png.webp" alt="IP质量检测-IPV4"></p><h2 id="测试脚本"><a href="#测试脚本" class="headerlink" title="测试脚本"></a>测试脚本</h2><p>使用 <a href="https://github.com/oneclickvirt/ecs">https://github.com/oneclickvirt/ecs</a> 开源项目</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> noninteractive=<span class="literal">true</span> &amp;&amp; curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh &amp;&amp; <span class="built_in">chmod</span> +x goecs.sh &amp;&amp; ./goecs.sh <span class="built_in">env</span> &amp;&amp; ./goecs.sh install &amp;&amp; goecs</span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://pidan.dev/20251129/test-google-cloud-free-vps-us-west1/</id>
    <link href="https://pidan.dev/20251129/test-google-cloud-free-vps-us-west1/"/>
    <published>2025-11-29T08:04:33.000Z</published>
    <summary>
      <![CDATA[<p>谷歌永久免费小机，配置2C1G，带宽没写实测1G到10G之间，每月200G标准流量免费，免费30G标准存储，选了美国西海岸俄勒冈us-west1-a机房。<br>先说结论：回国网络延时较差，国际网络状况非常好，硬盘性能太差。</p>
<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/202511291614/%E5%8C%97%E4%BA%AC%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1-%E5%B1%80%E9%83%A8%E6%94%BE%E5%A4%A7.webp" alt="北京去程路由-局部放大"></p>]]>
    </summary>
    <title>测评VPS 谷歌Google Cloud免费主机 美国西部俄勒冈us-west1</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="评测" scheme="https://pidan.dev/categories/%E8%AF%84%E6%B5%8B/"/>
    <category term="vps" scheme="https://pidan.dev/tags/vps/"/>
    <category term="云主机" scheme="https://pidan.dev/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA/"/>
    <category term="评测" scheme="https://pidan.dev/tags/%E8%AF%84%E6%B5%8B/"/>
    <category term="腾讯云" scheme="https://pidan.dev/tags/%E8%85%BE%E8%AE%AF%E4%BA%91/"/>
    <content>
      <![CDATA[<p>腾讯云99元轻量云应用服务器 境外地域 日本区，亚太区域说是线路抽奖，这次抽中的线路还不错。</p><p>先说结论，去程和三网回程的路由非常好，尤其电信和联通网络，带宽能跑足，入站30M，出站能超过100M，整体非常好。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1%E7%BA%BF%E8%B7%AF.webp" alt="北京去程线路测试"></p><span id="more"></span><h2 id="CPU内存测试"><a href="#CPU内存测试" class="headerlink" title="CPU内存测试"></a>CPU内存测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/cpu-%E5%86%85%E5%AD%98.webp" alt="CPU内存测试"></p><h2 id="磁盘性能测试"><a href="#磁盘性能测试" class="headerlink" title="磁盘性能测试"></a>磁盘性能测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E7%A1%AC%E7%9B%98%E6%B5%8B%E9%80%9F.webp" alt="磁盘性能测试"></p><h2 id="北京去程路由线路测试"><a href="#北京去程路由线路测试" class="headerlink" title="北京去程路由线路测试"></a>北京去程路由线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1%E7%BA%BF%E8%B7%AF.webp" alt="北京去程路由线路测试"></p><h2 id="三网回程路由线路测试"><a href="#三网回程路由线路测试" class="headerlink" title="三网回程路由线路测试"></a>三网回程路由线路测试</h2><p>电信线路从上海入境没有绕路，联通线路从北京入境没有绕路，移动线路有绕路单延迟同样很低。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E4%B8%89%E7%BD%91%E5%9B%9E%E7%A8%8B%E8%B7%AF%E7%94%B1%E6%A3%80%E6%B5%8B.webp" alt="三网回程路由线路测试"></p><h2 id="上游及回程线路测试"><a href="#上游及回程线路测试" class="headerlink" title="上游及回程线路测试"></a>上游及回程线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E4%B8%8A%E6%B8%B8%E5%8F%8A%E5%9B%9E%E7%A8%8B%E7%BA%BF%E8%B7%AF%E6%A3%80%E6%B5%8B.webp" alt="上游及回程线路测试"></p><h2 id="全国Ping"><a href="#全国Ping" class="headerlink" title="全国Ping"></a>全国Ping</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E5%85%A8%E5%9B%BDping.webp" alt="全国Ping"></p><h2 id="Ping值测试"><a href="#Ping值测试" class="headerlink" title="Ping值测试"></a>Ping值测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/PING%E5%80%BC%E6%A3%80%E6%B5%8B.webp" alt="Ping值测试"></p><h2 id="网络带宽上传下载测速"><a href="#网络带宽上传下载测速" class="headerlink" title="网络带宽上传下载测速"></a>网络带宽上传下载测速</h2><p>带宽很足，入站30M足量，出站100M、260M都有，不太懂这一块，有懂哥说一下。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E7%BD%91%E7%BB%9C%E5%B8%A6%E5%AE%BD%E4%B8%8A%E4%BC%A0%E4%B8%8B%E8%BD%BD%E6%B5%8B%E9%80%9F.webp" alt="网络带宽上传下载测速"></p><h2 id="跨国平台解锁"><a href="#跨国平台解锁" class="headerlink" title="跨国平台解锁"></a>跨国平台解锁</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E8%B7%A8%E5%9B%BD%E5%B9%B3%E5%8F%B0%E8%A7%A3%E9%94%81.webp" alt="跨国平台解锁"></p><h2 id="IP质量检测-IPV4"><a href="#IP质量检测-IPV4" class="headerlink" title="IP质量检测-IPV4"></a>IP质量检测-IPV4</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/IP%E8%B4%A8%E9%87%8F%E6%A3%80%E6%B5%8B-IPV4.webp" alt="IP质量检测-IPV4"></p><h2 id="IP质量检测-IPV6"><a href="#IP质量检测-IPV6" class="headerlink" title="IP质量检测-IPV6"></a>IP质量检测-IPV6</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/IP%E8%B4%A8%E9%87%8F%E6%A3%80%E6%B5%8B-IPV6.webp" alt="IP质量检测-IPV6"></p>]]>
    </content>
    <id>https://pidan.dev/20251117/test-tencent-cloud-vps-jp/</id>
    <link href="https://pidan.dev/20251117/test-tencent-cloud-vps-jp/"/>
    <published>2025-11-17T15:12:14.000Z</published>
    <summary>
      <![CDATA[<p>腾讯云99元轻量云应用服务器 境外地域 日本区，亚太区域说是线路抽奖，这次抽中的线路还不错。</p>
<p>先说结论，去程和三网回程的路由非常好，尤其电信和联通网络，带宽能跑足，入站30M，出站能超过100M，整体非常好。</p>
<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251117230206/%E5%8E%BB%E7%A8%8B%E8%B7%AF%E7%94%B1%E7%BA%BF%E8%B7%AF.webp" alt="北京去程线路测试"></p>]]>
    </summary>
    <title>测评VPS 腾讯云99轻量应用服务器境外地域 日本区</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="评测" scheme="https://pidan.dev/categories/%E8%AF%84%E6%B5%8B/"/>
    <category term="vps" scheme="https://pidan.dev/tags/vps/"/>
    <category term="云主机" scheme="https://pidan.dev/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA/"/>
    <category term="评测" scheme="https://pidan.dev/tags/%E8%AF%84%E6%B5%8B/"/>
    <category term="雨云" scheme="https://pidan.dev/tags/%E9%9B%A8%E4%BA%91/"/>
    <content>
      <![CDATA[<p>雨云最新的云服务器日本东京，本文选了东京软银大带宽2区（移动优化）主机来做使用评测。<br>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev"> 雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），还提供1元一天体验版本。</p><p>先说结论，软银优化线路，线路平直不绕远，延迟北京实测120ms波动，晚间少许丢包，建站没问题，带宽100M充足，流量管饱，便宜实惠。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171052464.webp" alt="三网回程线路测试"></p><span id="more"></span><h2 id="CPU内存测试"><a href="#CPU内存测试" class="headerlink" title="CPU内存测试"></a>CPU内存测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115170740139.webp" alt="cpu内存测试图"></p><h2 id="SSD硬盘性能测试"><a href="#SSD硬盘性能测试" class="headerlink" title="SSD硬盘性能测试"></a>SSD硬盘性能测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115170832986.webp" alt="硬盘性能测试"></p><h2 id="ip质量测试"><a href="#ip质量测试" class="headerlink" title="ip质量测试"></a>ip质量测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115170903951.webp" alt="ip质量测试"></p><h2 id="Ping测试"><a href="#Ping测试" class="headerlink" title="Ping测试"></a>Ping测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115170933990.webp" alt="Ping测试"></p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115170955582.webp" alt="Ping测试"></p><h2 id="三网回程线路测试"><a href="#三网回程线路测试" class="headerlink" title="三网回程线路测试"></a>三网回程线路测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171052464.webp" alt="三网回程线路测试"></p><h2 id="上游及回程线路检测"><a href="#上游及回程线路检测" class="headerlink" title="上游及回程线路检测"></a>上游及回程线路检测</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171128385.webp" alt="上游及回程线路检测"></p><h2 id="路由追踪"><a href="#路由追踪" class="headerlink" title="路由追踪"></a>路由追踪</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171153632.webp" alt="路由追踪"></p><h2 id="带宽上传下载速度测试"><a href="#带宽上传下载速度测试" class="headerlink" title="带宽上传下载速度测试"></a>带宽上传下载速度测试</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171241167.webp" alt="带宽上传下载速度测试"></p><h2 id="邮件端口检测"><a href="#邮件端口检测" class="headerlink" title="邮件端口检测"></a>邮件端口检测</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171312247.webp" alt="邮件端口检测"></p><h2 id="国外流媒体及各种服务解锁"><a href="#国外流媒体及各种服务解锁" class="headerlink" title="国外流媒体及各种服务解锁"></a>国外流媒体及各种服务解锁</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171343776.webp" alt="国外流媒体解锁"></p><h2 id="测试脚本"><a href="#测试脚本" class="headerlink" title="测试脚本"></a>测试脚本</h2><p>使用 <a href="https://github.com/oneclickvirt/ecs">https://github.com/oneclickvirt/ecs</a> 开源项目</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> noninteractive=<span class="literal">true</span> &amp;&amp; curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh &amp;&amp; <span class="built_in">chmod</span> +x goecs.sh &amp;&amp; ./goecs.sh <span class="built_in">env</span> &amp;&amp; ./goecs.sh install &amp;&amp; goecs</span><br></pre></td></tr></table></figure><p>结束。</p>]]>
    </content>
    <id>https://pidan.dev/20251115/test-rainyun-cloud-host-server-jp2/</id>
    <link href="https://pidan.dev/20251115/test-rainyun-cloud-host-server-jp2/"/>
    <published>2025-11-15T09:05:00.000Z</published>
    <summary>
      <![CDATA[<p>雨云最新的云服务器日本东京，本文选了东京软银大带宽2区（移动优化）主机来做使用评测。<br>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev"> 雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），还提供1元一天体验版本。</p>
<p>先说结论，软银优化线路，线路平直不绕远，延迟北京实测120ms波动，晚间少许丢包，建站没问题，带宽100M充足，流量管饱，便宜实惠。</p>
<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20251115171052464.webp" alt="三网回程线路测试"></p>]]>
    </summary>
    <title>雨云 云服务器RCS/ECS/VPS评测 日本东京软银大带宽2区IIJ移动优化 复测</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="WebRTC" scheme="https://pidan.dev/categories/WebRTC/"/>
    <category term="技术分享" scheme="https://pidan.dev/categories/WebRTC/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="技术分享" scheme="https://pidan.dev/tags/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="LiveKit" scheme="https://pidan.dev/tags/LiveKit/"/>
    <category term="WebRTC" scheme="https://pidan.dev/tags/WebRTC/"/>
    <category term="turn" scheme="https://pidan.dev/tags/turn/"/>
    <category term="stun" scheme="https://pidan.dev/tags/stun/"/>
    <content>
      <![CDATA[<p>使用官方配置的方式公网部署LiveKit，使用自己的ssl证书，不使用caddy自动申请的免费证书。</p><span id="more"></span><p>首先按照 <a href="https://pidan.dev/20250721/webrtc-livekit-deploy-with-tls/">https://pidan.dev/20250721/webrtc-livekit-deploy-with-tls/</a> 这里的部署方式，使用官方的教程创建好各种启动的配置文件。然后我们修改一下这些配置文件，来使用我们自己申请的证书文件。</p><p>你也可以直接复制本文的各种配置文件直接启动livekit，不走他的官方启动流程也是没问题的。</p><h2 id="设置域名解析"><a href="#设置域名解析" class="headerlink" title="设置域名解析"></a>设置域名解析</h2><p>我们配置两个域名都解析到这台公网服务器，并且我们已经下载了他们的ssl证书文件。</p><ul><li>lk.abc.com  此域名为livekit的域名</li><li>lk-turn.abc.com  此域名为livekit内置的turn的域名</li></ul><p>你的公网服务器防火墙需要开启的端口：</p><ul><li>8443&#x2F;TCP   livekit接口 HTTPS and TURN&#x2F;TLS</li><li>3478&#x2F;UDP   TURN&#x2F;UDP 网络线路条件良好的情况下，此端口不开也能使用，但是推荐开。</li><li>50000-50100&#x2F;UDP   WebRTC over UDP</li></ul><p>实测上边的这几个端口是必须开的.</p><h2 id="配置caddy"><a href="#配置caddy" class="headerlink" title="配置caddy"></a>配置caddy</h2><p>编辑或创建<code>caddy.yaml</code>文件</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">logging:</span></span><br><span class="line">  <span class="attr">logs:</span></span><br><span class="line">    <span class="attr">default:</span></span><br><span class="line">      <span class="attr">level:</span> <span class="string">INFO</span></span><br><span class="line"><span class="attr">storage:</span></span><br><span class="line">  <span class="attr">&quot;module&quot;:</span> <span class="string">&quot;file_system&quot;</span></span><br><span class="line">  <span class="attr">&quot;root&quot;:</span> <span class="string">&quot;/data&quot;</span></span><br><span class="line"><span class="attr">apps:</span></span><br><span class="line">  <span class="attr">tls:</span></span><br><span class="line">    <span class="attr">certificates:</span></span><br><span class="line">      <span class="attr">load_files:</span>  <span class="comment"># 这里挂载自己的ssl证书，我申请的免费证书，两个域名所以申请两个，你有通配符证书最好了。</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">certificate:</span> <span class="string">&quot;/cert/lk.abc.com_bundle.pem&quot;</span></span><br><span class="line">          <span class="attr">key:</span> <span class="string">&quot;/cert/lk.abc.com.key&quot;</span></span><br><span class="line">        <span class="bullet">-</span> <span class="attr">certificate:</span> <span class="string">&quot;/cert/lk-turn.abc.com_bundle.pem&quot;</span></span><br><span class="line">          <span class="attr">key:</span> <span class="string">&quot;/cert/lk-turn.abc.com.key&quot;</span></span><br><span class="line">  <span class="attr">layer4:</span></span><br><span class="line">    <span class="attr">servers:</span></span><br><span class="line">      <span class="attr">main:</span></span><br><span class="line">        <span class="attr">listen:</span> [<span class="string">&quot;:8443&quot;</span>]   <span class="comment"># 这里可以设置443，如果你不能用443，那么设置成别的，这里要和docker-compose里开放的端口对应</span></span><br><span class="line">        <span class="attr">routes:</span></span><br><span class="line">          <span class="bullet">-</span> <span class="attr">match:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="attr">tls:</span></span><br><span class="line">                <span class="attr">sni:</span></span><br><span class="line">                  <span class="bullet">-</span> <span class="string">&quot;lk-turn.abc.com&quot;</span>   <span class="comment"># 修改为自己的域名</span></span><br><span class="line">            <span class="attr">handle:</span></span><br><span class="line">              <span class="bullet">-</span> <span class="attr">handler:</span> <span class="string">tls</span></span><br><span class="line">              <span class="bullet">-</span> <span class="attr">handler:</span> <span class="string">proxy</span></span><br><span class="line">                <span class="attr">upstreams:</span></span><br><span class="line">                  <span class="bullet">-</span> <span class="attr">dial:</span> [<span class="string">&quot;livekit:5349&quot;</span>]  <span class="comment"># 这里的livekit为docker-compose定义的服务名</span></span><br><span class="line">          <span class="bullet">-</span> <span class="attr">match:</span></span><br><span class="line">              <span class="bullet">-</span> <span class="attr">tls:</span></span><br><span class="line">                  <span class="attr">sni:</span></span><br><span class="line">                    <span class="bullet">-</span> <span class="string">&quot;lk.abc.com&quot;</span>    <span class="comment"># 修改为自己的域名</span></span><br><span class="line">            <span class="attr">handle:</span></span><br><span class="line">              <span class="bullet">-</span> <span class="attr">handler:</span> <span class="string">tls</span></span><br><span class="line">                <span class="attr">connection_policies:</span></span><br><span class="line">                  <span class="bullet">-</span> <span class="attr">alpn:</span> [<span class="string">&quot;http/1.1&quot;</span>]</span><br><span class="line">              <span class="bullet">-</span> <span class="attr">handler:</span> <span class="string">proxy</span></span><br><span class="line">                <span class="attr">upstreams:</span></span><br><span class="line">                  <span class="bullet">-</span> <span class="attr">dial:</span> [<span class="string">&quot;livekit:7880&quot;</span>]   <span class="comment"># 这里的livekit为docker-compose定义的服务名</span></span><br></pre></td></tr></table></figure><h2 id="配置livekit配置文件"><a href="#配置livekit配置文件" class="headerlink" title="配置livekit配置文件"></a>配置livekit配置文件</h2><p>编辑或创建<code>livekit.yaml</code>文件</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">port:</span> <span class="number">7880</span></span><br><span class="line"><span class="attr">bind_addresses:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="string">&quot;&quot;</span></span><br><span class="line"><span class="attr">rtc:</span></span><br><span class="line">    <span class="attr">tcp_port:</span> <span class="number">7881</span></span><br><span class="line">    <span class="attr">port_range_start:</span> <span class="number">50000</span></span><br><span class="line">    <span class="attr">port_range_end:</span> <span class="number">50100</span>    <span class="comment"># 这里端口范围不能设置太大，会把机器卡死，比如设置100到1000范围就够用了，自己测试用100就够了。</span></span><br><span class="line">    <span class="attr">use_external_ip:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">enable_loopback_candidate:</span> <span class="literal">false</span></span><br><span class="line"><span class="attr">redis:</span></span><br><span class="line">    <span class="attr">address:</span> <span class="string">lk-redis:6379</span></span><br><span class="line">    <span class="attr">username:</span> <span class="string">&quot;&quot;</span></span><br><span class="line">    <span class="attr">password:</span> <span class="string">&quot;&quot;</span></span><br><span class="line">    <span class="attr">db:</span> <span class="number">0</span></span><br><span class="line">    <span class="attr">use_tls:</span> <span class="literal">false</span></span><br><span class="line">    <span class="attr">sentinel_master_name:</span> <span class="string">&quot;&quot;</span></span><br><span class="line">    <span class="attr">sentinel_username:</span> <span class="string">&quot;&quot;</span></span><br><span class="line">    <span class="attr">sentinel_password:</span> <span class="string">&quot;&quot;</span></span><br><span class="line">    <span class="attr">sentinel_addresses:</span> []</span><br><span class="line">    <span class="attr">cluster_addresses:</span> []</span><br><span class="line">    <span class="attr">max_redirects:</span> <span class="literal">null</span></span><br><span class="line"><span class="attr">turn:</span></span><br><span class="line">    <span class="attr">enabled:</span> <span class="literal">true</span></span><br><span class="line">    <span class="attr">domain:</span> <span class="string">lk-turn.abc.com</span>    <span class="comment"># 修改为自己的域名</span></span><br><span class="line">    <span class="attr">tls_port:</span> <span class="number">5349</span></span><br><span class="line">    <span class="attr">udp_port:</span> <span class="number">3478</span></span><br><span class="line">    <span class="attr">external_tls:</span> <span class="literal">true</span></span><br><span class="line"><span class="attr">keys:</span></span><br><span class="line">    <span class="attr">APIVg796bZUscSq:</span> <span class="string">p60ixbfgRFssDXAH8tWJfyxg2ftmfZeIw0QCki53fYZI</span>   <span class="comment"># 生成自己的ak sk</span></span><br></pre></td></tr></table></figure><h2 id="修改redis配置"><a href="#修改redis配置" class="headerlink" title="修改redis配置"></a>修改redis配置</h2><p>编辑或创建<code>redis.conf</code>文件</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">bind 0.0.0.0   # 这里放开</span><br><span class="line">protected-mode no   # 这里关闭</span><br><span class="line">port 6379</span><br><span class="line">timeout 0</span><br><span class="line">tcp-keepalive 300</span><br></pre></td></tr></table></figure><h2 id="修改docker-compose文件"><a href="#修改docker-compose文件" class="headerlink" title="修改docker compose文件"></a>修改docker compose文件</h2><p>编辑或创建<code>docker-compose.yaml</code>文件</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">services:</span></span><br><span class="line">  <span class="attr">lk-caddy:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">livekit/caddyl4</span></span><br><span class="line">    <span class="attr">command:</span> <span class="string">run</span> <span class="string">--config</span> <span class="string">/etc/caddy.yaml</span> <span class="string">--adapter</span> <span class="string">yaml</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;8443:8443&quot;</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./caddy.yaml:/etc/caddy.yaml</span>  <span class="comment"># 挂载刚才编辑的配置文件</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./caddy_data:/data</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./cert:/cert</span>     <span class="comment"># 挂载自己的ssl证书文件</span></span><br><span class="line">    <span class="attr">networks:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">livekit-network</span></span><br><span class="line">  <span class="attr">livekit:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">livekit/livekit-server:latest</span></span><br><span class="line">    <span class="attr">command:</span> <span class="string">--config</span> <span class="string">/etc/livekit.yaml</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line">    <span class="attr">ports:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;7880:7880&quot;</span>               <span class="comment"># LiveKit HTTP/WebSocket 端口</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;7881:7881&quot;</span>               <span class="comment"># LiveKit RTC 信令端口(如果使用)</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;5349:5349&quot;</span>               <span class="comment"># TURN over TLS 端口</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;3478:3478/udp&quot;</span>           <span class="comment"># TURN UDP 端口</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;3478:3478/tcp&quot;</span>           <span class="comment"># TURN TCP 端口</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">&quot;50000-50100:50000-50100/udp&quot;</span>  <span class="comment"># RTC 端口范围，注意和livekit.yaml中配置的端口范围一致</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./livekit.yaml:/etc/livekit.yaml</span></span><br><span class="line">    <span class="attr">environment:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">TZ=Asia/Shanghai</span></span><br><span class="line">    <span class="attr">ulimits:</span></span><br><span class="line">      <span class="attr">nproc:</span> <span class="number">65535</span>   <span class="comment"># 高性能实时服务器需要配置Linux系统参数</span></span><br><span class="line">      <span class="attr">nofile:</span></span><br><span class="line">        <span class="attr">soft:</span> <span class="number">65535</span></span><br><span class="line">        <span class="attr">hard:</span> <span class="number">70000</span></span><br><span class="line">    <span class="attr">networks:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">livekit-network</span></span><br><span class="line">  <span class="attr">lk-redis:</span></span><br><span class="line">    <span class="attr">image:</span> <span class="string">redis:7-alpine</span></span><br><span class="line">    <span class="attr">command:</span> <span class="string">redis-server</span> <span class="string">/etc/redis.conf</span></span><br><span class="line">    <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line">    <span class="attr">volumes:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">./redis.conf:/etc/redis.conf</span></span><br><span class="line">    <span class="attr">networks:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">livekit-network</span></span><br><span class="line"><span class="attr">networks:</span></span><br><span class="line">  <span class="attr">livekit-network:</span></span><br><span class="line">    <span class="attr">driver:</span> <span class="string">bridge</span></span><br></pre></td></tr></table></figure><h2 id="放置ssl证书文件"><a href="#放置ssl证书文件" class="headerlink" title="放置ssl证书文件"></a>放置ssl证书文件</h2><p>证书我从腾讯云申请的免费ssl证书文件。</p><ul><li><code>cloud.tencent.com_bundle.crt</code> 证书文件</li><li><code>cloud.tencent.com_bundle.pem</code> 证书文件</li><li><code>cloud.tencent.com.key</code> 私钥文件</li><li><code>cloud.tencent.com.csr</code> CSR 文件</li></ul><p>创建目录并放到<code>./cert</code>目录下。然后设置权限</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cd</span> ./cert</span><br><span class="line"><span class="built_in">chmod</span> 644 *.crt</span><br><span class="line"><span class="built_in">chmod</span> 600 *.key</span><br></pre></td></tr></table></figure><h2 id="启动livekit服务"><a href="#启动livekit服务" class="headerlink" title="启动livekit服务"></a>启动livekit服务</h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">docker compose up -d</span><br><span class="line"></span><br><span class="line">docker compose down</span><br><span class="line"></span><br><span class="line">docker compose logs -f --<span class="built_in">tail</span> 1000</span><br></pre></td></tr></table></figure><h2 id="测试连通性"><a href="#测试连通性" class="headerlink" title="测试连通性"></a>测试连通性</h2><p><a href="https://livekit.io/connection-test">https://livekit.io/connection-test</a> 使用官方的测试页面进行测试</p><p>此时我们的livekit服务接口为<code>wss://lk.abc.com:8443</code>    </p><p>至于token需要调用官方的sdk生成一下，比如下边是我写的一个livekit go sdk的示例：</p><figure class="highlight golang"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"> <span class="string">&quot;fmt&quot;</span></span><br><span class="line"> <span class="string">&quot;github.com/livekit/protocol/auth&quot;</span></span><br><span class="line"> <span class="string">&quot;time&quot;</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">NewAccessToken</span><span class="params">(roomName, pID <span class="type">string</span>)</span></span> (<span class="type">string</span>, <span class="type">error</span>) &#123;</span><br><span class="line"></span><br><span class="line"> apiKey := <span class="string">&quot;APIgJX&quot;</span>    <span class="comment">// 填写你刚才代码生成的apiKey</span></span><br><span class="line"> apiSecret := <span class="string">&quot;AXBbhpWBguYelOy6c&quot;</span>    <span class="comment">// 填写你刚才代码生成的apiSecret</span></span><br><span class="line"></span><br><span class="line"> at := auth.NewAccessToken(apiKey, apiSecret)</span><br><span class="line"> grant := &amp;auth.VideoGrant&#123;</span><br><span class="line">  RoomJoin: <span class="literal">true</span>,</span><br><span class="line">  Room:     roomName,</span><br><span class="line"> &#125;</span><br><span class="line"> at.SetVideoGrant(grant).</span><br><span class="line">  SetIdentity(pID).</span><br><span class="line">  SetName(pID).</span><br><span class="line">  SetValidFor(time.Hour * <span class="number">24</span> * <span class="number">30</span>) <span class="comment">// 30天过期</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> at.ToJWT()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> &#123;</span><br><span class="line"> token, _ := NewAccessToken(<span class="string">&quot;room001&quot;</span>, <span class="string">&quot;user002&quot;</span>)    <span class="comment">// 房间名，用户参会者名字</span></span><br><span class="line"> fmt.Printf(token)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://docs.livekit.io/home/self-hosting/vm/">https://docs.livekit.io/home/self-hosting/vm/</a><br><a href="https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/">https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/</a>    </p>]]>
    </content>
    <id>https://pidan.dev/20251113/webrtc-livekit-deploy-with-tls-certificate-files/</id>
    <link href="https://pidan.dev/20251113/webrtc-livekit-deploy-with-tls-certificate-files/"/>
    <published>2025-11-13T15:57:34.000Z</published>
    <summary>
      <![CDATA[<p>使用官方配置的方式公网部署LiveKit，使用自己的ssl证书，不使用caddy自动申请的免费证书。</p>]]>
    </summary>
    <title>【WebRTC全流程】公网部署LiveKit并配置自己申请的ssl证书</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="cloudflare" scheme="https://pidan.dev/tags/cloudflare/"/>
    <category term="hexo" scheme="https://pidan.dev/tags/hexo/"/>
    <category term="analytics" scheme="https://pidan.dev/tags/analytics/"/>
    <content>
      <![CDATA[<p>部署caddy2反向代理 n8n，配置postgresql数据库，挂载中文汉化界面。</p><span id="more"></span><h2 id="数据库初始化脚本"><a href="#数据库初始化脚本" class="headerlink" title="数据库初始化脚本"></a>数据库初始化脚本</h2><p>参考官方的自动建表脚本<code>init-data.sh</code></p><p>参考官方文档 <a href="https://github.com/n8n-io/n8n-hosting/blob/main/docker-compose/withPostgres/init-data.sh">https://github.com/n8n-io/n8n-hosting/blob/main/docker-compose/withPostgres/init-data.sh</a></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">#</span><span class="language-bash">!/bin/bash</span></span><br><span class="line">set -e;</span><br><span class="line"></span><br><span class="line">if [ -n &quot;$&#123;POSTGRES_NON_ROOT_USER:-&#125;&quot; ] &amp;&amp; [ -n &quot;$&#123;POSTGRES_NON_ROOT_PASSWORD:-&#125;&quot; ]; then</span><br><span class="line">        psql -v ON_ERROR_STOP=1 --username &quot;$POSTGRES_USER&quot; --dbname &quot;$POSTGRES_DB&quot; &lt;&lt;-EOSQL</span><br><span class="line">                CREATE USER $&#123;POSTGRES_NON_ROOT_USER&#125; WITH PASSWORD &#x27;$&#123;POSTGRES_NON_ROOT_PASSWORD&#125;&#x27;;</span><br><span class="line">                GRANT ALL PRIVILEGES ON DATABASE $&#123;POSTGRES_DB&#125; TO $&#123;POSTGRES_NON_ROOT_USER&#125;;</span><br><span class="line">                GRANT CREATE ON SCHEMA public TO $&#123;POSTGRES_NON_ROOT_USER&#125;;</span><br><span class="line">        EOSQL</span><br><span class="line">else</span><br><span class="line">        echo &quot;SETUP INFO: No Environment variables given!&quot;</span><br><span class="line">fi</span><br></pre></td></tr></table></figure><h2 id="挂载中文汉化前端"><a href="#挂载中文汉化前端" class="headerlink" title="挂载中文汉化前端"></a>挂载中文汉化前端</h2><p>下载前端预编译包 <a href="https://github.com/other-blowsnow/n8n-i18n-chinese">https://github.com/other-blowsnow/n8n-i18n-chinese</a></p><h2 id="docker-compose-部署n8n"><a href="#docker-compose-部署n8n" class="headerlink" title="docker compose 部署n8n"></a>docker compose 部署n8n</h2><p>参考官方部署文档  <a href="https://github.com/n8n-io/n8n-hosting/tree/main/docker-compose/withPostgres">https://github.com/n8n-io/n8n-hosting/tree/main/docker-compose/withPostgres</a></p><p>编写<code>docker-compose.yml</code></p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">version:</span> <span class="string">&#x27;3.9&#x27;</span></span><br><span class="line"><span class="attr">services:</span></span><br><span class="line">    <span class="attr">n8nio:</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">n8nio/n8n:1.117.3</span></span><br><span class="line">        <span class="attr">volumes:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">&#x27;n8n_data:/home/node/.n8n&#x27;</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">./dist:/usr/local/lib/node_modules/n8n/node_modules/n8n-editor-ui/dist</span> <span class="comment"># 挂载前端</span></span><br><span class="line">        <span class="attr">ports:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">&#x27;5678:5678&#x27;</span></span><br><span class="line">        <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line">        <span class="attr">environment:</span></span><br><span class="line">            <span class="attr">TZ:</span> <span class="string">Asia/Shanghai</span></span><br><span class="line">            <span class="attr">N8N_SECURE_COOKIE:</span> <span class="literal">false</span></span><br><span class="line">            <span class="attr">N8N_HOST:</span> <span class="string">n8n.abc.com</span> <span class="comment"># 你的域名</span></span><br><span class="line">            <span class="attr">N8N_PORT:</span> <span class="number">5678</span></span><br><span class="line">            <span class="attr">N8N_PROTOCOL:</span> <span class="string">https</span></span><br><span class="line">            <span class="attr">NODE_ENV:</span> <span class="string">production</span></span><br><span class="line">            <span class="attr">WEBHOOK_URL:</span> <span class="string">https://n8n.abc.com/</span>  <span class="comment"># 你的域名</span></span><br><span class="line">            <span class="attr">GENERIC_TIMEZONE:</span> <span class="string">Asia/Shanghai</span></span><br><span class="line">            <span class="attr">N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS:</span> <span class="literal">true</span></span><br><span class="line">            <span class="attr">N8N_RUNNERS_ENABLED:</span> <span class="literal">true</span></span><br><span class="line">            <span class="attr">N8N_PROXY_HOPS:</span> <span class="number">2</span>   <span class="comment"># 这里代表允许跳过几跳代理层，比如caddy是一层，这里填1，再加上CDN代理，这里填2，代表两跳。</span></span><br><span class="line">            <span class="attr">N8N_DEFAULT_LOCALE:</span> <span class="string">zh-CN</span></span><br><span class="line">            <span class="attr">DB_TYPE:</span> <span class="string">postgresdb</span></span><br><span class="line">            <span class="attr">DB_POSTGRESDB_DATABASE:</span> <span class="string">n8n</span></span><br><span class="line">            <span class="attr">DB_POSTGRESDB_HOST:</span> <span class="string">n8n-postgres</span></span><br><span class="line">            <span class="attr">DB_POSTGRESDB_PORT:</span> <span class="number">5432</span></span><br><span class="line">            <span class="attr">DB_POSTGRESDB_USER:</span> <span class="string">n8n</span></span><br><span class="line">            <span class="attr">DB_POSTGRESDB_PASSWORD:</span> <span class="string">postgres</span></span><br><span class="line">        <span class="attr">networks:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">n8n-network</span></span><br><span class="line">        <span class="attr">depends_on:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">n8n-postgres</span></span><br><span class="line">    <span class="attr">n8n-postgres:</span></span><br><span class="line">        <span class="attr">image:</span> <span class="string">postgres:17</span></span><br><span class="line">        <span class="attr">volumes:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">n8n_postgres_data:/var/lib/postgresql/data</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">./init-data.sh:/docker-entrypoint-initdb.d/init-data.sh</span> <span class="comment"># 挂载数据库初始化脚本</span></span><br><span class="line">        <span class="attr">environment:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">TZ=Asia/Shanghai</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">POSTGRES_USER=postgres</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">POSTGRES_PASSWORD=postgres</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">POSTGRES_NON_ROOT_USER=n8n</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">POSTGRES_NON_ROOT_PASSWORD=postgres</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">POSTGRES_DB=n8n</span></span><br><span class="line">        <span class="attr">restart:</span> <span class="string">unless-stopped</span></span><br><span class="line">        <span class="attr">networks:</span></span><br><span class="line">            <span class="bullet">-</span> <span class="string">n8n-network</span></span><br><span class="line"><span class="attr">volumes:</span></span><br><span class="line">  <span class="attr">n8n_data:</span></span><br><span class="line">  <span class="attr">n8n_postgres_data:</span></span><br><span class="line"><span class="attr">networks:</span></span><br><span class="line">    <span class="attr">n8n-network:</span></span><br><span class="line">          <span class="attr">driver:</span> <span class="string">bridge</span></span><br></pre></td></tr></table></figure><h2 id="配置caddy反向代理"><a href="#配置caddy反向代理" class="headerlink" title="配置caddy反向代理"></a>配置caddy反向代理</h2><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">n8n.pidan.ltd &#123;</span><br><span class="line">        encode gzip zstd</span><br><span class="line"></span><br><span class="line">        handle /robots.txt &#123;</span><br><span class="line">                respond `User-agent: *</span><br><span class="line">                Disallow: /` 200</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        # 添加 HTTP 头阻止索引</span><br><span class="line">        header &#123;</span><br><span class="line">                X-Robots-Tag &quot;noindex, nofollow, noarchive&quot;</span><br><span class="line">        &#125;</span><br><span class="line">        reverse_proxy 172.17.0.1:5678 &#123;</span><br><span class="line">                flush_interval -1</span><br><span class="line">        &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>]]>
    </content>
    <id>https://pidan.dev/20251103/deploy-n8n-with-postgres/</id>
    <link href="https://pidan.dev/20251103/deploy-n8n-with-postgres/"/>
    <published>2025-11-03T13:21:18.000Z</published>
    <summary>
      <![CDATA[<p>部署caddy2反向代理 n8n，配置postgresql数据库，挂载中文汉化界面。</p>]]>
    </summary>
    <title>部署caddy2反向代理 n8n postgres 配置中文汉化界面</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="LibreOffice" scheme="https://pidan.dev/tags/LibreOffice/"/>
    <category term="gotenberg" scheme="https://pidan.dev/tags/gotenberg/"/>
    <category term="go" scheme="https://pidan.dev/tags/go/"/>
    <category term="文档类型转换" scheme="https://pidan.dev/tags/%E6%96%87%E6%A1%A3%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2/"/>
    <content>
      <![CDATA[<p>本文一起做的事：</p><ul><li>解决<code>convert to PDF: supervisor run task: context deadline exceeded</code> 503 504 timeout 异常</li><li>部署 gotenberg 服务提供 api 接口，实现 word 等 office 文件转换成 pdf 文件的功能。内部实现是 LibreOffice。</li><li>使用负载均衡模式，来解决 LibreOffice 处理任务锁住导致并发上不去的问题。</li></ul><span id="more"></span><h2 id="解决convert-to-PDF-supervisor-run-task-context-deadline-exceeded-503-504-timeout异常"><a href="#解决convert-to-PDF-supervisor-run-task-context-deadline-exceeded-503-504-timeout异常" class="headerlink" title="解决convert to PDF: supervisor run task: context deadline exceeded 503&#x2F;504&#x2F;timeout异常"></a>解决<code>convert to PDF: supervisor run task: context deadline exceeded</code> 503&#x2F;504&#x2F;timeout异常</h2><p>部署服务很简单可以直接往下看，这里我们先说解决这个异常，这个是最棘手的。</p><h3 id="问题现象"><a href="#问题现象" class="headerlink" title="问题现象"></a>问题现象</h3><p>现象出现在，需要处理很多文档的解析，有很多不通地区不同时间不同人不同电脑创建的office word文档，doc&#x2F;docx 都有，需要转换成 pdf 文件再过 OCR 模型去解析，我使用 gotenberg 这个服务，能提供 api 接口并内部调用 LibreOffic 来实现 pdf 的转换，实际跑批时候发现这个服务经常出现 503&#x2F;504&#x2F;timeout 等问题，即使按照文档设置了接口超时到 3600s 也不行，同样会卡住 1h 然后提示超时。</p><p>表象是服务超时，但是 1h 还超时就肯定不对了，gotenberg 日志提示<code>convert to PDF: supervisor run task: context deadline exceeded</code>这里的 task 就是 LibreOffice 执行的，它异常，我认为 1h 已经是 LibreOffice 自己卡死了进入死循环了，那么为什么？什么会导致它卡死，为什么有的 word 正常，有的 word 不正常，这是我要找到的原因。</p><p>经过很长时间试错，直到我尝试对比多个 word 里包含的字体种类，我猜测是字体的原因。word 转 pdf 最容易出现的就是字体问题，比如 pdf 出现很多方框，还没想过缺少字体会把 LibreOffice 卡死。那么我尝试加上字体试试：</p><p>我们按照官网的方式重新打一个docker镜像 <a href="https://gotenberg.dev/docs/configuration#fonts">https://gotenberg.dev/docs/configuration#fonts</a></p><p>编写<code>Dockerfile</code>文件：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">FROM gotenberg/gotenberg:8.23.1</span><br><span class="line"></span><br><span class="line">USER root</span><br><span class="line"></span><br><span class="line">COPY ./fonts/* /usr/local/share/fonts/</span><br><span class="line"></span><br><span class="line">RUN sed -i &#x27;s@deb.debian.org@repo.huaweicloud.com@g&#x27; /etc/apt/sources.list.d/debian.sources</span><br><span class="line"></span><br><span class="line">RUN apt-get update &amp;&amp; apt-get install -y  \</span><br><span class="line">    fonts-noto-core \</span><br><span class="line">    fonts-noto-cjk \</span><br><span class="line">    fonts-noto-color-emoji \</span><br><span class="line">    fonts-liberation \</span><br><span class="line">    fonts-wqy-zenhei \</span><br><span class="line">    fonts-arphic-gbsn00lp \</span><br><span class="line">    fonts-wqy-microhei \</span><br><span class="line">    fonts-arphic-gkai00mp \</span><br><span class="line">    ttf-wqy-zenhei \</span><br><span class="line">    fonts-symbola \</span><br><span class="line">    fontconfig \</span><br><span class="line">    libgl1 \</span><br><span class="line"> &amp;&amp; apt-get clean \</span><br><span class="line"> &amp;&amp; rm -rf /var/lib/apt/lists/*</span><br><span class="line"></span><br><span class="line">RUN fc-cache -f -v</span><br><span class="line"></span><br><span class="line"># USER gotenberg</span><br></pre></td></tr></table></figure><ul><li>.&#x2F;fonts&#x2F;* 目录里是我当前 windows10 电脑里的所有字体，都是 ttf 文件。目录在<code>C:\Windows\Fonts</code>直接全选复制粘贴到我们的这个文件夹里。</li><li>fonts-noto-color-emoji 是 emoji，没啥用但是加上吧还是。</li><li>fontconfig 是一个字体管理工具，必须的。</li><li>fonts-wqy-zenhei 文泉驿正黑，一个高质量的开源中文字体，覆盖了大部分汉字。</li><li>fonts-noto-cjk 谷歌的思源字体，同时支持中文、日文和韩文，是处理多语言文档的理想选择。能够保障覆盖绝大多数字体。</li><li>fonts-arphic-gkai00mp 文鼎 PL 简报楷，高质量的楷体字体。</li><li>fonts-arphic-gbsn00lp 文鼎 PL 简报宋，高质量的宋体字体。</li><li>fonts-symbola 包含大量 Unicode 符号和特殊字符，对于处理数学公式或特殊符号的文档很有帮助。</li><li>ttf-mscorefonts-installer 包含微软常用的核心字体，如 宋体 (SimSun)、黑体 (SimHei)、Times New Roman 等。这个包能很好地解决 Word 文档兼容性问题。gotenberg原始镜像里包含这个工具，所以我没有重新装。</li></ul><blockquote><p>你要问上边这些怎么选出来的：Gemini给的。</p></blockquote><p><code>fc-cache -f -v</code>是使用 fontconfig 刷新系统字体缓存。</p><p>注意官方最后还是用了<code>USER gotenberg</code>，但是这里我不用，仍然用 root 账户。</p><p>然后我们编写<code>docker-compose.yml</code>文件</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">services:</span><br><span class="line">  gotenberg-api:</span><br><span class="line">    build:</span><br><span class="line">      context: .</span><br><span class="line">      dockerfile: Dockerfile</span><br><span class="line">    environment:</span><br><span class="line">      - TZ=Asia/Shanghai</span><br><span class="line">    env_file:</span><br><span class="line">      - .<span class="built_in">env</span></span><br><span class="line">    restart: unless-stopped</span><br></pre></td></tr></table></figure><p>编写 gotenberg 的环境变量文件<code>.env</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">API_TIMEOUT=240s  # gotenberg api接口内部超时时间</span><br><span class="line">#</span><br><span class="line">LIBREOFFICE_START_TIMEOUT=60s   # LibreOffice启动最长等待时间</span><br><span class="line">LIBREOFFICE_MAX_QUEUE_SIZE=1    # 最大队列1</span><br><span class="line">LIBREOFFICE_RESTART_AFTER=1     # 执行一个重启一次</span><br><span class="line">LIBREOFFICE_AUTO_START=true     # 在启动容器时LibreOffice自动启动</span><br></pre></td></tr></table></figure><p>我们编译新的镜像，并启动服务</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker compose build</span><br><span class="line">docker compose up -d</span><br></pre></td></tr></table></figure><p>这时候再跑之前老转换超时的 word 文件，应该就能解决问题。</p><article class="message is-warning"><div class="message-body"><p>最重要的一点，这个方法解决了我大部分问题，但是还是有 word 文档超时，504&#x2F;503 问题还是会出现，所以还要持续观察一段时间，看是别的原因，还是又缺少别的字体。</p></div></article><h2 id="配置负载均衡模式提高服务并发"><a href="#配置负载均衡模式提高服务并发" class="headerlink" title="配置负载均衡模式提高服务并发"></a>配置负载均衡模式提高服务并发</h2><p>LibreOffice 自己带锁，一次只跑一个任务，所以我们要上 nginx，启动多个 gotenberg 实例来负载均衡。</p><p>编写<code>docker-compose.yml</code>文件：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line">services:</span><br><span class="line">  gotenberg1:</span><br><span class="line">    build:</span><br><span class="line">      context: .</span><br><span class="line">      dockerfile: Dockerfile</span><br><span class="line">    container_name: gotenberg-instance-1</span><br><span class="line">    environment:</span><br><span class="line">      - TZ=Asia/Shanghai</span><br><span class="line">    restart: unless-stopped</span><br><span class="line">    networks:</span><br><span class="line">      - gotenbergNetwork</span><br><span class="line">  gotenberg2:</span><br><span class="line">    build:</span><br><span class="line">      context: .</span><br><span class="line">      dockerfile: Dockerfile</span><br><span class="line">    container_name: gotenberg-instance-2</span><br><span class="line">    environment:</span><br><span class="line">      - TZ=Asia/Shanghai</span><br><span class="line">    restart: unless-stopped</span><br><span class="line">    networks:</span><br><span class="line">      - gotenbergNetwork</span><br><span class="line">  nginx:</span><br><span class="line">    image: nginx:alpine</span><br><span class="line">    container_name: gotenberg-load-balancer</span><br><span class="line">    ports:</span><br><span class="line">      - &quot;33332:80&quot;</span><br><span class="line">    volumes:</span><br><span class="line">      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro</span><br><span class="line">    depends_on:</span><br><span class="line">      - gotenberg1</span><br><span class="line">      - gotenberg2</span><br><span class="line">    restart: unless-stopped</span><br><span class="line">    networks:</span><br><span class="line">      - gotenbergNetwork</span><br><span class="line">networks:</span><br><span class="line">  gotenbergNetwork:</span><br><span class="line">    driver: bridge</span><br></pre></td></tr></table></figure><blockquote><p>也可以用云原生docker命令直接启动多个实例。我懒，所以不用。</p></blockquote><p>编写<code>nginx.conf</code>文件：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line">upstream gotenberg_backend &#123;</span><br><span class="line">    # 指向你的 Gotenberg 服务，使用容器名称作为主机名</span><br><span class="line">    server gotenberg-instance-1:3000;</span><br><span class="line">    server gotenberg-instance-2:3000;</span><br><span class="line">    # 负载均衡算法</span><br><span class="line">    random;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">server &#123;</span><br><span class="line">    listen 80; # Nginx 监听容器内部的 80 端口</span><br><span class="line">    server_name localhost; # 可以是你的域名或IP</span><br><span class="line"></span><br><span class="line">    # 设置客户端最大上传文件大小（根据需要调整）</span><br><span class="line">    client_max_body_size 500M;</span><br><span class="line"></span><br><span class="line">    location / &#123;</span><br><span class="line">        proxy_pass http://gotenberg_backend; # 将请求代理到 Gotenberg 后端集群</span><br><span class="line">        proxy_set_header Host $host;</span><br><span class="line">        proxy_set_header X-Real-IP $remote_addr;</span><br><span class="line">        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br><span class="line">        proxy_set_header X-Forwarded-Proto $scheme;</span><br><span class="line"></span><br><span class="line">        # 增加 Nginx 与后端服务的超时时间，以匹配 Gotenberg 的 --api-timeout</span><br><span class="line">        proxy_connect_timeout 480s;</span><br><span class="line">        proxy_send_timeout 480s;</span><br><span class="line">        proxy_read_timeout 480s;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>编写 gotenberg 的环境变量文件<code>.env</code></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">API_TIMEOUT=480s  # gotenberg api接口内部超时时间</span><br><span class="line">#</span><br><span class="line">LIBREOFFICE_START_TIMEOUT=60s   # LibreOffice启动最长等待时间</span><br><span class="line">LIBREOFFICE_MAX_QUEUE_SIZE=1    # 最大队列1</span><br><span class="line">LIBREOFFICE_RESTART_AFTER=1     # 执行一个重启一次</span><br><span class="line">LIBREOFFICE_AUTO_START=true     # 在启动容器时LibreOffice自动启动</span><br></pre></td></tr></table></figure><blockquote><p>注意这里的 API_TIMEOUT 数值，要和 nginx.conf 里的 timeout 值都写相同值。</p></blockquote><p>最后我们编译镜像并启动容器即可使用。</p><h2 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h2><p>官方文档 <a href="https://gotenberg.dev/docs/configuration">https://gotenberg.dev/docs/configuration</a><br>我给官方提的 QA，官方也搞不清楚怎么解决 <a href="https://github.com/gotenberg/gotenberg/discussions/1335">https://github.com/gotenberg/gotenberg/discussions/1335</a></p>]]>
    </content>
    <id>https://pidan.dev/20250920/office-convert-pdf-use-gotenberg-libreoffice/</id>
    <link href="https://pidan.dev/20250920/office-convert-pdf-use-gotenberg-libreoffice/"/>
    <published>2025-09-20T13:48:17.000Z</published>
    <summary>
      <![CDATA[<p>本文一起做的事：</p>
<ul>
<li>解决<code>convert to PDF: supervisor run task: context deadline exceeded</code> 503 504 timeout 异常</li>
<li>部署 gotenberg 服务提供 api 接口，实现 word 等 office 文件转换成 pdf 文件的功能。内部实现是 LibreOffice。</li>
<li>使用负载均衡模式，来解决 LibreOffice 处理任务锁住导致并发上不去的问题。</li>
</ul>]]>
    </summary>
    <title>使用gotenberg提供LibreOffice文档类型转换服务word转pdf 解决context deadline exceeded 503问题</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="评测" scheme="https://pidan.dev/categories/%E8%AF%84%E6%B5%8B/"/>
    <category term="vps" scheme="https://pidan.dev/tags/vps/"/>
    <category term="云主机" scheme="https://pidan.dev/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA/"/>
    <category term="评测" scheme="https://pidan.dev/tags/%E8%AF%84%E6%B5%8B/"/>
    <category term="雨云" scheme="https://pidan.dev/tags/%E9%9B%A8%E4%BA%91/"/>
    <content>
      <![CDATA[<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250912233559513.png" alt="雨云 香港主机卡片"></p><p>本文选了润雨云云服务器香港极速三区三网直连（CN2+CMI+CUG）主机来做使用评测。</p><p>CPU 1 核、1G 内存、30G 硬盘 SSD、3M 上传、3M 下载、不限流量。</p><p>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev">雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），量大管饱，经济实惠，还提供 1 元一天体验版本。</p><span id="more"></span><h2 id="评测脚本"><a href="#评测脚本" class="headerlink" title="评测脚本"></a>评测脚本</h2><p>使用 <a href="https://github.com/oneclickvirt/ecs">https://github.com/oneclickvirt/ecs</a> 开源项目</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> noninteractive=<span class="literal">true</span> &amp;&amp; curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh &amp;&amp; <span class="built_in">chmod</span> +x goecs.sh &amp;&amp; ./goecs.sh <span class="built_in">env</span> &amp;&amp; ./goecs.sh install &amp;&amp; goecs</span><br></pre></td></tr></table></figure><p>开始自动测试主机性能。</p><h2 id="CPU-和内存性能测试"><a href="#CPU-和内存性能测试" class="headerlink" title="CPU 和内存性能测试"></a>CPU 和内存性能测试</h2><p>AMD EPYC 7K62 48-Core Processor</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250912233705382.png" alt="cpu内存性能测试"></p><h2 id="SSD-硬盘性能测试"><a href="#SSD-硬盘性能测试" class="headerlink" title="SSD 硬盘性能测试"></a>SSD 硬盘性能测试</h2><p>SSD 性能如下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">-----------------------------------硬盘测试-通过fio测试-----------------------------------</span><br><span class="line">测试路径         块大小       读测试(IOPS)            写测试(IOPS)            总和(IOPS)</span><br><span class="line">/root             4k        101.93 MB/s(25.5k)      102.20 MB/s(25.6k)      204.13 MB/s(51.0k)</span><br><span class="line">/root             64k       807.59 MB/s(12.6k)      811.84 MB/s(12.7k)      1.62 GB/s(25.3k)</span><br><span class="line">/root             512k      1.49 GB/s(2903)         1.57 GB/s(3058)         3.05 GB/s(5961)</span><br><span class="line">/root             1m        1.52 GB/s(1487)         1.63 GB/s(1587)         3.15 GB/s(3074)</span><br></pre></td></tr></table></figure><h2 id="流媒体解锁"><a href="#流媒体解锁" class="headerlink" title="流媒体解锁"></a>流媒体解锁</h2><p>出口 ip 支持解锁 Netflix、Youtube，还不支持 DisneyPlus 解锁。</p><h2 id="IP-质量检测"><a href="#IP-质量检测" class="headerlink" title="IP 质量检测"></a>IP 质量检测</h2><p>ip 质量检测如下，情况比较良好。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">--------------------------------------IP质量检测--------------------------------------</span><br><span class="line">以下为各数据库编号，输出结果后将自带数据库来源对应的编号</span><br><span class="line">ipinfo数据库  [0] | scamalytics数据库 [1] | virustotal数据库   [2] | abuseipdb数据库   [3] | ip2location数据库    [4]</span><br><span class="line">ip-api数据库  [5] | ipwhois数据库     [6] | ipregistry数据库   [7] | ipdata数据库      [8] | db-ip数据库          [9]</span><br><span class="line">ipapiis数据库 [A] | ipapicom数据库    [B] | bigdatacloud数据库 [C] | dkly数据库        [D] | ipqualityscore数据库 [E]</span><br><span class="line">IPV4:</span><br><span class="line">安全得分:</span><br><span class="line">声誉(越高越好): 0 [2]</span><br><span class="line">信任得分(越高越好): 34 [8]</span><br><span class="line">VPN得分(越低越好): 2 [8]</span><br><span class="line">代理得分(越低越好): 100 [8]</span><br><span class="line">社区投票-无害: 0 [2]</span><br><span class="line">社区投票-恶意: 0 [2]</span><br><span class="line">威胁得分(越低越好): 96 [8]</span><br><span class="line">欺诈得分(越低越好): 0 [1 E]</span><br><span class="line">滥用得分(越低越好): 0 [3]</span><br><span class="line">ASN滥用得分(越低越好): 0.0018 (Low) [A]</span><br><span class="line">公司滥用得分(越低越好): 0.0117 (Elevated) [A]</span><br><span class="line">威胁级别: low [9]</span><br><span class="line">黑名单记录统计:(有多少黑名单网站有记录):</span><br><span class="line">无害记录数: 0 [2]  恶意记录数: 0 [2]  可疑记录数: 0 [2]  无记录数: 95 [2]</span><br><span class="line">安全信息:</span><br><span class="line">使用类型: Commercial [3] corporate [9] hosting [A] business [0 7 8] hosting - high probability [C]</span><br><span class="line">公司类型: business [A] isp [0 7]</span><br><span class="line">是否云提供商: No [7]</span><br><span class="line">是否数据中心: Yes [1 C] No [0 5 6 8 A]</span><br><span class="line">是否移动设备: No [5 A C] Yes [E]</span><br><span class="line">是否代理: No [0 1 4 5 6 7 8 9 A C E]</span><br><span class="line">是否VPN: No [0 1 6 7 A C E]</span><br><span class="line">是否Tor: No [0 1 3 6 7 8 A C E]</span><br><span class="line">是否Tor出口: No [1 7]</span><br><span class="line">是否网络爬虫: No [9 A E]</span><br><span class="line">是否匿名: No [1 6 7 8]</span><br><span class="line">是否攻击者: No [7 8]</span><br><span class="line">是否滥用者: No [7 8 A C E]</span><br><span class="line">是否威胁: No [7 8 C]</span><br><span class="line">是否中继: No [0 7 8 C]</span><br><span class="line">是否Bogon: No [7 8 A C]</span><br><span class="line">是否机器人: No [E]</span><br><span class="line">DNS-黑名单: 315(Total_Check) 0(Clean) 7(Blacklisted) 18(Other)</span><br></pre></td></tr></table></figure><h2 id="IP-路由追踪-三网回程路由"><a href="#IP-路由追踪-三网回程路由" class="headerlink" title="IP 路由追踪 三网回程路由"></a>IP 路由追踪 三网回程路由</h2><p>IP 回程路由非常好！</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250912233900889.png" alt="路由追踪 三网回程路由"></p><h2 id="IP-路由追踪-国内去程路由"><a href="#IP-路由追踪-国内去程路由" class="headerlink" title="IP 路由追踪 国内去程路由"></a>IP 路由追踪 国内去程路由</h2><p>去程路由直直的非常好。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250912234149190.webp" alt="路由追踪 去程路由"></p><h2 id="Ping-IP"><a href="#Ping-IP" class="headerlink" title="Ping IP"></a>Ping IP</h2><p>ping 延迟非常低，属于比较好的香港速度。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250912234312329.webp" alt="ping ip"></p><h2 id="附近节点网速测试"><a href="#附近节点网速测试" class="headerlink" title="附近节点网速测试"></a>附近节点网速测试</h2><p>这款主机的网络带宽 3M 上传、3M 下载，网络上传和下载的速度测试如下，完全能跑满小水管：</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250912234425903.png" alt="服务器带宽测试"></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>啥都可以干，路由线路非常好，可以选大一点的水管机型。</p>]]>
    </content>
    <id>https://pidan.dev/20250912/test-rainyun-cloud-host-server-hk-fast/</id>
    <link href="https://pidan.dev/20250912/test-rainyun-cloud-host-server-hk-fast/"/>
    <published>2025-09-12T15:29:30.000Z</published>
    <summary>
      <![CDATA[<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250912233559513.png" alt="雨云 香港主机卡片"></p>
<p>本文选了润雨云云服务器香港极速三区三网直连（CN2+CMI+CUG）主机来做使用评测。</p>
<p>CPU 1 核、1G 内存、30G 硬盘 SSD、3M 上传、3M 下载、不限流量。</p>
<p>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev">雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），量大管饱，经济实惠，还提供 1 元一天体验版本。</p>]]>
    </summary>
    <title>雨云 云服务器评测 香港三网直连</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="评测" scheme="https://pidan.dev/categories/%E8%AF%84%E6%B5%8B/"/>
    <category term="vps" scheme="https://pidan.dev/tags/vps/"/>
    <category term="云主机" scheme="https://pidan.dev/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA/"/>
    <category term="评测" scheme="https://pidan.dev/tags/%E8%AF%84%E6%B5%8B/"/>
    <category term="雨云" scheme="https://pidan.dev/tags/%E9%9B%A8%E4%BA%91/"/>
    <content>
      <![CDATA[<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911224415022.png" alt="网络去程路由追踪"></p><p>本文选了润雨云云服务器香港大带宽四区（移动优化 IIJ）主机来做使用评测。<br>CPU 4核、8G内存、30G硬盘SSD、100M上传、100M下载、300G流量。<br>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev">雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），量大管饱，经济实惠，还提供 1 元一天体验版本。</p><span id="more"></span><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911224641124.png" alt="雨云香港主机卡片"></p><h2 id="评测脚本"><a href="#评测脚本" class="headerlink" title="评测脚本"></a>评测脚本</h2><p>使用 <a href="https://github.com/oneclickvirt/ecs">https://github.com/oneclickvirt/ecs</a> 开源项目</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">export</span> noninteractive=<span class="literal">true</span> &amp;&amp; curl -L https://raw.githubusercontent.com/oneclickvirt/ecs/master/goecs.sh -o goecs.sh &amp;&amp; <span class="built_in">chmod</span> +x goecs.sh &amp;&amp; ./goecs.sh <span class="built_in">env</span> &amp;&amp; ./goecs.sh install &amp;&amp; goecs</span><br></pre></td></tr></table></figure><p>开始自动测试主机性能。</p><h2 id="CPU-和内存性能测试"><a href="#CPU-和内存性能测试" class="headerlink" title="CPU 和内存性能测试"></a>CPU 和内存性能测试</h2><p>AMD EPYC 7K62 48-Core Processor</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911224916679.png" alt="cpu和内存性能测试结果"></p><h2 id="SSD-硬盘性能测试"><a href="#SSD-硬盘性能测试" class="headerlink" title="SSD 硬盘性能测试"></a>SSD 硬盘性能测试</h2><p>SSD 性能如下：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">-----------------------------------硬盘测试-通过fio测试-----------------------------------</span><br><span class="line">测试路径         块大小       读测试(IOPS)            写测试(IOPS)            总和(IOPS)</span><br><span class="line">/root             4k        149.89 MB/s(37.5k)      150.28 MB/s(37.6k)      300.17 MB/s(75.0k)</span><br><span class="line">/root             64k       1.27 GB/s(19.8k)        1.27 GB/s(19.9k)        2.54 GB/s(39.7k)</span><br><span class="line">/root             512k      1.39 GB/s(2712)         1.46 GB/s(2856)         2.85 GB/s(5568)</span><br><span class="line">/root             1m        1.48 GB/s(1445)         1.58 GB/s(1541)         3.06 GB/s(2986)</span><br></pre></td></tr></table></figure><h2 id="流媒体解锁"><a href="#流媒体解锁" class="headerlink" title="流媒体解锁"></a>流媒体解锁</h2><p>出口 ip 支持解锁 Netflix、Youtube，还不支持 DisneyPlus 解锁。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911225324374.png" alt="流媒体解锁结果图"></p><h2 id="IP-质量检测"><a href="#IP-质量检测" class="headerlink" title="IP 质量检测"></a>IP 质量检测</h2><p>ip 质量检测如下，情况比较良好。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line">--------------------------------------IP质量检测--------------------------------------</span><br><span class="line">以下为各数据库编号，输出结果后将自带数据库来源对应的编号</span><br><span class="line">ipinfo数据库  [0] | scamalytics数据库 [1] | virustotal数据库   [2] | abuseipdb数据库   [3] | ip2location数据库    [4]</span><br><span class="line">ip-api数据库  [5] | ipwhois数据库     [6] | ipregistry数据库   [7] | ipdata数据库      [8] | db-ip数据库          [9]</span><br><span class="line">ipapiis数据库 [A] | ipapicom数据库    [B] | bigdatacloud数据库 [C] | dkly数据库        [D] | ipqualityscore数据库 [E]</span><br><span class="line">IPV4:</span><br><span class="line">安全得分:</span><br><span class="line">声誉(越高越好): 0 [2]</span><br><span class="line">信任得分(越高越好): 36 [8]</span><br><span class="line">VPN得分(越低越好): 2 [8]</span><br><span class="line">代理得分(越低越好): 100 [8]</span><br><span class="line">社区投票-无害: 0 [2]</span><br><span class="line">社区投票-恶意: 0 [2]</span><br><span class="line">威胁得分(越低越好): 89 [8]</span><br><span class="line">欺诈得分(越低越好): 17 [1] 0 [E]</span><br><span class="line">滥用得分(越低越好): 0 [3]</span><br><span class="line">ASN滥用得分(越低越好): 0.0018 (Low) [A]</span><br><span class="line">公司滥用得分(越低越好): 0.0068 (Low) [A]</span><br><span class="line">威胁级别: low [9]</span><br><span class="line">黑名单记录统计:(有多少黑名单网站有记录):</span><br><span class="line">无害记录数: 0 [2] 恶意记录数: 0 [2]  可疑记录数: 0 [2]  无记录数: 95 [2]</span><br><span class="line">安全信息:</span><br><span class="line">使用类型: business [0 7 8] hosting [A] Commercial [3] corporate [9] hosting - high probability [C]</span><br><span class="line">公司类型: isp [0 7] business [A]</span><br><span class="line">是否云提供商: No [7]</span><br><span class="line">是否数据中心: Yes [1 C] No [0 5 6 8 A]</span><br><span class="line">是否移动设备: Yes [E] No [5 A C]</span><br><span class="line">是否代理: No [0 1 4 5 6 7 8 9 A C E]</span><br><span class="line">是否VPN: No [0 1 6 7 A C E]</span><br><span class="line">是否Tor: No [0 1 3 6 7 8 A C E]</span><br><span class="line">是否Tor出口: No [1 7]</span><br><span class="line">是否网络爬虫: No [9 A E]</span><br><span class="line">是否匿名: No [1 6 7 8]</span><br><span class="line">是否攻击者: No [7 8]</span><br><span class="line">是否滥用者: No [7 8 A C E]</span><br><span class="line">是否威胁: No [7 8 C]</span><br><span class="line">是否中继: No [0 7 8 C]</span><br><span class="line">是否Bogon: No [7 8 A C]</span><br><span class="line">是否机器人: No [E]</span><br><span class="line">DNS-黑名单: 315(Total_Check) 0(Clean) 7(Blacklisted) 12(Other)</span><br></pre></td></tr></table></figure><h2 id="IP-路由追踪-三网回程路由"><a href="#IP-路由追踪-三网回程路由" class="headerlink" title="IP 路由追踪 三网回程路由"></a>IP 路由追踪 三网回程路由</h2><p>IP 回程路由一般，有点绕路，</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911225831867.png" alt="IP路由追踪 三网回程"></p><h2 id="IP-路由追踪-国内去程路由"><a href="#IP-路由追踪-国内去程路由" class="headerlink" title="IP 路由追踪 国内去程路由"></a>IP 路由追踪 国内去程路由</h2><p>去程路由直直的非常好。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911230045968.png" alt="IP路由追踪 国内去程路由"></p><h2 id="Ping-IP"><a href="#Ping-IP" class="headerlink" title="Ping IP"></a>Ping IP</h2><p>作为香港这么近的地理位置，这个延迟结果只能算中规中矩，不是太好，但是这个主机本来也是大带宽策略，不是低延迟策略，不能要求太多，建站用完全没问题。</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911234653924.png" alt="ping ip 结果图片"></p><h2 id="附近节点网速测试"><a href="#附近节点网速测试" class="headerlink" title="附近节点网速测试"></a>附近节点网速测试</h2><p>这款主机的网络带宽 100M 上传、100M 下载，网络上传和下载的速度测试如下，大致能跑满：</p><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911230209450.png" alt="附近节点网速测试"></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>可以用于建站，这个区域带宽很足，比较推荐。</p>]]>
    </content>
    <id>https://pidan.dev/20250911/test-rainyun-cloud-host-server-hk/</id>
    <link href="https://pidan.dev/20250911/test-rainyun-cloud-host-server-hk/"/>
    <published>2025-09-11T14:37:22.000Z</published>
    <summary>
      <![CDATA[<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250911224415022.png" alt="网络去程路由追踪"></p>
<p>本文选了润雨云云服务器香港大带宽四区（移动优化 IIJ）主机来做使用评测。<br>CPU 4核、8G内存、30G硬盘SSD、100M上传、100M下载、300G流量。<br>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev">雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），量大管饱，经济实惠，还提供 1 元一天体验版本。</p>]]>
    </summary>
    <title>雨云 云服务器评测 香港大带宽四区IIJ移动优化</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="评测" scheme="https://pidan.dev/categories/%E8%AF%84%E6%B5%8B/"/>
    <category term="vps" scheme="https://pidan.dev/tags/vps/"/>
    <category term="云主机" scheme="https://pidan.dev/tags/%E4%BA%91%E4%B8%BB%E6%9C%BA/"/>
    <category term="评测" scheme="https://pidan.dev/tags/%E8%AF%84%E6%B5%8B/"/>
    <category term="雨云" scheme="https://pidan.dev/tags/%E9%9B%A8%E4%BA%91/"/>
    <content>
      <![CDATA[<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250910231337804.png" alt="雨云日本主机"></p><p>雨云最新的云服务器日本东京开始公测，本文选了东京软银大带宽2区（移动优化）主机来做使用评测。<br>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev"> 雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），还提供1元一天体验版本。</p><span id="more"></span><h2 id="主机配置"><a href="#主机配置" class="headerlink" title="主机配置"></a>主机配置</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250910231611614.png" alt="主机配置"></p><p>这个区域延迟会高一点，但是带宽给的比较大，我们选了100M带宽，2核4G版本使用。</p><p>下图为主机cpu信息：AMD EPYC 7K62<br><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250910231640626.png" alt="主机cpu信息"></p><h2 id="Ping-IP"><a href="#Ping-IP" class="headerlink" title="Ping IP"></a>Ping IP</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250910231709845.png" alt="ping ip"></p><p>简单ping了一下ip，建站没问题，延迟有点高也完全能接受，晚上偶尔丢包，我在北京实测90ms到140ms左右波动。</p><h2 id="IP-路由追踪"><a href="#IP-路由追踪" class="headerlink" title="IP 路由追踪"></a>IP 路由追踪</h2><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250910231806702.png"></p><p>去程也是正常走线路，没有绕路。回程不知道咋测，不测了。</p>]]>
    </content>
    <id>https://pidan.dev/20250910/test-rainyun-cloud-host-server/</id>
    <link href="https://pidan.dev/20250910/test-rainyun-cloud-host-server/"/>
    <published>2025-09-10T15:12:09.000Z</published>
    <summary>
      <![CDATA[<p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250910231337804.png" alt="雨云日本主机"></p>
<p>雨云最新的云服务器日本东京开始公测，本文选了东京软银大带宽2区（移动优化）主机来做使用评测。<br>还没购买的可以注册购买 <a href="https://www.rainyun.com/ODA1MzUy_?s=pidan.dev"> 雨云 - 新一代云服务提供商</a>（优惠码：ODA1MzUy），还提供1元一天体验版本。</p>]]>
    </summary>
    <title>雨云 云服务器评测 日本东京软银大带宽2区IIJ移动优化</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="UPS" scheme="https://pidan.dev/tags/UPS/"/>
    <category term="NAS" scheme="https://pidan.dev/tags/NAS/"/>
    <category term="威联通" scheme="https://pidan.dev/tags/%E5%A8%81%E8%81%94%E9%80%9A/"/>
    <category term="PVE" scheme="https://pidan.dev/tags/PVE/"/>
    <category term="NUT" scheme="https://pidan.dev/tags/NUT/"/>
    <content>
      <![CDATA[<p>我们要做到流程：</p><ol><li>QNAP 威联通 NAS 连接 UPS 并配置断电网络广播</li><li>pve 或 pc 或 linux 客户端使用 NUT 监听 NAS 的断电消息</li></ol><span id="more"></span><p>我们假设：</p><ul><li>你的威联通 NAS ip 为 192.168.124.100（作为 server）</li><li>你的 PVE 或者 PC ip 为 192.168.124.160（作为 client）</li></ul><h2 id="PVE-配置-NUT-监听-NAS-断电消息"><a href="#PVE-配置-NUT-监听-NAS-断电消息" class="headerlink" title="PVE 配置 NUT 监听 NAS 断电消息"></a>PVE 配置 NUT 监听 NAS 断电消息</h2><h3 id="NAS-连接-UPS-并启用断电网络广播"><a href="#NAS-连接-UPS-并启用断电网络广播" class="headerlink" title="NAS 连接 UPS 并启用断电网络广播"></a>NAS 连接 UPS 并启用断电网络广播</h3><p><img src="https://r2.pidan.dev/finchxu/blog-cf/imgs/20250906120656616.png"></p><h3 id="查看威联通-NAS-UPS-SERVER-配置"><a href="#查看威联通-NAS-UPS-SERVER-配置" class="headerlink" title="查看威联通 NAS UPS SERVER 配置"></a>查看威联通 NAS UPS SERVER 配置</h3><p>通过 ssh 登录你的 NAS，查看 ups nut server 配置</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cat</span> /mnt/HDA_ROOT/.config/ups/upsd.users</span><br></pre></td></tr></table></figure><p>威联通的配置都是固定的如下，账号 admin，密码 123456</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">[admin]</span><br><span class="line">        password = 123456</span><br><span class="line">        allowfrom = localhost</span><br><span class="line">actions = SET</span><br><span class="line">instcmds = ALL</span><br><span class="line">        upsmon master           <span class="comment"># or upsmon slave</span></span><br></pre></td></tr></table></figure><h3 id="在-PVE-配置-NUT-client-监听"><a href="#在-PVE-配置-NUT-client-监听" class="headerlink" title="在 PVE 配置 NUT client 监听"></a>在 PVE 配置 NUT client 监听</h3><p>在你的 PVE shell 或 ssh 里操作</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装</span></span><br><span class="line">apt install nut -y</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建开启自启配置</span></span><br><span class="line">systemctl <span class="built_in">enable</span> --now nut-client</span><br><span class="line"></span><br><span class="line"><span class="comment"># 修改nut.conf 启用网络客户端监听模式</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">&quot;MODE=netclient&quot;</span> &gt; /etc/nut/nut.conf</span><br><span class="line"></span><br><span class="line"><span class="comment"># 把威联通的ups nut server信息配置进来</span></span><br><span class="line">vim /etc/nut/upsmon.conf</span><br></pre></td></tr></table></figure><p>在文件底部添加代码：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">MONITOR qnapups@192.168.124.100 1 admin 123456 slave</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 重启加载配置</span></span><br><span class="line">systemctl restart nut-client.service</span><br><span class="line"></span><br><span class="line"><span class="comment"># 检查UPS状态</span></span><br><span class="line">upsc qnapups@192.168.124.100</span><br><span class="line"></span><br><span class="line"><span class="comment"># 打印如下信息就是连接成功了。</span></span><br><span class="line">root@pve:~# upsc qnapups@192.168.124.100</span><br><span class="line">Init SSL without certificate database</span><br><span class="line">battery.charge: 100</span><br><span class="line">battery.charge.low: 10</span><br><span class="line">battery.mfr.date: 2001/01/01</span><br><span class="line">battery.runtime: 2200</span><br><span class="line">battery.runtime.low: 120</span><br><span class="line">battery.type: PbAc</span><br><span class="line">battery.voltage: 13.6</span><br><span class="line">battery.voltage.nominal: 12.0</span><br><span class="line">device.mfr: American Power Conversion</span><br><span class="line">device.model: Back-UPS BK650M2-CH</span><br></pre></td></tr></table></figure><p>参考 <a href="https://github.com/Bpazy/blog/issues/206">https://github.com/Bpazy/blog/issues/206</a></p><h2 id="PC-windows-配置-NUT-Client"><a href="#PC-windows-配置-NUT-Client" class="headerlink" title="PC windows 配置 NUT Client"></a>PC windows 配置 NUT Client</h2><blockquote><p>记得在 NAS 里配置上你 windows 电脑的 ip。</p></blockquote><p>参考 <a href="https://www.cnblogs.com/HeisenbergUncertainty/p/18065831">https://www.cnblogs.com/HeisenbergUncertainty/p/18065831</a></p><p>ttps:&#x2F;&#x2F;github.com&#x2F;gawindx&#x2F;WinNUT-Client</p>]]>
    </content>
    <id>https://pidan.dev/20250906/qnap-nas-config-ups-nut-slave/</id>
    <link href="https://pidan.dev/20250906/qnap-nas-config-ups-nut-slave/"/>
    <published>2025-09-06T03:50:38.000Z</published>
    <summary>
      <![CDATA[<p>我们要做到流程：</p>
<ol>
<li>QNAP 威联通 NAS 连接 UPS 并配置断电网络广播</li>
<li>pve 或 pc 或 linux 客户端使用 NUT 监听 NAS 的断电消息</li>
</ol>]]>
    </summary>
    <title>QNAP威联通NAS连接UPS并配置断电网络广播，pve客户端使用NUT监听</title>
    <updated>2026-05-26T14:45:37.888Z</updated>
  </entry>
  <entry>
    <author>
      <name>finch xu</name>
    </author>
    <category term="技术分享" scheme="https://pidan.dev/categories/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/"/>
    <category term="DNS" scheme="https://pidan.dev/tags/DNS/"/>
    <content>
      <![CDATA[<p>记录一些可用国内外安全 DNS</p><span id="more"></span><table><thead><tr><th>Provider</th><th>Protocol</th><th>Safety</th><th>Address</th><th>Note</th></tr></thead><tbody><tr><td>阿里云</td><td>DNS over UDP IPv4</td><td>DNSSEC,ENDS</td><td>223.5.5.5, 223.6.6.6</td><td></td></tr><tr><td>阿里云</td><td>DNS over UDP IPv6</td><td>DNSSEC,ENDS</td><td>2400:3200::1, 2400:3200:baba::1</td><td></td></tr><tr><td>阿里云</td><td>DNS over HTTPS&#x2F;2</td><td>DNSSEC,ENDS</td><td><a href="https://dns.alidns.com/dns-query">https://dns.alidns.com/dns-query</a></td><td></td></tr><tr><td>阿里云</td><td>DNS over HTTPS&#x2F;2</td><td>DNSSEC,ENDS</td><td><a href="https://223.5.5.5/dns-query">https://223.5.5.5/dns-query</a></td><td></td></tr><tr><td>阿里云</td><td>DNS over HTTPS&#x2F;2</td><td>DNSSEC,ENDS</td><td><a href="https://223.6.6.6/dns-query">https://223.6.6.6/dns-query</a></td><td></td></tr><tr><td>阿里云</td><td>DNS over HTTPS&#x2F;3</td><td>DNSSEC,ENDS</td><td>h3:&#x2F;&#x2F;dns.alidns.com&#x2F;dns-query</td><td></td></tr><tr><td>阿里云</td><td>DNS over HTTPS&#x2F;3</td><td>DNSSEC,ENDS</td><td>h3:&#x2F;&#x2F;223.5.5.5&#x2F;dns-query</td><td></td></tr><tr><td>阿里云</td><td>DNS over HTTPS&#x2F;3</td><td>DNSSEC,ENDS</td><td>h3:&#x2F;&#x2F;223.6.6.6&#x2F;dns-query</td><td></td></tr><tr><td>阿里云</td><td>DNS over QUIC</td><td>DNSSEC,ENDS</td><td>quic:&#x2F;&#x2F;dns.alidns.com:853</td><td></td></tr><tr><td>阿里云</td><td>DNS over QUIC</td><td>DNSSEC,ENDS</td><td>quic:&#x2F;&#x2F;223.5.5.5:853</td><td></td></tr><tr><td>阿里云</td><td>DNS over QUIC</td><td>DNSSEC,ENDS</td><td>quic:&#x2F;&#x2F;223.6.6.6:853</td><td></td></tr><tr><td>阿里云</td><td>DNS over TLS</td><td>DNSSEC,ENDS</td><td>tls:&#x2F;&#x2F;dns.alidns.com</td><td></td></tr><tr><td>阿里云</td><td></td><td></td><td><a href="https://alidns.com/">https://alidns.com/</a></td><td>文档</td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td>腾讯</td><td>DNS over UDP</td><td>ENDS</td><td>119.29.29.29</td><td></td></tr><tr><td>腾讯</td><td>DNS over UDP IPv6</td><td>ENDS</td><td>2402:4e00::</td><td></td></tr><tr><td>腾讯</td><td>DNS over HTTPS&#x2F;2</td><td>ENDS</td><td><a href="https://doh.pub/dns-query">https://doh.pub/dns-query</a></td><td></td></tr><tr><td>腾讯</td><td>DNS over HTTPS&#x2F;2</td><td>ENDS</td><td><a href="https://120.53.53.53/dns-query">https://120.53.53.53/dns-query</a></td><td></td></tr><tr><td>腾讯</td><td>DNS over HTTPS&#x2F;2</td><td>ENDS</td><td><a href="https://1.12.12.12/dns-query">https://1.12.12.12/dns-query</a></td><td></td></tr><tr><td>腾讯</td><td>DNS over TLS</td><td>ENDS</td><td>tls:&#x2F;&#x2F;dot.pub</td><td></td></tr><tr><td>腾讯</td><td>DNS over HTTPS SM2</td><td>ENDS</td><td><a href="https://sm2.doh.pub/dns-query">https://sm2.doh.pub/dns-query</a></td><td>国密 SM2</td></tr><tr><td>腾讯</td><td></td><td></td><td><a href="https://www.dnspod.cn/products/publicdns">https://www.dnspod.cn/products/publicdns</a></td><td>文档</td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td>火山引擎</td><td>DNS over UDP(IPv4)</td><td></td><td>180.184.1.1, 180.184.2.2</td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td>CloudFlare</td><td>DNS over UDP IPv4</td><td>DNSSEC,ENDS</td><td>1.1.1.1, 1.0.0.1</td><td></td></tr><tr><td>CloudFlare</td><td>DNS over UDP IPv6</td><td>DNSSEC,ENDS</td><td>2606:4700:4700::1111, 2606:4700:4700::1001</td><td></td></tr><tr><td>CloudFlare</td><td>DNS-over-HTTPS IPv4 IPv6</td><td>DNSSEC,ENDS</td><td><a href="https://dns.cloudflare.com/dns-query">https://dns.cloudflare.com/dns-query</a></td><td></td></tr><tr><td>CloudFlare</td><td>DNS over TLS</td><td>DNSSEC,ENDS</td><td>tls:&#x2F;&#x2F;one.one.one.one</td><td></td></tr><tr><td>CloudFlare</td><td>DNS over TLS</td><td>DNSSEC,ENDS</td><td>tls:&#x2F;&#x2F;1.1.1.1, tls:&#x2F;&#x2F;1.0.0.1</td><td></td></tr><tr><td>CloudFlare</td><td>DNS over UDP IPv4</td><td>DNSSEC,ENDS</td><td>1.1.1.3, 1.0.0.3</td><td>阻止恶意软件和成人内容</td></tr><tr><td>CloudFlare</td><td>DNS over UDP IPv6</td><td>DNSSEC,ENDS</td><td>2606:4700:4700::1113, 2606:4700:4700::1003</td><td>阻止恶意软件和成人内容</td></tr><tr><td>CloudFlare</td><td>DNS-over-HTTPS IPv4</td><td>DNSSEC,ENDS</td><td><a href="https://family.cloudflare-dns.com/dns-query">https://family.cloudflare-dns.com/dns-query</a></td><td>阻止恶意软件和成人内容</td></tr><tr><td>CloudFlare</td><td>DNS-over-TLS</td><td>DNSSEC,ENDS</td><td>tls:&#x2F;&#x2F;family.cloudflare-dns.com</td><td>阻止恶意软件和成人内容</td></tr><tr><td>CloudFlare</td><td></td><td></td><td><a href="https://developers.cloudflare.com/1.1.1.1/encryption/">https://developers.cloudflare.com/1.1.1.1/encryption/</a></td><td>文档</td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Google</td><td>DNS over UDP IPv4</td><td>DNSSEC,ENDS</td><td>8.8.8.8, 8.8.4.4</td><td></td></tr><tr><td>Google</td><td>DNS over UDP IPv6</td><td>DNSSEC,ENDS</td><td>2001:4860:4860::8888, 2001:4860:4860::8844</td><td></td></tr><tr><td>Google</td><td>DNS over HTTPS</td><td>DNSSEC,ENDS</td><td><a href="https://dns.google/dns-query">https://dns.google/dns-query</a></td><td></td></tr><tr><td>Google</td><td>DNS over TLS</td><td>DNSSEC,ENDS</td><td>tls:&#x2F;&#x2F;dns.google</td><td></td></tr><tr><td>Google</td><td></td><td></td><td><a href="https://developers.google.com/speed/public-dns?hl=zh-cn">https://developers.google.com/speed/public-dns?hl=zh-cn</a></td><td>文档</td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td>AdGuard</td><td>DNS over QUIC</td><td></td><td>quic:&#x2F;&#x2F;family.adguard-dns.com</td><td></td></tr><tr><td>AdGuard</td><td>DNS over HTTP</td><td></td><td><a href="https://dns.adguard-dns.com/dns-query">https://dns.adguard-dns.com/dns-query</a></td><td></td></tr><tr><td>AdGuard</td><td></td><td></td><td><a href="https://adguard-dns.io/zh_cn/public-dns.html">https://adguard-dns.io/zh_cn/public-dns.html</a></td><td>文档</td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Quad9</td><td>DNS over UDP</td><td></td><td>9.9.9.9, 149.112.112.112</td><td></td></tr><tr><td>Quad9</td><td>DNS over HTTPS</td><td></td><td><a href="https://dns.quad9.net/dns-query">https://dns.quad9.net/dns-query</a></td><td></td></tr><tr><td>Quad9</td><td>DNS over HTTPS</td><td></td><td><a href="https://dns.quad9.net/dns-query">https://dns.quad9.net/dns-query</a></td><td></td></tr><tr><td>Quad9</td><td>DNS over HTTPS</td><td>DNSSEC,ENDS</td><td><a href="https://dns11.quad9.net/dns-query">https://dns11.quad9.net/dns-query</a></td><td></td></tr><tr><td>Quad9</td><td>DNS over UDP IPv4</td><td>DNSSEC,ENDS</td><td>9.9.9.11, 149.112.112.11</td><td></td></tr><tr><td></td><td></td><td></td><td></td><td></td></tr><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><p>更全的全球 DNS 文档 <a href="https://adguard-dns.io/kb/zh-CN/general/dns-providers">https://adguard-dns.io/kb/zh-CN/general/dns-providers</a><br>EDNS 客户端子网 (ECS) 指南 <a href="https://developers.google.com/speed/public-dns/docs/ecs?hl=zh-cn">https://developers.google.com/speed/public-dns/docs/ecs?hl=zh-cn</a><br>DNSSEC <a href="https://developers.google.com/speed/public-dns/docs/security?hl=zh-cn#dnssec">https://developers.google.com/speed/public-dns/docs/security?hl=zh-cn#dnssec</a></p>]]>
    </content>
    <id>https://pidan.dev/20250823/available-dns/</id>
    <link href="https://pidan.dev/20250823/available-dns/"/>
    <published>2025-08-23T15:08:30.000Z</published>
    <summary>
      <![CDATA[<p>记录一些可用国内外安全 DNS</p>]]>
    </summary>
    <title>available-dns</title>
    <updated>2026-05-26T14:45:37.884Z</updated>
  </entry>
</feed>
