JSON 结构与配置边界
先确认正在编辑哪一层
V2Ray 生态中的“配置文件”并非只指一个文件。v2rayN 保存服务器资料、订阅分组、路由规则与参数设置,再按选中的内核生成运行配置。v2rayNG 和 v2flyNG 也有应用自身的数据与内核运行配置两层。界面里改了端口,不代表订阅原文随之变化;编辑临时生成的 JSON,也不代表下次启动会保留。查阅字段前,应确认文件来自手动管理、客户端导出,还是一次启动的临时目录,并记录生成它的客户端和内核。
本页示例以 V2Ray 风格 JSON 和 Xray 常见字段为主。V2Fly 与 Xray 有共同的配置基础,但协议支持、传输名称和扩展选项会分化。sing-box 使用另一套配置结构,不能因为 v2rayN 支持切换内核,就把这里的 JSON 原样交给它。遇到“未知字段”时,先查实际启动的内核,再查该内核接受的字段;不要只根据客户端名称推断。获取客户端时可从平台下载页选择对应入口。
对象、数组与引用关系
JSON 的最外层是对象,字段名与字符串都使用英文双引号。数组用方括号,适合保存多个入站、出站或规则;对象用花括号,适合保存一组参数。数字端口通常写成数字,布尔值写成小写的 true 或 false。标准 JSON 不接受注释、末尾多余逗号和单引号。即使某个工具允许带注释的扩展语法,也应在分享或迁移前导出标准 JSON,避免另一个解析器拒绝读取。
下面是一份可独立启动的本地直连基线,用于检查 JSON 解析、本地监听和日志输出,不包含代理服务器。它只监听回环地址,不设置系统代理,也不会创建桌面菜单。配置加载成功后,本地 SOCKS 入口把请求交给 direct 出站。此时能访问某个地址,只能说明这条直连路径可用,不能证明订阅中的代理服务器可用。将配置交给客户端前,还要确认客户端是否支持自定义配置入口,以及是否会重写本地端口。
{
"log": {
"loglevel": "warning"
},
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
}
],
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
}
]
}
从结构正确到语义正确
解析通过只解决了语法问题。若 routing 中写了不存在的 outboundTag,或者规则引用的入站标签拼错,配置仍可能报错或无法按预期分流。标签是同一份运行配置内的引用名,区分大小写;它不是界面显示的备注,也不是服务器域名。建议先列出入站和出站的 tag,再检查规则引用。数组顺序也有含义:普通路由规则按顺序尝试匹配,首个出站通常承担未匹配请求的默认出口,不能随意按字母排序。
| 字段 | 负责内容 | 常见误区 |
|---|---|---|
inbounds | 本地监听与接收协议 | 把服务器地址填进 listen |
outbounds | 连接目标或代理服务器 | 忽略默认出口顺序 |
routing | 匹配请求并选择出口 | 引用不存在的 tag |
dns | 内置解析器设置 | 误认为自动接管系统 DNS |
policy | 用户级连接策略与统计开关 | 把时间参数当成带宽限制 |
阅读后续局部示例时,应把字段合并到对应的顶层位置,而不是把多个完整对象依次粘进同一文件。一个顶层对象中不要重复定义 routing 或 dns,重复键的处理会依赖解析实现,容易出现界面与实际运行不一致。每次合并只改一个功能,保留修改前副本,并在启动日志里确认加载结果。若只需要订阅导入与日常连接,优先让客户端生成配置,只有界面无法表达的需求才进入手动 JSON 管理。
inbounds 入站与本地监听
listen、port 与 protocol 的分工
入站是应用流量进入内核的入口。listen 决定监听本机哪个地址,port 决定端口,protocol 决定接收什么协议。桌面本地代理通常监听 127.0.0.1,只有本机进程可连接;写成 0.0.0.0 则通常会监听所有 IPv4 接口,可能把入口暴露给局域网。它并不表示“使用任意服务器”,也不代表外部一定可以访问,最终还受防火墙和网络环境影响。没有明确的共享需求时,不应扩大监听范围。
SOCKS 与 HTTP 是不同的本地代理协议,应用设置必须与入口对应。浏览器填写 HTTP 代理地址时,不能随意指向一个只接收 SOCKS 的端口;命令行工具使用 SOCKS 时,也要确认它是否支持代理端解析域名。v2rayN 界面可能提供本地混合端口,由客户端和所选内核负责实现。不要据此在任意 V2Ray 风格配置里填写一个名为 mixed 的协议,是否可用必须以当前内核的实际配置定义为准。
并列定义 SOCKS 与 HTTP
下面是两个入站对象组成的局部片段。它们应替换或合并到顶层 inbounds 数组,不能与已占用相同端口的入站并存。两个入口都绑定回环地址,SOCKS 开启 UDP 接收,HTTP 入口供支持 HTTP 代理的程序使用。开启 udp 只代表该入站接受相关请求,不保证后续出站、服务器与网络路径都能转发 UDP。应用没有发出代理请求时,修改内核路由也不会让它自动进入这些端口。
{
"inbounds": [
{
"tag": "local-socks",
"listen": "127.0.0.1",
"port": 10808,
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true
}
},
{
"tag": "local-http",
"listen": "127.0.0.1",
"port": 10809,
"protocol": "http",
"settings": {}
}
]
}
本地端口不是服务器远端端口。前者供本机应用连接,后者位于 outbounds 的服务器设置中,两者通常没有必要相同。遇到端口占用时,先退出重复启动的客户端,确认后台是否还有内核进程,再换用空闲端口。改完入站端口后,还必须同步应用代理设置和客户端的系统代理配置。只改 JSON 不改系统代理,会造成内核正常启动、浏览器却继续连接旧端口的现象。
sniffing 的用途与边界
嗅探可从受支持的流量特征中尝试提取域名,为域名路由提供依据。它不是解密工具,也不保证每条连接都有可识别的域名。以 Xray 为例,下面的对象可放进某个入站对象内部,routeOnly 表示嗅探结果仅用于路由判断。是否支持该字段、能识别哪些协议,应以所用内核为准。如果应用本来就向 SOCKS 入口提交域名,路由已有可用的域名信息,通常不需要为了“完整”而额外开启所有嗅探选项。
{
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"],
"routeOnly": true
}
}
Android 的 VPN 模式通过系统提供的虚拟网络接口接收流量,用户通常不需要逐个给应用填写 SOCKS 端口。v2rayNG 的“分应用代理”又决定哪些应用进入或绕过这条路径,它与入站 JSON 的监听地址不是同一层设置。桌面端启用其他接管方式时也要区分系统层与内核层:先确认流量是否到达内核,再分析后续规则,不能看到“VPN 已连接”就直接断定每个应用都使用同一入口。
允许局域网设备访问时,还要考虑认证、访问来源和防火墙范围。无认证的 HTTP 或 SOCKS 入口不适合直接面向不受信任网络。接入设备应明确知道代理地址,主机也应限制可访问的网段;仅修改 listen 而忽略网络边界,会产生超出预期的访问面。排错时可先在本机完成回环测试,再增加局域网访问,最后检查防火墙。逐层放开比同时修改多个地址与规则更容易确定问题来源。
outbounds 出站与协议参数
默认出口与显式标签
出站决定内核如何继续处理请求。freedom 通常用于直连,blackhole 用于阻断,VMess 等协议则通过相应服务器转发。tag 是路由选择出口时使用的标识,不会自动变成一个可用服务器。一个叫 proxy 的标签可以指向任何协议,因此判断出口性质必须同时看 protocol 与 settings。没有命中路由规则的请求通常交给 outbounds 中的首个出站;把 direct 放在第一项,就是在默认路径上选择直连。
下方片段定义直连和阻断两个出口,适合用来练习路由引用,但不包含远端代理能力。blackhole 的空设置会按协议默认方式处理被阻断请求。若需要返回特定响应,应查当前内核对应的协议设置,不要把任意 HTTP 文本当作通用回应。配置多个出站时应使用清晰且唯一的标签,例如 direct、block 与 proxy,避免只用一串序号;路由排查时能直接看懂出口含义,比缩短几个字符更重要。
{
"outbounds": [
{
"tag": "direct",
"protocol": "freedom",
"settings": {}
},
{
"tag": "block",
"protocol": "blackhole",
"settings": {}
}
]
}
以 VMess 理解服务器字段
VMess 出站将服务器地址、远端端口和用户参数放在 settings 的 vnext 数组中。address 可以是服务器域名或地址,port 是服务器实际监听的端口,users 描述认证用户。下面展示字段形状,example.net 是文档用途域名,全零 UUID 也是教学值,不能用于连接真实服务。实际使用必须从已有服务器配置或有效订阅取得匹配参数;这里没有可用节点,也不应通过随机生成 UUID 来猜测服务器凭据。
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "example.net",
"port": 443,
"users": [
{
"id": "00000000-0000-0000-0000-000000000000",
"alterId": 0,
"security": "auto",
"level": 0
}
]
}
]
}
}
这段对象本身不是完整连接方案,还缺少与服务端对应的传输和安全层设置。端口使用 443 不等于自动启用 TLS,users 中的 security 也不等于 streamSettings 中的 security;它们处于不同层级。现代 VMess 配置通常使用 alterId 为零,但迁移旧资料时仍应以服务器端配置为准。时间明显不准确可能影响认证过程,遇到握手错误时应先确认系统时间与时区设置,再逐项核对用户参数。
不要跨协议搬运字段
VMess、VLESS 与其他协议的用户结构并不完全相同。把某个协议的 users 对象直接粘到另一个协议下面,可能在解析阶段失败,也可能形成没有实际意义的参数组合。同样,连接地址、传输 Host 与 TLS serverName 可以是不同字段,它们分别服务于网络连接、应用层请求与证书验证。只有服务端明确要求时才填写相应值,不要为了让三个名称看起来一致而覆盖订阅给出的设置。
| 字段 | 常见位置 | 检查重点 |
|---|---|---|
tag | 出站对象 | 与 outboundTag 完全对应 |
address / port | 协议服务器设置 | 实际服务地址与监听端口 |
id | 支持 UUID 的协议用户项 | 使用有效的服务器资料 |
streamSettings | 出站对象 | 与服务端传输、安全层一致 |
订阅更新与手动编辑之间还存在覆盖关系。客户端一般以订阅中的服务器记录重新生成出站,直接改临时 JSON 不会反向更新订阅,也可能在下次切换服务器时丢失。长期需要自定义时,应使用客户端提供的自定义配置或模板机制,并保留服务器资料来源。只想修改路由时,不应同时改动认证字段;只想调整本地端口时,也不需要重写整个出站。缩小修改面能减少把正常连接参数改坏的风险。
“连通性测试通过”和“实际传输正常”也不是同一个结论。测试可能只验证连接建立、特定网址或特定请求,而实际应用还会使用长连接、不同域名与 UDP。应先确认出站能建立协议连接,再结合访问日志核实应用请求确实走到这个标签,最后测试实际业务。有关单条分享链接与订阅地址的差异,可继续阅读分享链接与订阅导入说明,避免在错误的数据层修改参数。
streamSettings 传输与安全层
把协议、传输和 TLS 分开看
出站协议负责代理请求的组织与认证,传输负责如何在两端之间承载数据,TLS 等安全层负责相应连接的保护与身份验证。这三个维度有关联,但不能互相替代。同一个 VMess 协议可以搭配不同传输,服务器端却未必同时开放这些组合。客户端能显示某个选项,不代表当前服务器支持它。排查时应按“协议一致、传输一致、安全层一致”的顺序逐层核对,而不是反复尝试下拉框中的所有组合。
streamSettings 位于对应的入站或出站对象内,不是任意顶层字段。这里关注客户端出站,示例以 WebSocket 搭配 TLS 说明结构。network 为 ws 时,对应的参数放在 wsSettings;security 为 tls 时,对应的参数放在 tlsSettings。不同内核及其实现对传输名称、可用扩展有差异。遇到新名称或废弃提示,应查当前内核支持范围,而不是仅把字段名替换成看似相近的拼写。
{
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"serverName": "example.net"
},
"wsSettings": {
"path": "/proxy",
"headers": {
"Host": "example.net"
}
}
}
}
地址、serverName 与 Host
示例中的 example.net 与路径仅用于解释字段,实际连接必须使用服务端给出的值。出站 address 决定先向哪里建立连接,tlsSettings.serverName 用于 TLS 服务名称及证书校验,WebSocket 的 Host 用于 HTTP 请求中的主机标识。反向代理场景可能要求这些值不同。手动编辑时应逐项记录,而不是用服务器备注覆盖全部字段。域名看起来相同只是某些部署的结果,不是配置格式的普遍规则。
path 也不是随意填写的说明文字。反向代理常按路径把 WebSocket 请求转交给后端,路径不匹配可能返回普通网页、重定向或错误状态。路径的大小写、前导斜杠及额外查询内容都可能影响服务端行为。发现连接建立后立即关闭时,先核对服务端要求的路径与 Host,再检查中间代理是否支持升级连接。不要通过修改本地入站端口来解决远端 WebSocket 路径错误,两者处在完全不同的位置。
按连接阶段定位错误
连接超时首先说明在给定时间内未完成某个阶段,不能直接推断认证密码错误。若服务器地址无法解析,应先看域名解析;若地址能解析但无法建立连接,应检查远端监听、防火墙与网络路径;若已经进入 TLS 阶段,日志通常会提供证书或握手相关线索;只有进入代理协议认证后,用户参数才是主要检查对象。这个顺序能减少把路由规则、DNS 和认证字段同时改乱的情况。
传输层还有许多高级选项,例如套接字行为、连接复用和特定传输扩展。它们通常不属于第一次配置的必填项。将多个来源的“优化参数”合并,可能改变连接生命周期、增加不兼容组合,或者让服务端无法识别请求。应先建立一个与服务端明确对应的最小配置,再按单个需求验证新增选项。对没有明确证据的问题,不应通过堆叠参数期待速度自然变快。
REALITY 等扩展也不能被理解为 tlsSettings 的随意替代值,它们有特定内核要求和独立参数约束。v2rayNG 使用 Xray 内核,v2flyNG 使用 V2Fly 内核,两者可接受的协议与扩展并不保证一致。迁移前应核对每个服务器所需功能,再决定客户端与内核,而不是先导入再逐个删除报错字段。桌面使用 v2rayN 时,也要确认该服务器实际选择了哪个内核运行。
需要比较修改结果时,保留同一个服务器、同一条网络和同一个测试目标,只调整一个参数,并记录日志中的阶段变化。若一次测试把传输、服务器地址和路由模式全换了,即使恢复连接,也无法知道哪个改动起作用。反复出现握手失败可参照运行日志报错定位继续排查;速度问题则应在连接正确后另行分析,不能把所有慢连接都归因于 TLS。
routing 路由与规则顺序
先理解规则何时生效
路由处理已经进入内核的请求,再按条件选择出站。它不会替应用打开系统代理,也不会自动接收未进入客户端的连接。普通 field 规则按数组顺序匹配,首先满足条件的规则决定出口。规则中的多个不同条件通常需要同时满足,同一个 domain 或 ip 数组内的多个条目则用于表达候选匹配。设计规则时先明确流量来源、目标与出口,再选择字段,不要先堆满列表后再猜它们的优先级。
下面给出一段局部路由配置:私有地址与 geosite:cn 域名交给 direct。本例要求 outbounds 中已存在 direct 标签;geoip 和 geosite 引用还要求当前运行环境提供对应且兼容的规则数据。没有命中任何规则时,普通配置仍回到首个出站,而不是自动选择一个叫 proxy 的标签。想实现“其余请求走代理”,应在确认有效代理出站后安排默认出口,不要只凭规则名称判断完整行为。
{
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": ["geoip:private"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
}
]
}
}
domainStrategy 与匹配形式
routing.domainStrategy 控制路由匹配过程中如何处理域名与地址。AsIs 通常只按请求现有的信息匹配;IPIfNonMatch 在域名规则没有匹配时尝试解析,以便继续进行地址规则判断;IPOnDemand 则在匹配需要地址信息时触发解析。它不是 DNS 服务器地址,也不是强制所有出站优先使用某种地址族。选择策略时要考虑是否有地址规则、域名是否可正确解析,以及额外解析对排错和请求路径的影响。
域名规则可表达完整域名、域名及其子域、关键字或正则等不同匹配范围。常见的 full:example.net 只针对指定名称,domain:example.net 包括相应子域,regexp: 则需要理解正则表达式与 JSON 字符串转义。仅想匹配一个站点时优先选范围清晰的形式。宽泛关键字可能误中不相关域名,复杂正则也会增加维护负担。修改后应同时测试预期命中和预期不命中的目标。
{
"type": "field",
"domain": [
"full:example.net",
"domain:example.org"
],
"network": "tcp",
"outboundTag": "direct"
}
这一条示例要求目标域名符合其中一项,并且网络类型为 TCP。若请求仅携带地址,域名规则可能没有可用依据;若嗅探得到域名,还要看嗅探和路由的具体设置。不要把“网站使用某个域名”与“内核收到了这个域名”混为一谈。应用自行解析、使用加密解析或直接连接地址时,内核可见信息会变化。检查访问日志中的目标形式,通常比继续增加域名条目更有效。
从例外规则排到默认路径
需要优先处理的窄规则应放在更宽规则前面,例如先处理明确的内部服务,再放较大范围的地址或域名集合。若前面已有覆盖所有 TCP 的规则,后面再写单个网站的 TCP 例外往往不会生效。维护时给规则保留用途说明,但说明应写在文档或客户端支持的备注处,不能直接把中文注释塞进标准 JSON。清理失效条目时也要保留可回退副本,避免一次删掉依赖关系。
“绕过大陆”是客户端预定义规则集的常见名称,不是 JSON 中一个自动完成全部分流的布尔开关。它的实际效果取决于规则数据、规则顺序、默认出口与 DNS 行为。不同客户端、内核和规则数据更新后,边界目标可能有不同结果。需要精确分流时,应检查运行时 routing,而不是只看菜单名称。系统代理与路由模式的关系,可参照系统代理与绕过大陆模式详解。
排查单个目标时,先确认请求是否进入内核,再看命中了哪个出口,最后检查该出口能否连接。临时添加一条完整域名规则进行对照,若仍不命中,就检查请求是否带域名、配置是否重新加载,以及上方是否已有更宽的匹配。局域网地址访问异常还应看系统代理绕过列表,因为请求可能根本没进内核。桌面进程规则依赖平台和接管能力,不能把 Android 的分应用代理理解为通用 routing 字段。
dns 解析与路由协作
区分系统解析与内置解析
DNS 负责把域名转换为地址,但一次访问中可能存在多处解析。应用可以调用系统解析器,也可能使用自身的解析机制;内核在路由判断或建立出站连接时,也可能调用内置 DNS。顶层 dns 主要配置内核的解析能力,不会仅凭存在这个对象就接管整台设备的 DNS 请求。看到系统仍使用原有解析器,不代表内核的 dns 没有加载,必须先确定所观察的查询来自哪一个进程、哪一个处理阶段。
请求携带域名进入 SOCKS 时,后续可能由内核或远端服务器处理域名;应用先解析并提交地址时,内核收到的则可能只有地址。两种模式会改变域名路由的可见信息,也会影响错误出现的位置。排查“域名打不开但地址可连”时,要先找出解析发生在哪一侧,再检查返回结果。直接把所有解析服务器换一遍,可能掩盖原来的问题,却不能解释为何某个应用与浏览器表现不同。
一个用于理解字段的解析片段
下面的片段使用本机解析器,保留系统当前的解析路径,并指定内置查询优先取得 IPv4 结果。hosts 中的 example.test 指向文档示例地址,仅用于说明静态映射,不提供实际网站服务。把这段合并到顶层 dns 后,仍需由具体功能调用内置解析器才会使用它。不同内核对查询策略与服务器选项支持有差异;若启动时报字段错误,应回到当前内核的配置定义核对。
{
"dns": {
"hosts": {
"example.test": "192.0.2.10"
},
"servers": [
"localhost"
],
"queryStrategy": "UseIPv4"
}
}
hosts 适合少量明确、稳定的本地映射,不适合长期代替动态站点的解析。很多服务依赖多个地址、区域调度与故障切换,固定一个过期地址可能造成间歇性失败。使用静态映射时还要注意 TLS 证书仍按域名验证,改变目标地址并不能让任意服务器获得对应身份。删除测试映射后,应考虑应用和系统缓存,否则下一次访问仍可能使用旧结果,从而误以为配置没有生效。
解析策略不等于出站策略
dns.queryStrategy 与 routing.domainStrategy 名称相近,但作用不同。前者主要约束内置 DNS 查询的地址族,后者控制路由匹配是否需要把域名解析为地址。某些出站或套接字设置还有自己的域名处理选项,它们也不能混为一谈。只改内置 DNS 查询为 IPv4,不代表所有应用、系统解析以及远端代理都只使用 IPv4。想定位地址族问题,应分别观察本地解析、实际连接目标和最终出口。
| 设置位置 | 主要作用 | 不能据此推断 |
|---|---|---|
dns.servers | 内置解析服务器选择 | 所有应用均使用这些服务器 |
dns.queryStrategy | 内置查询地址族策略 | 整台设备停用另一地址族 |
routing.domainStrategy | 路由是否解析域名以匹配地址 | 指定了解析服务器 |
dns.hosts | 内置解析静态映射 | 改写了操作系统 hosts 文件 |
指定加密解析服务时,还要解决解析服务自身的可达性。若查询服务使用域名,而连接这个服务又依赖同一个尚未工作的解析链,就可能形成循环依赖。若代理服务器的域名也依赖一条必须先经过代理才能使用的解析路径,启动阶段同样可能卡住。应明确服务器域名如何得到初始地址、查询连接如何出站,以及失败时是否有可理解的备用路径。复杂设置并不天然比简单设置可靠。
排错可以分成三步:先确认域名能否得到结果,再确认结果是否属于可用地址,最后检查连接是否走到预期出口。解析成功而连接超时,应继续检查网络路径,不要把所有超时都称为 DNS 错误;解析失败也不应通过关闭证书验证处理。比较两个解析结果时,要记录时间和地址族,动态调度可能导致结果不同。只有变化与故障能重复对应时,才有依据决定保留哪项修改。
路由中的 geosite 数据描述域名集合,geoip 数据描述地址集合,它们不是 DNS 缓存,也不会自动把域名转换为正确地址。规则集合能否加载、域名能否解析和出口能否连接是三个独立检查点。透明接管、虚拟地址与 DNS 分流还会引入更多状态,建议先建立普通本地代理基线,再逐步增加这些能力。涉及路由器或旁路由,可阅读Xray 网关部署概览,不要直接套用桌面监听配置。
policy 策略、日志与统计
用户级策略怎样关联
policy 用于定义连接行为和统计相关策略,不是另一个路由表,也不是给某个应用自动分配带宽的限速器。levels 对象按用户级别组织参数,键名在 JSON 中是字符串,协议用户里的 level 则用于关联相应级别。级别只在协议和配置路径支持该机制时才有意义,不能把任意入站标签当作级别名称。若没有明确的需求,先使用内核默认策略,避免把不理解的参数当作通用优化项。
下面展示级别零的连接时间参数,数值以秒计,用于解释结构,而不是推荐所有网络都使用这一组值。handshake 限制相应连接握手阶段的时间,connIdle 处理连接空闲时间;uplinkOnly 与 downlinkOnly 影响连接进入单向状态后的等待行为。各参数具体作用于哪些协议和阶段,应以当前内核实现为准。它们不能替代服务器健康检查,也不能通过单纯增大数值恢复一个不可达的远端地址。
{
"policy": {
"levels": {
"0": {
"handshake": 4,
"connIdle": 300,
"uplinkOnly": 2,
"downlinkOnly": 5
}
}
}
}
时间参数的代价
空闲超时设得很短,可能让暂时没有数据的连接过早结束;设得很长,则可能让已失效连接更久地占用资源。长连接应用是否受影响,还取决于应用自身心跳、服务端超时和网络设备状态。排查中断时应记录从最后一次有效数据到断开的时间,确认是否反复出现相同间隔。只看到一次断线就把所有超时拉长,既不能定位问题,也可能拖慢真正失败连接的释放。
握手超时也需要结合阶段理解。网络拥塞、服务器响应缓慢和认证不一致,都可能表现为握手没有按时完成,但处理方法不同。提高握手等待时间只能扩大容忍窗口,不会修复错误用户参数或不匹配的传输。先用运行日志确认失败阶段,再决定是否做小幅度调整。若修改后只是从“快速失败”变成“等待更久后失败”,应恢复原值,继续检查地址、协议和安全层。
先用合适的日志级别
log 位于顶层,loglevel 可选择当前内核支持的级别。日常使用通常关注 warning 或 error;定位问题时可临时提高到 info,需要更细信息时再短时间使用 debug。级别更详细不等于连接速度更快,日志也可能包含访问目标、本地路径或用户标识。分享排错内容前应删去订阅地址、认证资料与可识别个人的信息。保留错误原文和发生顺序,比只截取最后一句“失败”更有帮助。
{
"log": {
"loglevel": "info"
}
}
若显式设置 access 与 error 文件路径,还要确认运行账户有写入权限,目录存在且磁盘空间足够。桌面客户端可能已经接管日志输出,手动设置路径不一定会显示在客户端的日志面板里。相对路径依赖进程工作目录,不应按编辑器所在目录推断。为避免日常产生过多记录,完成定位后应恢复较低日志级别,并按自己的保留周期清理包含访问记录的文件。
统计开关不等于监控面板
stats、policy 中的统计选项与 api 的统计查询能力相互配合,不能只启用一个开关就期待桌面自动出现图表。入站、出站与用户统计有不同作用域,用户统计还可能依赖协议中的用户标识字段。客户端如果已经提供流量统计,应先使用其界面能力,不要为显示数字额外暴露管理接口。统计反映的是特定计数位置,不一定等于运营商计费流量,也不等于应用实际文件大小。
评估“优化”时应采用相同应用、相同服务器与相同测试目标,先记录原配置下的现象,再只改变一个策略。吞吐量受节点负载、线路、协议、应用并发和设备能力共同影响,policy 中几个时间值并不能决定整条链路速度。若连接稳定但下载缓慢,应按速度慢的分层排查方法区分节点、线路与本地设置,而不是反复缩短超时或打开所有统计选项。
配置验证、迁移与回退
建立能复现的修改记录
修改配置前,先保存当前可用状态,并写清楚要解决的具体问题。例如“某个应用未进入代理”“一个域名命中错误出口”或“切换网络后解析失败”。这些问题分别对应入口、路由与解析,不应统一处理为重新导入全部订阅。记录客户端、实际内核、接管方式和修改字段即可,不需要抄写认证资料。保存副本时也要注意其中可能包含私密服务器信息,不宜上传到公开位置。
手动 JSON 的验证至少有三层:语法解析、内核接受、运行行为。语法层检查括号、引号、逗号与数据类型;内核层检查字段支持、标签引用和资源加载;行为层检查真实应用是否按预期进入入口并使用正确出口。前两层通过不等于第三层必然成功。反过来,某个网页偶然打开,也不能证明整个配置正确,它可能直接访问或使用了缓存,需要观察实际路径才能得出结论。
按固定顺序启动与测试
先关闭重复运行的客户端或测试进程,避免本地端口冲突。载入配置后先看启动日志,确认没有语法错误、未知字段、缺失规则数据或监听失败,再让应用发起一个明确请求。若启动失败,不要继续切换路由模式;若启动正常但没有访问记录,先检查应用入口;若有记录却走错标签,再检查路由顺序。这样的顺序能把“没有接收到请求”和“收到后处理错误”清楚分开。
- 保留原配置,在副本中只修改一个字段组,并记录预期变化。
- 加载副本,检查解析结果、标签引用、规则数据和端口监听。
- 使用固定目标发起请求,核对日志中的目标信息与出站标签。
- 测试一个不应受影响的目标,确认例外规则没有扩大作用范围。
- 恢复常用应用与原有日志级别,观察重启客户端后修改是否保留。
测试目标应覆盖实际需求,但不必一次测试所有网站。至少包含一个预期直连目标和一个预期通过远端出站的目标;涉及局域网时再加一个内部服务。不要使用页面能否打开作为唯一指标,浏览器缓存、已有连接和应用自带代理都可能干扰结果。修改路由或 DNS 后,可以关闭相关应用再重新打开,使新请求确实经过新配置;需要清理缓存时,也应记录清理范围,避免比较条件变化不明。
区分可恢复错误与兼容性问题
出现 unknown field 一类信息时,应先确认配置格式是否属于当前内核,再看字段拼写与层级。出现 address already in use 时,应检查重复进程和端口,而不是更换服务器。出现证书错误时,应检查时间、服务名称与证书链。出现规则数据读取失败时,应检查文件是否由客户端正确管理。错误文案会因内核而变化,但“先找失败阶段,再改对应字段”的方法保持不变。
| 现象 | 先检查 | 暂不优先修改 |
|---|---|---|
| 内核未启动 | JSON、字段兼容性、监听端口 | 网站域名规则 |
| 没有应用访问记录 | 系统代理、应用入口、接管范围 | 远端认证用户 |
| 出口与预期不符 | 规则顺序、目标形式、tag 引用 | TLS 证书验证 |
| 重启后修改消失 | 生成配置与持久设置的边界 | 网络线路 |
从 v2rayN 迁移到 v2rayNG 时,可以优先迁移受支持的服务器资料,再在移动端重新设置分应用代理和路由。桌面系统代理、文件路径与窗口偏好不属于可直接搬运的内核配置。迁移到 v2flyNG 还要核对 V2Fly 内核能否接受原服务器所需协议与传输。订阅能被读取,只能证明导入格式可识别,不能保证其中每个条目都能由目标内核运行。迁移完成后应按同一检查流程重新验证。
客户端支持导出分享链接、完整配置与备份资料时,应先确认导出内容的用途。分享链接通常围绕单个服务器,不会完整保留路由、DNS 和系统设置;备份可能包含更多应用数据,恢复后影响范围也更大。将导出文件提供给他人排查前,应去除服务器认证和订阅内容。仅需要说明规则问题时,可以单独提供 routing、相关标签定义与脱敏日志,避免整份备份在多个位置流转。
回退不只是把旧文本粘回来,还包括恢复系统代理、原来的内核选择、日志级别与应用入口。若新增过局域网监听或管理接口,也要一并撤回。回退后重新启动并验证原有目标,确认基线确实恢复,再考虑下一次尝试。日常操作仍可回到入门指南按主线检查;需要更换设备平台则使用客户端下载页。保留一条明确可用的基线,比积累大量来源不明的配置片段更便于长期维护。