← 返回博客

2026年同一份机场订阅换4款客户端对比:Clash Meta、sing-box、v2rayN、Stash 差在哪、节点为什么会丢

📌 一分钟总结

同一份订阅在不同客户端上表现不一样,问题往往不在「谁更快」。本文实测三个内核的协议支持矩阵与空载资源占用,讲清节点为什么会丢、换客户端什么时候有用。

同一份订阅链接,手机上能列出 42 个节点,换到电脑上只剩 33 个;或者节点一个不少,但一到晚上看 4K 就频繁断流。多数人的第一反应是「这个客户端不行」,于是来回换客户端——换完发现没什么变化。问题往往不在「哪个客户端更快」,而在你换的到底是哪一层。

本文不做任何速度测试。原因很直白:客户端的快慢主要由节点、出口线路和本地网络决定,随便跑几个数字就说「A 比 B 快 30%」是不负责任的。本文只做两件能复现的事——用每个内核自带的配置校验器实测它们的协议支持边界,用同一台机器、同一份空载配置实测它们的资源占用;剩下的部分讲清楚「丢节点」「换客户端没用」这两类问题的判断路径。订阅链接本身由机场面板生成,像自由猫这类后台,通常同时提供通用订阅和 Clash 订阅两个入口——这两个入口给你的东西,格式并不一样。

一、先分清「客户端」和「内核」:你换掉的到底是哪一层

绝大多数教程把「Clash Verge Rev」「v2rayN」「Stash」并列成「客户端」,然后开始比谁好用。这个比法一开始就混了两层:界面(GUI)和内核(core)。GUI 决定配置怎么填、日志怎么看;内核决定支持哪些协议、怎么解析订阅、怎么处理 DNS 和 UDP。你以为在换客户端,很可能只是换了个壳,内核换没换才是关键。

常见客户端实际内核原生配置格式平台
Clash Verge Rev / Clash Meta for Android / OpenClashmihomo(原 Clash.Meta)Clash YAML全平台
sing-box 官方客户端 / Hiddify / Karingsing-boxsing-box JSON全平台
v2rayN / v2rayNG / NekorayXray-coreXray JSON + 分享链接Windows / Android / 桌面
Stash / Surge / Shadowrocket闭源自有内核Clash 兼容 YAML 或私有格式Apple 平台为主

看这张表就能明白两件事。第一,桌面端「换客户端」如果从 Clash Verge Rev 换到另一款 Clash 系 GUI,内核还是 mihomo,能力边界完全没变,除界面以外不会有任何差异;第二,从 Clash 系换到 v2rayN,你不只是换了界面,还从 mihomo 换成了 Xray-core——协议支持范围随之改变,这才是「节点变少」的高发场景。各类客户端各自的配置方式,在这篇客户端配置教程里有分平台的步骤。

二、同一份订阅读出来不一样,最先出问题的是「格式」

订阅链接看着都是一串 URL,实际有四种完全不同的内容:

订阅类型内容本质谁能直接读
通用订阅base64 编码的分享链接列表(vmess:// vless:// ss:// 等)v2rayN / v2rayNG / Nekoray
Clash 订阅一段 YAML(proxies / proxy-groups / rules)mihomo 系全部客户端、Stash
sing-box 订阅一段 JSON(inbounds / outbounds / route)sing-box 系
客户端私有格式各家自己的配置语法仅对应客户端

所以「同一份订阅」这句话本身常常是假的:你在 Clash 客户端里加的是 Clash 订阅入口,在 v2rayN 里加的是通用订阅入口,内容从一开始就不一样。真正被拿来对比的,其实是面板同一份节点数据生成的两种不同表达。瑶瑶领先这类面板就是典型做法:一个按钮给通用订阅,另一个按钮给 Clash 订阅,节点是同一批,文件不一样。

当客户端拿不到自己认的格式时,就走第二层:订阅转换。常见的是客户端内置转换、机场自建转换、或者自部署的 subconverter / Sub-Store。转换器干的事说白了就三步——把源格式解出来、把每个节点翻译成目标内核的类型名和字段、再拼成目标格式。问题出在第二步:翻译表不可能覆盖所有内核的所有类型。目标内核不认的类型,转换器要么整个节点丢掉,要么退化成别的写法,而多数转换器不会在你的界面上大声提示「这个节点我没转成功」。

判断方法是先数数,而不是先猜:把订阅原文取回来(curl -s "订阅链接" | base64 -d),统计 vmess:// 与 vless:// 各有多少条;再回到客户端里数节点总数。两边差几条、差的是哪些名字,答案立刻清楚。这一步的完整做法(包括订阅格式互转、转换后节点名对比)在这篇订阅转换与 Sub-Store 教程里讲过,思路比工具更重要。

三、协议支持矩阵实测:哪些节点会被静默丢掉

协议支持不是靠记忆判断的。三个内核都自带配置校验功能——mihomo 用 -t,sing-box 用 check,Xray 用 run -test。给它们一份「只声明协议名、不给任何参数」的最小配置,观察报错类型就能分离出两种情况:报「未知类型 / 不支持的协议」说明这个内核根本不认这个 id;报「缺少某字段 / 参数非法」说明它认,只是配置不完整。

实测环境:Linux x86_64,mihomo v1.19.32、sing-box v1.14.2、Xray-core v26.3.27(均为官方发布版二进制)。共探测 13 个协议 id,结果如下。

协议 idmihomosing-boxXray-core
vless✅✅✅
vmess✅✅✅
trojan✅✅✅
http✅✅✅
shadowsocks❌(它叫 ss)✅✅
socks❌(它叫 socks5)✅✅
socks5✅❌❌
hysteria✅✅✅(要求 version=2)
hysteria2✅✅❌
tuic✅✅❌
anytls✅✅❌
ssh✅✅❌
wireguard✅⚠️ 见下✅

发现一:同一个协议,三个内核可能用不同名字。Shadowsocks 在 mihomo 里必须写 ss,写 shadowsocks 直接报 unsupport proxy type: shadowsocks;而 sing-box 和 Xray 只认 shadowsocks。SOCKS 更绕:mihomo 用 socks5,sing-box 和 Xray 用 socks——三个内核里没有哪一个同时接受两种写法。这就是手工「抄配置」时最常出现的失败:配置逻辑完全正确,只是类型名是另一个内核的写法。

发现二:Hysteria2 的写法在 Xray 系里是反直觉的。mihomo 和 sing-box 都用 hysteria2 这个 id,Xray-core 却把 2 版接在 hysteria 这个 id 下、靠 settings.version: 2 区分:实测把协议写成 hysteria2,Xray 直接返回 unknown config id: hysteria2;改成 hysteria 并带上 version: 2 与 TLS 之后,校验通过(Configuration OK.)。同一个节点,在两个内核里是两种完全不同的配置写法。

发现三:TUIC、AnyTLS、SSH 在 Xray-core 上不存在。订阅里如果有这几类节点,走 v2rayN / v2rayNG 这一系,它们会直接消失。反过来,socks5 与 shadowsocks 这两个「mihomo 口味」的 id 在 sing-box 上也会被拒绝。所以「换客户端后节点变少」不需要玄学解释:先看丢掉的节点是什么协议,再对照这张表,八成能对上。

另外注意 wireguard 这一行的 ⚠️:sing-box 从 1.11.0 起废弃了 WireGuard 出站写法、1.13.0 起移除,1.14.2 实测以出站形式声明会直接报错并提示改用 endpoints。如果你的配置是从旧版本抄来的,内核一升级就会启动失败——这不是机场的问题,也不是订阅的问题。以 IEPL 专线为主的SS-ID这类机场通常只提供主流协议,跨内核反而最省事;如果你专门挑 TUIC、AnyTLS 这类较新的协议,那选机场时就得先确认目标客户端认不认。

四、内核资源占用实测:同一台机器、同一份空载配置

再强调一次:下面这组数字不包含任何速度意义,因为整个测试里没有任何节点、也没有任何流量。它测的是内核本身的开销——启动要多久、空转占多少内存。方法如下:同一台 Linux x86_64 机器,给每个内核一份最小配置(一个本地环回入站 + 直连出站 + 一条兜底直连规则,不配任何上游代理),每个内核独立运行 3 次,记录从进程启动到端口开始监听的时间,稳定 5 秒后连续采样内存占用读中位数。

内核(实测版本)二进制体积启动到监听空载内存线程数
mihomo v1.19.3259.1 MiB26.5 ms39.2 MB11~12
sing-box v1.14.277.5 MiB45.7 ms46.8~54.1 MB13
Xray-core v26.3.2734.9 MiB13.6 ms29.2 MB10~11

台架上有个自检环节必须交代,否则这组数字不可信:三次运行里,每个内核都要能在本地完成一次 SOCKS5 握手。三个内核、共 9 次全部成功——说明测到的是真的在提供服务的进程,而不是一个启动就崩掉的空壳。如果连本地握手都失败,读出来的「内存占用」是崩溃进程的残留值,没有任何比较意义。

这组数字怎么读:

启动时间差三倍(13.6 ms vs 45.7 ms),对普通用户基本无感。但你把它放到路由器或容器里就会被放大——开机自启的代理内核如果在低性能 CPU 上慢一个数量级,第一次联网的等待是能感觉到的。

空载内存差 25 MB 左右,对小内存设备有意义。128 MB 内存的老路由器、或者还要同时跑广告过滤插件的软路由,30 MB 和 55 MB 的差别就是「够用」和「一开就吃紧」。在电脑和手机上,这点差距基本可以忽略。

二进制体积差 2.2 倍,影响的是存储与更新成本。路由器闪存小的,装 77.5 MiB 的内核要额外想办法;体积差异也间接说明各个内核内置的能力范围不同(比如内嵌的协议栈、规则集解析、图形栈)。

而这三行数字里没有任何一项能解释「谁更快」。结论就是本文最想让你记住的一句:内核差异的作用域是「兼容性」和「资源占用」,不是「速度」。速度的账在节点、线路和本地网络上。

五、连接层与 DNS:差异真正咬人的地方

如果说协议矩阵决定「节点在不在」,那连接层和 DNS 决定「在的节点用起来顺不顺」。这几处是换客户端后最容易出现「表面正常、实际不舒服」的地方。

TUN 栈。TUN 模式要把系统流量整体接管,内核得自己实现一个网络栈。用户态栈(gVisor 那一类)实现简单、隔离性好,但每个包都要在世界内核与用户态之间来回一次;系统栈性能更接近原生,但对平台和权限的要求更苛刻。这条差异在游戏、语音、UDP 密集场景里才会暴露。注意闭源客户端会自行调整路线——Stash 较新的版本说明里就提到移除了 gVisor 隧道栈,所以不要拿一年前的评测结论套今天的版本。

UDP 能不能被代理。很多人抱怨「某些 App 明明显示连着代理却打不开」,根因是那些应用走 UDP/QUIC,而当前配置只代理了 TCP。判断路径很简单:看内核是否在转发 UDP、以及客户端是否开了 TUN——系统代理模式下,很多非代理感知的应用根本不会去连那个端口。做跨境多账号、海外社媒运营这类对出口 IP 纯净度敏感的场景,节点类型比客户端更要紧,仙路湾这类住宅 IP / 原生 IP 机场解决的就是「出口像不像真人」这一层,而任何客户端都不会帮你把机房 IP 变成住宅 IP。

多路复用(mux)。开着它能减少重复握手,看着「连接数变少、更快」,但代价是丢包时队头阻塞被放大。典型症状是「网页秒开、下载和看视频频繁卡住」,很多人误判成机场限速。排查方法是先关掉 mux 再复现一次,如果症状消失,问题就在这一层。

DNS 配置格式。这块的可移植性比节点订阅差得多。实测 sing-box v1.14.2 会直接拒绝旧版 DNS 写法,报错原文是「legacy DNS server formats are deprecated in sing-box 1.12.0 and removed in sing-box 1.14.0」;改用新版 dns.servers 的 type / server 结构后校验通过。也就是说,换内核时节点订阅可以靠转换器搬过去,DNS 那一堆选项基本要按新内核的文档重写。

规则引擎。两套内核的写法完全不同但都可用:mihomo 用 rule-providers 声明规则源,再在规则里用 RULE-SET,name,POLICY 引用(实测校验通过);sing-box 用 route.rule_set 声明远程规则集,再在 route.rules 里用 action 指定动作(实测校验通过)。规则文件本身不通用,只有节点这部分能用转换器搬运。所以「换客户端」的成本,通常落在规则与 DNS 的重写上,而不是节点的重新导入。

六、五步一致性排查:确认「换了客户端,东西没变」

怀疑换客户端后出问题时,按顺序做这五步,每一步都有明确判据,别凭感觉。

第一步:数节点数。把订阅原文解出来数一遍,再数客户端里的节点总数。数字一致,说明格式与协议映射没问题,可以直接跳到第四步;数字不一致,差异就是丢节点的实锤,去做第二步。

第二步:对名字。导出两边的节点名列表做差集,看丢的是哪几个。如果丢掉的集中在某一种协议上,问题在协议支持(对照第三节的矩阵);如果乱七八糟地丢,问题更可能在转换器,换一个转换入口(比如直接用面板提供的另一种订阅格式)再试。

第三步:单节点验证。挑一个节点,在两个客户端里各连一次,时间窗尽量靠近(比如都放在晚高峰同一小时内)。如果同一个节点在 A 里能用、在 B 里超时,才是真正的客户端差异;两个都不能用,去查节点侧。

第四步:看 UDP 与 QUIC。在客户端的连接列表里找一个明显走 UDP 的应用(游戏、语音通话、视频会议),看它的连接有没有出现在代理列表里。没出现,就是没被接管,和节点质量无关。

第五步:看规则命中。打开连接日志,找一个你确定应该走代理的域名,确认它命中的策略组是不是你以为的那个。很多「换了客户端后打不开某网站」其实是规则顺序或规则集没加载,而不是节点问题。分层的排查思路在这篇客户端故障排查指南里按层拆过,可以对着走。

七、决策框架:什么时候该换客户端,什么时候换了也没用

你观察到的现象归因该做什么
节点数量比订阅里少格式或协议映射换订阅入口或转换器,不用换客户端
某个节点在 A 能用、B 不能用平级兼容差异换客户端有意义
所有客户端里同一个节点晚高峰都慢节点 / 线路 / 出口换客户端没用,换线路或换机场
网页正常但视频频繁卡顿多路复用或 UDP 未接管先关 mux、开 TUN,再判断
某网站打不开但其他网站正常规则命中或 DNS 解析查规则与 DNS,和节点无关
路由器/容器上启动慢、内存吃紧内核资源占用按第四节选占用低的内核

把这张表倒过来看,就是一个选择逻辑:先定位问题在哪一层,再决定换什么。凡是「所有客户端都一样」的现象,换客户端永远解决不了;凡是「节点数量不对」「某个协议不认」的现象,换内核才有效,而这时候你要换的其实是内核,不是界面。

举个完整的例子走一遍。某人从 Clash 系换到 v2rayN 之后,节点数从 42 掉到 33,第一反应是「v2rayN 不行」,准备再换回去。按上面的表走:节点数量不对 → 归因格式或协议映射 → 先数节点对名字,发现丢掉的 9 个全部是 TUIC 与 AnyTLS → 对照第三节的矩阵,这两个 id 在 Xray-core 上不存在 → 结论是「不是 v2rayN 不行,是这 9 个节点头脑上就不属于 Xray 系」,要么继续用 Clash 系内核对这两个协议的支持,要么接受丢节点,两条路都不需要折腾 GUI。同一张表也可以反向用:如果他丢节点的原因是「所有客户端里都少了同样的 6 个节点」,那问题在订阅侧的转换,换任何客户端都是白换。

还有一类判断经常被忽略:「换了之后感觉变好」这件事本身可信度有多高。如果两次测试不在同一时间窗、不走同一节点、不排除本地网络波动,那结论就是噪声。想认真比一次,最简单的做法是:固定节点、固定时间窗(都放在晚高峰同一小时内)、固定测试方式(同一个测速脚本或同一段下载)、各跑三次看离散程度。三次里差异不稳定,就说明这次比较没有结论,别急着换。

八、常见问题

Q:手机快、电脑慢,是客户端的问题吗?基本不是。同一个节点在不同设备上速度不同,先看两边的网络路径(一个走 5G 一个走宽带,出口完全不同)、再看 UDP 是否接管、最后才看客户端。真要做对比,必须同一节点、同一时间窗、同一类网络。

Q:为什么 Clash 系客户端里的节点比 v2rayN 里多?先确认两边用的是不是同一个订阅入口。如果确认是同一份节点数据,那就是协议支持的差别——按第三节的矩阵,TUIC、AnyTLS、SSH 这类节点在 Xray 系里不存在,转换时会被丢掉或跳过。

Q:换客户端要重新买订阅吗?不用。只要客户端认你的订阅格式,导进去就行。真正需要重写的是规则和 DNS 部分,节点部分可以一直用。

Q:内核要不要追新版本?要,但要接受配置可能失效。sing-box 从 1.13.0 起移除 WireGuard 出站、从 1.14.0 起移除旧 DNS 格式,都是会直接让旧配置启动失败的变更。升级前先看该版本的迁移说明,比升级后翻日志快得多。

Q:多路复用到底开不开?看症状。网络稳定、丢包率低的线路,开着能省握手;线路一到晚高峰就抖的,关掉更稳。它不是「性能开关」,是取舍。

Q:为什么同一个内核,两个 GUI 用起来感觉不一样?GUI 差异通常体现在默认配置上——默认开不开 TUN、默认 DNS 怎么配、默认规则集从哪加载。内核相同但默认值不同,表现就会不同。所以比较时要把两边的默认配置摊开看,而不是比较界面。

Q:同一个机场,为什么有人推荐 Clash 系、有人推荐 sing-box?看两件事:你的节点协议构成,以及你对规则维护的要求。节点里混了 TUIC、AnyTLS 这类较新协议的,Clash 系(mihomo 内核)覆盖面更宽;需要精细的出站策略、把远程规则集当订阅一样增量更新、或者要和 TUN 配合做分流的,sing-box 的 route 模型更顺手。两边都能跑主流协议,所以「哪个更好」这种问法本身就问错了——该问的是「我的节点和规则在哪个内核上不折腾」。

推荐阅读