用户真正想问的:不是「有没有这条规则」
在搜索引擎里,和「分流不生效」一起出现的,往往是「我明明加了 DOMAIN 为什么还是直连」「GEOIP,CN 写了为什么还走代理」。在工程上,这些句子应当被翻译成同一句判断:对这一条连接,内核在 rules: 里到底命中了哪一行? Clash 系列内核不会对同一连接「投票表决」多行规则,也不会自动帮你把最符合意图的那行挪到最前;它只做一件事:从列表顶端往下扫,遇到第一个能匹配当前连接上下文的行,就采用该行第三列(或等价格式里指定的)策略,并停止继续向下扫描。因此,你手写的精确定义,只要排在一条更宽、但更早能命中的规则后面,就永无出头之日——在日志里就会表现为「我写的行从来没出现过」。
与 按进程路由 或 Sniffer 还原域名 等专题相比:本文不展开进程名怎么拼、SNI 怎么开,而假设你已经能让日志里出现「可供规则匹配的主机名或 IP」。若日志里只有 IP 没有域名、GEOSITE 又长期不命中,应先回到那两篇之一补齐「匹配输入」,再谈顺序;否则你会在「顺序正确」的幻觉里反复试节点。
铁律:自上而下,只认第一条命中
把 rules: 想成单行道上的检查站:第 1 行检查不过,看第 2 行,依此类推。任何一行只要条件满足,就发放「通行证」并结束。这里有两个常见误解需要纠正。第一,行号在 YAML 里越靠上,优先级越高,与「这行是 DOMAIN 还是 GEOIP」没有绝对的高低关系;再具体的 DOMAIN 规则,如果物理位置在一条宽泛规则之后,也不会插队。第二,「规则优先级」在文档里常指代类型之间的默认顺序,但最终仍以你的列表为准——订阅合并、GUI 的「覆写块」、远程 Rule Provider 展开后的行序,合起来才是真的顺序。
实践上,请你养成习惯:在客户端连接日志里找命中的规则名/行描述。若你期望命中「单独为某站写的 DOMAIN 行」,但日志里反复显示「某条国内直连桶」或「来自远程集的一条大类规则」,这几乎总说明那一条大类在合并结果里更靠前。此时不要先换机场节点,而应先调整行序或把例外写进更靠前的 pre-rules、override 等机制(以你使用的前端/模板为准),把个人例外整段前移到安全位置。
最后一行 MATCH:全表兜底,不是「再试一次」
MATCH 是一种不附加 DNS/IP/主机名条件 的通配,语义是:「如果上面所有行都没命中,就把这条连接交给第三列写的策略或策略组。」它通常应出现在 rules: 的最末尾,并给出一个你认可的全局默认出口,例如 MATCH,PROXY 或 MATCH,DIRECT。它不是在其它规则都试过之后的「再匹配一轮」,而是:一旦执行到这里,说明上面没有任何一行适用于当前上下文的条件判断已经返回 true。若你忘了写 MATCH,或合并时被模板截断,行为取决于内核与版本,常见表现是走某个隐式默认或策略组中第一条——这类不确定性正是线上「随订阅版本飘」的温床。
也请注意:MATCH 行本身不解决「想分流却走了全局默认」的问题;如果你希望某类流量在 Match 前就被拿走,必须在该行之前用 DOMAIN、IP-CIDR、GEOSITE、PROCESS-NAME 等条件把它截住。很多用户的配置里 GEOIP,CN,DIRECT 很靠前,后面才是海外站点的 DOMAIN-suffix,那么只要 GEOIP 先判定为 CN,你写在后面的「国外站走代理」永远执行不到,这就是「分流不生效」在顺序层面的典型样例,而不是 MATCH 写坏。
各类型之间谁「抢跑」?没有魔法,只拼列表位置
DOMAIN 类、IP-CIDR、GEOIP、GEOSITE、RULE-SET、PROCESS-NAME 等,本质上都是条件匹配器。社区模板里常给出推荐「骨架顺序」:例如先私有网段、再广告、再国内/局域网、再国外站点、再国家桶、最后 MATCH。这背后的逻辑是:把最不可能争议、最应该早停的放行或拦截放在最前,把最宽的桶放在中后段。你本地若把一条「全端口拦截」或「全 CN 直连」顶在很前,它会成为事实上的高优先级,其它精细规则再漂亮也只能做摆设。
涉及 IP 与域名两类输入时,还要记住:有的规则在「仅有 IP、尚未有域名」阶段参与匹配,有的规则需要等 DNS 或 Sniffer 补全主机名。若你观察到「同一站点第一次连接命中 GEOIP,刷新后又命中 DOMAIN」,这往往与连接阶段与解析阶段可见信息不同步有关。此时除了顺序,还要对照 DNS 与 FakeIP 总览,让解析路径与规则预期一致。本文保持聚焦顺序;DNS 大段不重复。
第三列是策略组名:先存在,再引用
规则行里写的 PROXY、🚀 节点选择 等,不是魔法字符串,而是 proxy-groups 里已声明的组名,或是 DIRECT、REJECT 等内置策略。若第三列打错了一个字符、或与订阅里实际组名(含表情与空格)不一致,表现为「一命中就报错/回落到默认组」,在初学者眼里也像「规则没生效」。在调整顺序前,应先在面板上确认该组存在且可选节点非空。若你使用 url-test / fallback 等自动选路,具体落在哪个成员节点是策略组自己的逻辑,和「命中了第几条规则」是两层问题,可另读 健康检查与自动切换 一文,避免和本文混淆。
订阅、覆写与「插入位置」:合并后的行序才是真的
很多 GUI 提供「Prepend rules / 在规则最前插入覆写」与「Append / 追在末尾」两类入口。其用意是:远程订阅往往自带庞大国内直连、广告拦截、远程 RULE-SET,你若只会改本地 YAML 文件、却不懂合并顺序,可能一直在改一份根本不会被优先生效的配置层。更隐蔽的一种情况是:你手工把新规则加在文件最底部,而订阅模块在每次更新时把整段 rules 重排,把远程模板重新压到最前。对外表现就是:「我保存了、重启了,可还是老样子」——这不是内核不听话,而是一直在读合并后的别份列表。
因此,务必将「我在编辑器里看到的前几行」与「客户端「完整配置/调试视图」里展开的最终 rules 列表」做一次对照。只有后者才是运行时顺序。对使用 Subconverter 或远程规则集的朋友,可参阅 Subconverter 与 YAML 工作流,理解 provider 与 inline 的边界,但核心始终一句:覆写必须插在会生效的那一层、且能留在合并结果靠前位置。
当「不是顺序」:DNS、FakeIP 与 Sniffer 的错觉
若日志显示命中行正确、策略组也对,但业务仍异常,应怀疑的不是规则顺序,而是解析与连接目标不一致。例如:浏览器 DoH 抢先解析、系统缓存了旧 A 记录、FakeIP 返回与规则假设的不同段。此类问题在现象上常像「分流不生效」或「规则优先级 错乱」,实则需要回到 DNS 段整体排查。与本文并列阅读时,建议以「连接日志中首条命中的行为准」为分界:先确认命中,再下钻 DNS 与 TUN/系统代理是否叠加。
一段可改写的骨架:先看顺序,再填策略名
下例仅演示相对顺序与 MATCH 落点;组名 PROXY、STREAM 请替换为你配置中实际存在的 proxy-groups 名称。远程 RULE-SET 的插入点若由订阅工具决定,请把最在乎的个人例外放在工具允许的「最前覆写区」。
# Skeleton — replace PROXY, STREAM, DIRECT with your real policy / group names
rules:
- DOMAIN-SUFFIX,local,DIRECT
- DOMAIN-SUFFIX,lan,DIRECT
- IP-CIDR,10.0.0.0/8,DIRECT
- GEOSITE,cn,DIRECT
- DOMAIN-SUFFIX,example-foreign.com,STREAM
- GEOSITE,youtube,STREAM
- GEOIP,CN,DIRECT
- MATCH,PROXY
若你的痛点是「海外站误被 GEOIP,CN 吃掉」,在真实排障中通常要么把更精确的域名规则前移到该 GEOIP 行之前,要么审视那笔流量的目标 IP 为什么会被判成 CN(CDN 与家宽出口)。顺序与数据两者常常要一起动。
排查清单:先对日志,再换节点
- 在问题连接出现时,截一张日志:命中规则名/描述 与 策略组/节点。
- 在「完整运行配置」中搜索该规则行,看它在 全表第几行、前面是否还有会抢跑的更宽规则。
- 确认
MATCH在最末,且你理解「其它未命中时」会进哪个默认组。 - 若命中已符合预期但业务仍错,再切 DNS 与 FakeIP / Sniffer 视角排查。
- 每轮订阅或模板更新后,复查一次合并后行首,避免「覆写被顶到后面」回归。
提示:规则逻辑再完美也不能绕过产品条款与法律边界;企业环境请先遵守内部网络策略。
关于下载:日常获取安装包请优先 本站下载页;开源仓库适合查 Issue 与提交记录,不必作为首跳下载入口。
小结
Clash Meta 与 Mihomo 的 规则顺序,用一句话说就是:谁先匹配听谁的;MATCH 负责在整张表都未命中时,把残量流量交给你指定的默认 策略。搞清这一点之后,「写了 GEOIP/DOMAIN 仍不对」这类问题,多半能拆成:要么行序被更宽规则截胡,要么合并后的真实列表早不是你编辑的那份,再要么 DNS/嗅探没把条件喂给规则。与单讲某一类语法的文章相比,这篇刻意留在「表头思维模型」层,方便你和 国家/站点桶 教程、站内配置总览 连读、互相引用。
把「首条命中」读进日志、再动节点,是排查 分流不生效 时最省时的路径;比在网络里盲目切换服务器更能定位根因。相比分散在多种小工具里维护名单,在一份可合并、可审阅的 rules 上协作,也更容易随版本复盘。