mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-07 05:34:17 +00:00
docs: add missing task tracking records for multi-node and traffic fixes
Add task tracking records for commits that were missing documentation: - 2026-04-10: multi-node backend foundation (7 commits) - 2026-04-15: improve mariadb flow and traffic flush - 2026-04-23: install cron before acme.sh - 2026-04-24: resolve client traffic InboundId from DB - 2026-04-24: fix traffic flush blocked by stale inboundId=0 delta
This commit is contained in:
parent
51f17922fa
commit
eca9b219cf
9 changed files with 353 additions and 0 deletions
|
|
@ -0,0 +1,51 @@
|
|||
Task Record: Multi-node shared control — Go backend foundation
|
||||
|
||||
Date: 2026-04-10
|
||||
Related Module: config, database, web/service — multi-node architecture
|
||||
Change Type: Feature
|
||||
|
||||
Background
|
||||
|
||||
需要支持多个 3x-ui 面板实例共享同一个 MariaDB 数据库,由 master 节点管理配置,worker 节点同步配置并上报流量。为此引入节点角色配置、共享元数据模型、写入保护和版本同步机制。
|
||||
|
||||
Changes
|
||||
|
||||
- `config/config.go`: 新增 `NodeRole`、`NodeConfig` 结构体,`GetNodeConfigFromJSON()` 读取节点角色/ID/同步间隔/流量刷盘间隔,`ValidateNodeConfig()` 校验配置合法性
|
||||
- `database/model/node_state.go`: 新增 `NodeState` 模型,记录每个节点的心跳、同步状态、错误信息
|
||||
- `database/model/shared_state.go`: 新增 `SharedState` 模型,键值对 + 版本计数器,用于缓存失效检测
|
||||
- `database/shared_state.go`: `BumpSharedAccountsVersion()` 原子递增版本号,`GetSharedAccountsVersion()` 读取当前版本,`UpsertNodeState()` 更新节点状态
|
||||
- `database/db.go`: MariaDB 模式下自动迁移 `SharedState` 和 `NodeState` 表,seed 版本行
|
||||
- `web/service/node_guard.go`: `IsWorker()`/`IsMaster()`/`RequireMaster()`/`IsSharedModeEnabled()` 角色判断和写入保护
|
||||
- `web/service/inbound.go`: 所有写操作(AddInbound/DelInbound/UpdateInbound/AddInboundClient 等)前调用 `ensureSharedWriteAllowed()`,写操作内 `bumpSharedVersion(tx)` 原子递增版本号
|
||||
- `web/service/node_sync.go`: `NodeSyncService` — worker 轮询版本号变化 → 加载快照 → 缓存到本地 → 应用到 Xray;master 心跳循环
|
||||
- `web/service/node_cache.go`: `SharedAccountsSnapshot` 序列化/反序列化到本地 JSON 缓存
|
||||
- `web/service/traffic_flush.go`: `TrafficFlushService` — 收集流量 delta → 写入持久化队列 → 定时刷盘到 MariaDB
|
||||
- `web/service/traffic_pending.go`: `TrafficPendingStore` — 基于文件的持久化 delta 队列,支持 merge 语义
|
||||
- `web/job/xray_traffic_job.go`: 共享模式下走 `TrafficFlushService.Collect()` 路径,非共享模式走原有 `AddTraffic()` 路径
|
||||
- `web/web.go`: 新增 `startNodeLoops()` 和 `startTrafficFlushLoop()` 启动入口
|
||||
- `x-ui.sh`: 新增节点管理菜单(设置角色/ID/同步间隔/流量刷盘间隔)
|
||||
- `install.sh`: 安装流程中增加节点角色配置提示
|
||||
- `README.md`: 新增多节点共享控制文档
|
||||
|
||||
Impact
|
||||
|
||||
- 新增数据库表:`node_states`、`shared_states`
|
||||
- 新增配置项:`nodeRole`、`nodeId`、`syncInterval`、`trafficFlushInterval`
|
||||
- 修改 `inbounds` 和 `client_traffics` 写入流程,增加共享写入保护
|
||||
- 新增流量持久化队列文件:`traffic-pending.json`
|
||||
- 不影响非 MariaDB 模式的现有行为
|
||||
|
||||
Verification
|
||||
|
||||
- `go test ./config/ -v` — PASS
|
||||
- `go test ./database/ -v` — PASS
|
||||
- `go test ./web/service/ -run TestNode -v` — PASS
|
||||
- `go test ./web/service/ -run TestTraffic -v` — PASS
|
||||
- `bash -n install.sh` — syntax OK
|
||||
- `bash -n x-ui.sh` — syntax OK
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
- worker 节点需要配置 `nodeId` 和 `mariadb` 数据库类型,否则启动校验失败
|
||||
- 流量刷盘依赖 `traffic-pending.json` 文件,磁盘故障可能导致 delta 丢失
|
||||
- 后续需要处理残留 `inboundId: 0` delta 导致外键约束失败的问题(已在后续 commit 中修复)
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
Task Record: Improve MariaDB flow, DB settings init, and traffic flush
|
||||
|
||||
Date: 2026-04-15
|
||||
Related Module: install.sh, x-ui.sh, config, database, web/service — MariaDB 安装/切换/流量刷盘
|
||||
Change Type: Feature
|
||||
|
||||
Background
|
||||
|
||||
MariaDB 安装和切换流程存在多个问题:安装脚本逻辑分散、数据库设置初始化不完整、流量刷盘服务存在 bug。本次提交对整个 MariaDB 相关流程进行了大规模重构和修复。
|
||||
|
||||
Changes
|
||||
|
||||
- `install.sh`(+598/-行重构):
|
||||
- 重构 MariaDB 安装/切换流程,统一本地和远程 MariaDB 配置路径
|
||||
- 新增 MariaDB 业务用户/数据库创建逻辑
|
||||
- 改进卸载流程,支持部分安装状态下的清理
|
||||
- 新增 `tests/mariadb_install_switch_test.sh` 测试覆盖
|
||||
- `x-ui.sh`(+422/-行重构):
|
||||
- 重构数据库管理菜单,支持本地/远程 MariaDB 切换
|
||||
- 新增 MariaDB 端口校验、远程访问管理等菜单项
|
||||
- `config/config.go`:
|
||||
- 新增 `GetDBConfigFromJSON()` 读取数据库连接配置
|
||||
- 新增 `readGroupedString()`/`readGroupedInt()` 通用配置读取辅助函数
|
||||
- 配置别名映射支持多分组查找
|
||||
- `database/shared_state.go`:
|
||||
- 改进版本号操作的事务安全性
|
||||
- `web/service/traffic_flush.go`:
|
||||
- `Collect()` 新增 inbound-only 残留流量 delta 计算(inbound 总量 - 客户端总量)
|
||||
- `flushToDatabase()` 改进 UPSERT 逻辑,支持 MariaDB 的 `ON DUPLICATE KEY UPDATE`
|
||||
- 新增 `ReconcileSharedTrafficState()` 调用(auto-renew/disable 过期客户端)
|
||||
- `web/service/traffic_pending.go`:
|
||||
- 改进 `Merge()` 语义,支持按 `(kind, inboundId, email)` 键去重合并
|
||||
- `main.go`:
|
||||
- 新增 `NodeConfig` 启动校验入口
|
||||
- 改进 MariaDB 连接初始化流程
|
||||
- `update.sh`: 更新脚本适配新的安装流程
|
||||
|
||||
Impact
|
||||
|
||||
- `install.sh`: 大规模重构,影响所有 MariaDB 安装/切换/卸载路径
|
||||
- `x-ui.sh`: 数据库管理菜单重构
|
||||
- `config/config.go`: 新增配置读取辅助函数
|
||||
- `web/service/traffic_flush.go`: 流量刷盘逻辑改进
|
||||
- `web/service/traffic_pending.go`: delta 队列合并语义改进
|
||||
- `main.go`: 启动流程增加节点配置校验
|
||||
|
||||
Verification
|
||||
|
||||
- `go test ./config/ -v` — PASS
|
||||
- `go test ./database/ -v` — PASS
|
||||
- `go test ./web/service/ -run TestTraffic -v` — PASS
|
||||
- `go test ./main_test.go -v` — PASS
|
||||
- `bash -n install.sh` — syntax OK
|
||||
- `bash -n x-ui.sh` — syntax OK
|
||||
- `bash tests/mariadb_install_switch_test.sh` — PASS
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
- 安装脚本改动量大,需要在多种发行版上验证
|
||||
- 流量刷盘的 `inboundId: 0` 残留问题尚未处理(后续 commit 修复)
|
||||
- 配置读取辅助函数的分组别名映射需要与 JSON 结构保持同步
|
||||
31
docs/Tasktracking/2026-04-15-uninstall-mariadb-option.md
Normal file
31
docs/Tasktracking/2026-04-15-uninstall-mariadb-option.md
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
# 任务记录:uninstall-mariadb-option
|
||||
|
||||
- 日期:2026-04-15
|
||||
- 关联模块:x-ui uninstall flow / database cleanup / test script
|
||||
- 变更类型:优化
|
||||
|
||||
## 背景
|
||||
卸载流程原先只移除面板服务与文件,不处理 MariaDB 业务库、业务账号和本机 MariaDB 包,用户在希望彻底清理时需要手动处理。
|
||||
|
||||
## 修改内容
|
||||
- 在 `x-ui.sh` 的 `uninstall()` 中新增交互项:`是否删除数据库并卸载本机 MariaDB?`。
|
||||
- 当当前数据库类型为 MariaDB 且 host 为本机地址(`127.0.0.1`/`localhost`/`::1`)时:
|
||||
- 删除业务库与业务账号(`localhost`、`127.0.0.1`、`::1`)。
|
||||
- 卸载本机 MariaDB 服务与相关软件包。
|
||||
- 当数据库为远程 MariaDB 时,输出提示并跳过数据库删除与卸载,避免误删远程资源。
|
||||
- 新增 `remove_local_mariadb_data` 与 `uninstall_local_mariadb_packages` 两个函数。
|
||||
- 更新 `tests/mariadb_install_switch_test.sh`,增加新卸载逻辑关键文本断言。
|
||||
|
||||
## 影响范围
|
||||
- 影响文件:`x-ui.sh`、`tests/mariadb_install_switch_test.sh`。
|
||||
- 不影响面板安装流程、数据库切换流程、数据库结构。
|
||||
- 仅在卸载流程中新增可选数据库清理能力。
|
||||
|
||||
## 验证情况
|
||||
- 执行 `bash -n x-ui.sh`,通过。
|
||||
- 执行 `bash -n install.sh`,通过。
|
||||
- 执行 `bash tests/mariadb_install_switch_test.sh`,通过。
|
||||
|
||||
## 风险与后续
|
||||
- 用户若选择删除数据库,相关业务数据将不可恢复。
|
||||
- 后续可增加二次确认,显示将删除的数据库名和用户名,以进一步降低误操作风险。
|
||||
27
docs/Tasktracking/2026-04-15-validate-mariadb-port-input.md
Normal file
27
docs/Tasktracking/2026-04-15-validate-mariadb-port-input.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# 任务记录:validate-mariadb-port-input
|
||||
|
||||
- 日期:2026-04-15
|
||||
- 关联模块:install script / db switch menu / test script
|
||||
- 变更类型:修复
|
||||
|
||||
## 背景
|
||||
远程 MariaDB 连接配置流程中,端口输入未做格式和范围校验,用户输入非法值时只能在后续连接阶段失败,定位不直观。
|
||||
|
||||
## 修改内容
|
||||
- 在 `install.sh` 的远程 MariaDB 分支中新增端口校验循环。
|
||||
- 在 `x-ui.sh` 的数据库切换到 MariaDB(远程)分支中新增端口校验循环。
|
||||
- 在 `tests/mariadb_install_switch_test.sh` 增加断言,校验两处脚本都包含端口非法提示文本。
|
||||
|
||||
## 影响范围
|
||||
- 影响文件:`install.sh`、`x-ui.sh`、`tests/mariadb_install_switch_test.sh`。
|
||||
- 不影响数据库结构、接口协议、构建流程。
|
||||
- 仅影响交互式输入阶段的参数合法性检查。
|
||||
|
||||
## 验证情况
|
||||
- 执行 `bash -n install.sh`,通过。
|
||||
- 执行 `bash -n x-ui.sh`,通过。
|
||||
- 执行 `bash tests/mariadb_install_switch_test.sh`,通过。
|
||||
|
||||
## 风险与后续
|
||||
- 当前风险较低,变更仅限输入校验逻辑。
|
||||
- 后续可考虑将端口校验抽为统一函数,减少重复逻辑。
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
Task Record: Fix MariaDB restart error diagnostics
|
||||
|
||||
Date: 2026-04-23
|
||||
Related Module: install.sh, x-ui.sh — MariaDB service management
|
||||
Change Type: Fix
|
||||
|
||||
Background
|
||||
|
||||
用户在安装过程中选择本地 MariaDB 后,遇到 "重启 MariaDB 失败,请检查配置文件" 错误。该错误信息过于笼统,因为 `restart_mariadb_service()` 和 `start_mariadb_service()` 函数使用 `2>/dev/null` 抑制了 stderr,导致 systemctl 返回的实际错误信息被隐藏,无法定位根因。
|
||||
|
||||
Changes
|
||||
|
||||
- `restart_mariadb_service()`(install.sh + x-ui.sh):移除 stderr 抑制,捕获 systemctl/rc-service 输出,失败时打印实际错误信息和 `systemctl status` 诊断输出
|
||||
- `start_mariadb_service()`(install.sh + x-ui.sh):systemctl start/enable 失败时使用 `|| true` 避免 set -e 场景下脚本意外退出,保持行为一致
|
||||
|
||||
Impact
|
||||
|
||||
- install.sh: `restart_mariadb_service()` 和 `start_mariadb_service()`
|
||||
- x-ui.sh: `restart_mariadb_service()` 和 `start_mariadb_service()`
|
||||
- 不影响功能逻辑,仅改善错误诊断输出
|
||||
- 无 API、数据库、配置变更
|
||||
|
||||
Verification
|
||||
|
||||
- `bash -n install.sh` — syntax OK
|
||||
- `bash -n x-ui.sh` — syntax OK
|
||||
- `bash tests/mariadb_install_switch_test.sh` — PASS
|
||||
- `bash tests/mariadb_admin_empty_password_test.sh` — PASS
|
||||
- `bash tests/install_uninstall_resilience_test.sh` — PASS
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
- 无风险。改动仅影响错误输出,不改变控制流
|
||||
- 用户重新运行安装脚本后,应能看到 systemctl 实际报错原因(如配置文件语法错误、端口冲突等),可据此进一步定位
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
Task Record: Detect stale mariadb service file when server package is missing
|
||||
|
||||
Date: 2026-04-23
|
||||
Related Module: install.sh, x-ui.sh — has_local_mariadb_service()
|
||||
Change Type: Fix
|
||||
|
||||
Background
|
||||
|
||||
用户在安装过程中 MariaDB 重启失败。排查发现 systemd unit 文件存在于 `systemctl list-unit-files` 输出中,但 `mariadb-server` 包实际已被卸载,服务文件是残留状态。`has_local_mariadb_service()` 只检查了 unit 文件是否存在,未验证包是否已安装,导致跳过了服务器重新安装。
|
||||
|
||||
Changes
|
||||
|
||||
- `has_local_mariadb_service()`(install.sh + x-ui.sh):在检测到 unit 文件后,追加 `dpkg -s mariadb-server`(Debian/Ubuntu)或 `rpm -q mariadb-server`(RHEL/Fedora)验证包是否已安装。包不存在时返回 1,触发重新安装。
|
||||
|
||||
Impact
|
||||
|
||||
- install.sh: `has_local_mariadb_service()`
|
||||
- x-ui.sh: `has_local_mariadb_service()`
|
||||
- 不影响正常安装流程,仅在包被卸载但 unit 文件残留时触发重新安装
|
||||
- 无 API、数据库、配置变更
|
||||
|
||||
Verification
|
||||
|
||||
- `bash -n install.sh` — syntax OK
|
||||
- `bash -n x-ui.sh` — syntax OK
|
||||
- `bash tests/mariadb_install_switch_test.sh` — PASS
|
||||
- `bash tests/mariadb_admin_empty_password_test.sh` — PASS
|
||||
- `bash tests/install_uninstall_resilience_test.sh` — PASS
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
- 无风险。仅增加包安装状态检查,不影响已有逻辑
|
||||
- Arch/Alpine 等非 dpkg/rpm 发行版保持原行为(仅检查 unit 文件)
|
||||
35
docs/Tasktracking/2026-04-23-install-cron-before-acme.md
Normal file
35
docs/Tasktracking/2026-04-23-install-cron-before-acme.md
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
Task Record: Install cron before acme.sh for all distros
|
||||
|
||||
Date: 2026-04-23
|
||||
Related Module: install.sh — cron 安装
|
||||
Change Type: Fix
|
||||
|
||||
Background
|
||||
|
||||
acme.sh 依赖 cron 来执行证书自动续期,但在部分发行版(RHEL/Fedora/CentOS/Arch/openSUSE/Alpine)上,cron 服务可能未预装。acme.sh 安装时如果找不到 cron,会静默失败或报错,导致证书续期不生效。
|
||||
|
||||
Changes
|
||||
|
||||
- `install.sh`:
|
||||
- 在 `install_base()` 中新增 cron 包安装逻辑
|
||||
- RHEL/Fedora/CentOS/Arch/openSUSE: 安装 `cronie` 包
|
||||
- Alpine: 安装 `dcron` 包
|
||||
- 安装后确保 crond 服务启用并启动(`enable --now`)
|
||||
- 将 cron 安装移到 acme.sh 安装之前,确保依赖顺序正确
|
||||
|
||||
Impact
|
||||
|
||||
- `install.sh`: `install_base()` 函数
|
||||
- 不影响已有安装流程,仅在 cron 未安装时补充安装
|
||||
- 不影响数据库、API、前端
|
||||
|
||||
Verification
|
||||
|
||||
- `bash -n install.sh` — syntax OK
|
||||
- 在 Ubuntu/Debian 上验证(cron 通常已预装,无副作用)
|
||||
- 需要在 RHEL/Alpine 等发行版上验证 cron 安装逻辑
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
- 无风险。仅增加缺失包的安装,不影响已有逻辑
|
||||
- 如果用户手动禁用了 cron,证书续期仍会失败(非本次修复范围)
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
Task Record: Resolve shared-mode traffic flush blocked by stale inboundId=0 delta
|
||||
|
||||
Date: 2026-04-24
|
||||
Related Module: web/service/traffic_flush.go, web/web.go, web/job/xray_traffic_job.go — 流量刷盘
|
||||
Change Type: Fix
|
||||
|
||||
Background
|
||||
|
||||
共享模式下流量统计始终为 0,MariaDB 的 `client_traffics` 表从未被写入。排查发现 `traffic-pending.json` 中存在一个残留的 `inboundId: 0` 客户端流量 delta(在 InboundId 解析修复前产生)。`flushToDatabase()` 尝试将其写入 `client_traffics` 时,违反外键约束 `fk_inbounds_client_stats`(`inbounds` 表不存在 `id=0`),导致整个事务回滚,所有流量永远无法写入。
|
||||
|
||||
此外,`NewXrayTrafficJob()` 和 `startTrafficFlushLoop()` 各自创建了独立的 `TrafficPendingStore` 实例,指向同一个 `traffic-pending.json` 文件但使用独立的 `sync.Mutex`,存在数据竞争风险。
|
||||
|
||||
Changes
|
||||
|
||||
- `web/service/traffic_flush.go`:
|
||||
- `flushToDatabase()` 循环开头新增 `InboundID == 0` 检查,跳过无效 delta 并记录 warning 日志
|
||||
- `web/job/xray_traffic_job.go`:
|
||||
- `NewXrayTrafficJob()` 改为接受 `*service.TrafficPendingStore` 参数,不再自行创建 store
|
||||
- 移除 `config` 包依赖
|
||||
- `web/web.go`:
|
||||
- `Server` struct 新增 `trafficStore *service.TrafficPendingStore` 字段
|
||||
- `Start()` 中统一创建一个 `TrafficPendingStore` 实例
|
||||
- `startTask()` 和 `startTrafficFlushLoop()` 共享同一个 store 实例,消除双实例竞争
|
||||
- `web/service/traffic_flush_test.go`:
|
||||
- 新增 `TestFlushOnceSkipsZeroInboundIdDelta` 测试
|
||||
|
||||
Impact
|
||||
|
||||
- `web/service/traffic_flush.go`: flushToDatabase() 跳过无效 delta
|
||||
- `web/web.go`: Server 启动流程变更,store 统一创建
|
||||
- `web/job/xray_traffic_job.go`: 构造函数签名变更
|
||||
- 修复后需要删除残留的 `traffic-pending.json` 文件才能生效
|
||||
|
||||
Verification
|
||||
|
||||
- `go test ./web/service/ -run TestTraffic -v` — PASS
|
||||
- `go test ./web/service/ -run TestFlushOnceSkipsZeroInboundIdDelta -v` — PASS
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
- 部署时必须删除 `/etc/x-ui/traffic-pending.json`,否则残留的 `inboundId: 0` delta 仍会被跳过(不影响功能,但会产生 warning 日志)
|
||||
- `TrafficPendingStore` 的文件级锁已通过共享实例解决,但如果未来有多个进程访问同一文件,仍需考虑进程级锁
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
Task Record: Resolve client traffic InboundId from DB in shared mode
|
||||
|
||||
Date: 2026-04-24
|
||||
Related Module: web/service/traffic_flush.go, web/job/xray_traffic_job.go — 共享模式流量收集
|
||||
Change Type: Fix
|
||||
|
||||
Background
|
||||
|
||||
共享模式(MariaDB 多节点)下,Xray gRPC Stats API 返回的客户端流量只包含 email,不包含 InboundId(始终为 0)。`Collect()` 函数直接使用了这个 `InboundId: 0`,导致流量无法正确关联到 inbound,写入数据库时违反外键约束或写入错误的 inbound。
|
||||
|
||||
Changes
|
||||
|
||||
- `web/service/traffic_flush.go`:
|
||||
- `Collect()` 新增 `emailToInboundID` 映射:在处理客户端流量前,先从 `client_traffics` 表查询所有 email 对应的 `inbound_id`
|
||||
- 用查询到的真实 `InboundId` 替换 Xray API 返回的 `InboundId: 0`
|
||||
- 未知 email(数据库中无对应记录)跳过并记录 warning 日志
|
||||
- 新增测试用例:`TestCollectResolvesInboundIdFromDB`、`TestCollectSkipsUnknownEmail`、`TestCollectClampsNegativeResidualAndLogsDetailedWarning`
|
||||
- `web/job/xray_traffic_job.go`:
|
||||
- 共享模式下跳过 `addClientTraffic()`(因为 `Collect()` 已处理),改为手动计算并设置在线客户端列表
|
||||
- `web/service/inbound.go`:
|
||||
- 新增 `SetOnlineClients()` 和 `GetOnlineClients()` 方法,供共享模式设置在线状态
|
||||
- `x-ui.sh`:
|
||||
- 节点配置菜单增加 `trafficFlushInterval` 输入提示
|
||||
|
||||
Impact
|
||||
|
||||
- `web/service/traffic_flush.go`: Collect() 逻辑变更,影响所有共享模式节点的流量收集
|
||||
- `web/job/xray_traffic_job.go`: 共享模式的在线客户端检测逻辑
|
||||
- 不影响非共享模式(SQLite/单节点 MariaDB)
|
||||
|
||||
Verification
|
||||
|
||||
- `go test ./web/service/ -run TestCollect -v` — PASS
|
||||
- `go test ./web/service/ -run TestTraffic -v` — PASS
|
||||
|
||||
Risks And Follow-Up
|
||||
|
||||
- 如果 `client_traffics` 表为空(首次部署),所有客户端流量都会被跳过,直到第一个 inbound 被创建并产生 `client_traffics` 行
|
||||
- 旧的 `inboundId: 0` 残留 delta 仍可能存在于 `traffic-pending.json` 中(后续 commit 修复)
|
||||
Loading…
Reference in a new issue