背景

一份 mihomo 配置往往同时包含代理节点、自动测速、故障转移、域名分流和兜底规则。配置规模较小时,把这些内容理解成一张“代理列表”似乎也能工作;但节点和规则逐渐增多后,常见问题就会出现:换一个节点为什么要改多处配置?规则已经命中,为什么最终走的不是预期节点?自动选择与手工选择之间又是什么关系?

mihomo 通过 proxies、proxy-groups 和 rules 把这些问题拆成三个职责明确的层次。理解这三层,不仅有助于编写配置,也能让节点维护、策略调整和分流排障变得更可预测。

mihomo 三层设计结论

mihomo 的核心配置可以概括为“能力、策略、决策”三层:

  • proxies 对应“能力池/节点池”,很像 Nginx 的 upstream 成员。
  • proxy-groups 对应“策略层/调度层”,类似“对 upstream 的策略封装(手选、自动优选、故障转移、负载)”。
  • rules 对应“路由决策层”,类似“按条件把请求分流到不同策略”。

但有一个关键差异:mihomo 更偏“连接/流量元数据路由”(L3/L4 + 域名语义),Nginx 更偏“HTTP 请求语义路由”(L7)。

从一次实际连接的执行顺序看,则是:rules 先决定使用哪个策略,proxy-groups 再选出具体出站,最后由 proxies 中的节点完成连接。可以把它记成一句话:规则决定方向,组决定策略,节点决定怎么连接。

图表源文件

下列图表的可编辑 Draw.io 源文件为 Draws/mihomo-three-layer-config-design.drawio,其中包含“三层职责关系”和“单次连接决策流程”两个页面;文章使用同源导出的 SVG。

../../../Draws/mihomo-three-layer-relationship.svg

图 1:mihomo 三层职责关系。主路径是“流量元数据 → rules → proxy-groups → proxies”,规则也可以直接返回内置动作。

三个字段分别解决什么问题

字段关注点典型内容设计目标
proxies单个出站如何连出去协议类型、地址、端口、认证、TLS/Reality/Hysteria 参数把“节点细节”与“策略逻辑”解耦
proxy-groups多个出站怎么选select/url-test/fallback/load-balance 等策略把“策略变化”与“节点定义”解耦
rules什么流量走什么策略DOMAIN/IP-CIDR/GEOIP/RULE-SET 等规则把“业务路由”与“出站实现”解耦

这三个层次拆开后,配置演进更稳定:

  • 换节点,通常只改 proxies。
  • 改选路逻辑,通常只改 proxy-groups。
  • 改业务分流,通常只改 rules。

一次连接如何经过这三层

以 mode: rule 为前提,典型执行链路如下:

../../../Draws/mihomo-runtime-routing-flow.svg

图 2:单次连接的运行时决策流程。规则可以直接执行动作、直接指向节点,或先进入策略组再解析到最终节点。

  1. 入站接收连接

    • 来源可能是 mixed-port、redir、tproxy、tun。
  2. 生成流量元数据(metadata)

    • 目的地址(域名/IP)、端口、协议(TCP/UDP)等。
    • 若启用 DNS fake-ip,会先通过映射把 fake-ip 还原到域名语义。
    • 若启用流量嗅探(sniffer),可从 TLS SNI / HTTP Host 补全域名信息。
  3. 规则引擎顺序匹配 rules

    • 自上而下,first-match-wins(命中即停止)。
    • 规则结果是一个“动作或目标”:DIRECT / REJECT / 某个 proxy-group / 某个 proxy。
  4. 若目标是 proxy-group,进入组策略决策

    • select:使用当前手工选择项。
    • url-test:按探测延迟选择更优节点。
    • fallback:优先主节点,不可用时自动切换。
    • load-balance:按策略分摊连接(版本相关)。
  5. 解析到最终 proxy

    • 确定一个具体节点后,由对应协议适配器发起握手与转发。
  6. 管理连接生命周期

    • 已建立连接通常不会因规则变更而立即迁移;新连接按新规则生效。

这就是三层设计在运行时形成的完整闭环。

