双 mihomo 内核切节点不生效 (Dual Mihomo Cores Silent No-Op)
触发条件
- Windows 上 Vortex 类客户端同时存在服务内核(Windows service 常驻,开机自启)和 GUI 内核(跟界面走)。
- 两者是同一个程序的两份进程,各自维护独立的节点状态、独立想绑同一批端口。
典型布局(本机实测):
- 服务内核(PID 8656,
com.vortex.helper.exe服务态):占0.0.0.0:7897(混合端口)、:1053(DNS)、:39798(API) - GUI 内核(PID 46256, 同 exe 控制台态):只占到
127.0.0.1:39797(API),7897 绑定失败
- 服务内核(PID 8656,
症状
- 界面里切节点显示成功,但流量出口纹丝不动(cloudflare trace 的
ip=/loc=不变)。 - 用户反复切节点、换地区,全部"无效",且界面无任何报错。
- 内核日志反复出现:
Start Mixed(http+socks) server error: listen tcp :7897: bind: Only one usage of each socket address ...
排查步骤
- 先搞清谁扛着端口:
netstat -ano | grep ":7897" | grep LISTEN拿 PID →tasklist //FI "PID eq <pid>"看进程名。 - 发现两个同名进程 → 各自找 API 端口:
wmic process where "ProcessId=<pid>" get CommandLine,GUI 内核命令行带-ext-ctl 127.0.0.1:39797,服务内核占另一个(如 39798)。 - 对比两边的节点状态(mihomo RESTful API):
curl http://127.0.0.1:<api-port>/proxies/SELECT→now字段。
本例:GUI 停在"日本 4 Home",服务内核停在"香港 2"——界面切的是 GUI,流量走的是服务内核。 - 确认规则走向:
GET /connections看活跃连接的chains字段,直接显示实际用的节点链。
根因
- 服务内核先启动抢占了 7897;GUI 内核每次启动绑端口失败但界面照常工作(它有自己的 API 和显示逻辑),切换操作只改 GUI 内核的状态。
- 结果:GUI 是个"遥控器",但遥控的是一台没插电的电视。
解决
临时(不重启服务,直接改服务内核状态)
用 mihomo API 直接给扛端口那个内核切组:
# 注意:节点名是中文+空格,curl 的 -d 传中文 JSON 会因编码问题失败,
# 必须用 python urllib 发 UTF-8 body:
python -X utf8 -c "
import json, urllib.request
body = json.dumps({'name': 'app anytls 新加坡 1'}).encode('utf-8')
req = urllib.request.Request('http://127.0.0.1:39798/proxies/SELECT', data=body, method='PUT', headers={'Content-Type': 'application/json'})
print(urllib.request.urlopen(req, timeout=5).status) # 204 = 成功
"- 用
curl -X PUT -d '{"name":"app anytls 美国 1"}'会被 GBK 编码坑:返回 400proxy not exist(字节被转码,名字对不上)。 - 同理
curl -X PATCH在 mihomo 1.10.0 上对 proxies 端点是 405,要用 PUT。
根治
- 二选一:关掉 Windows service 版 Vortex(只留 GUI),或关 GUI 只用服务内核,保证只有一个内核抢端口。
- 判断依据:
sc query/ 服务列表里找 Vortex 服务项;GUI 内核日志的 bind 报错消失 = 只剩一个内核。
验证方法
切完立刻三连:
curl -x http://127.0.0.1:7897 https://www.cloudflare.com/cdn-cgi/trace看ip=/loc=变没变;GET /connections看chains是否已指向新节点;- 跑真实业务命令(如
agy --print)确认端到端可用。
附:此机场 (moeshark) 的 app anytls vs anytls 之谜
GUI 面板里才有 app anytls 前缀节点,普通 clash UA 拉订阅拿不到——门道在订阅 URL 的 nodeua=-win 参数,不在 User-Agent(实测:任意 UA + nodeua=-win 都返回 app 节点;去掉该参数无论 UA 都只有普通节点)。
app anytls X | anytls X | |
|---|---|---|
| 入口域名 | h2.moeshark.app | h1.moeshark.app |
| 入口 IP | 120.233.118.22(广州移动,国内中转入口) | 18.139.219.235(AWS 新加坡,直连) |
| 端口段 | 400xx(4 位) | 50xx(4 位) |
| 其余参数 | 密码/sni/alpn 完全相同 | 同左 |
即:app anytls = 国内中转线路(广州移动入口 → 隧道到落地),anytls = 直连线路。同一地区两条线路的落地出口 IP 相同(实测 SG:都是 188.253.5.73)。区别只是从本地到落地的路径:中转线路国内连通性更稳,直连线路依赖国际链路质量。对 Gemini 地区封锁判定无差别(按落地 IP 算)。
下次如何识别
- 任何"切了节点但没效果"的问题,第一反应查谁在真正监听代理端口,而不是反复换节点。
- 同名进程出现两份 → 怀疑状态分裂。
- GUI 显示 ≠ 数据面状态,以
netstat+ API/connections为准。
相关概念
- Antigravity agy 地区封锁排查 (Antigravity agy Geo-Block Diagnosis) —— 本坑的上层症状:切到美国无效,误以为全是地区封锁
- mihomo 节点拨不通排查 (Mihomo Node Connection Failure Diagnosis) —— 同生态另一类故障(节点层)
- Command Alias 命令行别名.md —— agyy 别名体系(代理变量围绕 7897)
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Network