与三层设计密切相关的字段

proxy-providers

作用:把节点来源外部化(订阅/API/文件),避免在 proxies 手工维护大量节点。

设计价值:

  • 数据与策略分离:节点集合可动态更新,proxy-groups 只引用集合。
  • 降低变更成本:节点轮换不需要改规则层。

rule-providers

作用:把规则集外部化,rules 里通过 RULE-SET,<name>,<target> 引用。

设计价值:

  • 规则可复用、可更新。
  • 主配置更短,业务规则与基础规则分层。

mode

  • rule:走规则引擎(最常用)。
  • global:忽略规则,强制走一个全局策略。
  • direct:忽略规则,全部直连。

设计价值:用模式切换实现“故障旁路”和“排障开关”。

dns.respect-rules

作用:让 DNS 查询的出站路径也受规则/策略影响,减少“请求走代理但 DNS 直连”造成的策略不一致。

设计价值:统一控制平面,降低 DNS 泄漏和分流错位。

rules 中的 no-resolve

典型写法:IP-CIDR,1.1.1.1/32,Proxy,no-resolve

作用:命中 IP 规则时不再触发额外解析流程。

设计价值:

  • 提升匹配效率。
  • 避免某些场景下的二次解析副作用。

sniffer、tun 与 dns.fake-ip

它们不直接属于三字段,但直接影响 rules 可见的元数据质量:

  • sniffer 提升域名识别能力。
  • dns.fake-ip 让“先 DNS 后连接”的流量仍可按域名规则分流。
  • tun 决定透明代理路径与流量进入方式。

换句话说:这几项是规则引擎的“数据供给层”。

与 Nginx 的对应关系和关键差异

维度mihomoNginx
资源池proxiesupstream 服务器列表
策略层proxy-groupsupstream 负载策略/backup/failover
路由层ruleslocation/map/条件路由
主要决策对象连接元数据(域名/IP/端口/协议/进程等)HTTP 请求语义(Host/URI/Header 等)
生效粒度更偏“连接级”更偏“请求级”
DNS 参与度很高(fake-ip、规则感知 DNS)通常较低(反向代理场景更多依赖上游解析配置)

因此,可以把 mihomo 理解为“面向通用流量的策略路由引擎”,而 Nginx 是“面向 HTTP 服务治理的请求路由引擎”。

一个简化的配置骨架

mode: rule

proxies:
  - { name: "node-hk-01", type: vless, server: "example.com", port: 443, uuid: "<uuid>", tls: true }
  - { name: "node-sg-01", type: hysteria2, server: "example.net", port: 443, password: "<password>" }

proxy-groups:
  - { name: "Auto", type: url-test, proxies: ["node-hk-01", "node-sg-01"], url: "http://www.gstatic.com/generate_204", interval: 300 }
  - { name: "Manual", type: select, proxies: ["Auto", "node-hk-01", "node-sg-01", "DIRECT"] }

rules:
  - DOMAIN-SUFFIX,example.cn,DIRECT
  - DOMAIN-SUFFIX,google.com,Manual
  - GEOIP,CN,DIRECT
  - MATCH,Manual

这个骨架对应的设计意图是:

  • proxies 只描述节点能力。
  • proxy-groups 提供自动与手工两层策略。
  • rules 把业务流量映射到策略,而不是绑死到某个节点。

面向长期维护的配置建议

  1. 规则层始终保留兜底 MATCH,<group>,避免漏流量。
  2. 业务规则、地域规则、兜底规则按顺序分段,保证 first-match 可预测。
  3. 对高频变更的数据(节点、规则集)优先 provider 化,主配置只保留编排。
  4. 对关键组(如 url-test/fallback)统一健康检查参数,减少策略行为漂移。
  5. 排障时用 mode: global/direct 快速隔离“规则问题”与“节点问题”。

总结

proxies 是“能力抽象”,proxy-groups 是“策略抽象”,rules 是“决策抽象”。三者解耦,是 mihomo 配置能够持续扩展、方便运维并且易于排障的核心设计。