v2.1.0-go
·
93 commits
to go-rewrite
since this release
v2.1.0-go
一次以并发正确性与运维健壮性为主的版本:修掉五处会在生产上造成实际损失的
缺陷,加固验证码浏览器路径,并补上 OpenAI Responses 的用量细节。因为其中有几处
改变了对外可观察的行为(见下),故按次版本号发布。
行为变更
- 客户端无法再覆盖网关的固定请求头。此前固定头先建立、客户端透传头后合并,
客户端送一个X-Device-Mid就能改掉该账号的设备指纹——而这正是每账号指纹隔离
的基础;大小写不同的两个同名头还会各占一个 map 键,最终取值取决于迭代顺序。
现在固定头恒胜:透传头先合并(键统一为规范形式),固定头最后覆写。
⚠️ 客户端不能再影响X-Device-Mid、Anthropic-Version、Content-Type等取值。 - 客户端断连不再冷却账号。此前上游请求被取消(用户关掉客户端、连接中断)会
按「连接失败」把账号冷却整整一轮冷却时长,一次中断最多可连锁影响 5 个账号。
现在识别为取消:不冷却、也不换号(换号只会白烧另一个账号的额度)。 - 异步(空闲池)路径开始识别 200 包装的业务错误。上游会用
200包装额度耗尽
一类的业务错误(如code=1005),此前异步路径直接当成功流转发:客户端收到空流、
账号不被标任何状态、下次仍会被选中白耗。现在与同步路径走同一套分类。 - 收到
SIGTERM会优雅停机。此前进程不处理停机信号,容器要等约 10 秒被强杀,
额度监控与领取调度器都来不及收尾;错误路径的os.Exit还会跳过全部defer。
现在停止接受新连接、等待在途请求收尾(上限 10 秒)后退出。
⚠️ zcode2api的退出码语义随之明确:0 为正常退出(含收到信号),1 为启动失败。 /v1/responses的 usage 口径变化。input_tokens现在并入缓存读写
(Anthropic 把缓存 token 单列在cache_read_input_tokens/
cache_creation_input_tokens,不计入input_tokens),并新增
input_tokens_details.{cached_tokens, cache_write_tokens}。此前只报原始
input_tokens,用量会被严重低估,且按cached_tokens判断上下文压缩时机的
客户端(如 Codex)会一直以为没有缓存命中。
修复内容
网关
- 额度信号不再改写更强的账号状态。
invalid(凭证失效,需人工介入)、
cooling(冷却窗口内)、disabled(管理员主动停用)三者与「额度用没用完」无关,
此前会被MarkModelExhausted无条件刷成active并清空冷却时间——并发下一条 402
就能把刚判失效的账号放回轮询。现在只更新模型耗尽清单,不动账号状态与冷却窗口。 - 异步路径的
200 + JSON分类与同步路径逐条对齐(1005 → 标该模型耗尽并换号;
3007 → 换令牌重试;其余业务码 → 投递错误事件;无业务码 → 判为无效流)。
运维
- HTTP 服务端补上
ReadHeaderTimeout(30 秒)与IdleTimeout(120 秒)。
WriteTimeout保持为 0——SSE 是长连接,写超时会把正常的长流掐断。
验证码
- 浏览器池的启动与关闭移出求解器锁。此前
pool.Start()(最长 90 秒)持锁执行,
期间所有求解者、乃至停机时的Close()全被钉住——后者会让容器等不到优雅退出。
并发冷启动由「启动中」闩串行化,仍只拉起一个浏览器进程。 - 连接浏览器失败时不再对未连接成功的对象调用
Close()(上游把这一处判定为
nil panic 风险),资源清理由 launcher 负责。 - 解包
tar的硬链接分支补上路径逃逸检查(符号链接分支原本已有)。此前未校验的
Linkname可把解包目录之外的任意文件内容复制进来。顺带修掉一处平台差异:
filepath.IsAbs("/etc/passwd")在 Windows 上返回 false(缺盘符),会让校验结果
随平台漂移。 ZCODE_CAPTCHA_TIMEOUT补下界(与同组其它超时项一致),设 0 或负数不再导致
每次求解的 deadline 立刻到期。
OpenAI 兼容
function_call_output现在同时接受字符串与内容块数组。Codex 在工具返回结构化
内容时会发数组,此前只做字符串断言会把整段工具输出静默变成空串,多轮工具上下文
随之丢失。- 流式 usage 合并改为数值取较大者,不再让
message_delta补发的
input_tokens: 0把已统计的用量清零。
使用说明
升级只需重启进程;没有新增配置项,现有数据卷与 .env 均无需改动。
反代部署多了一条建议:若前面挂了 Nginx / Caddy 等反向代理,请把 compose 的端口
改成只绑回环(- "127.0.0.1:3000:3000")。反代转发后 RemoteAddr 恒为代理地址,
后台登录的「单 IP 10 次失败」限速会退化成全局限速——任何人的十次失败都能锁死整个
后台。README 与 docker-compose.yml 注释里都写了这一条。
Docker
docker pull ghcr.io/fujunchao/zcode2api-plus:2.1.0-go支持 linux/amd64 和 linux/arm64,同时更新 latest。现有数据卷与非 root 运行
方式不变。
能力依据
本版的改动全部来自与上游仓库的逐项比对(评估报告见
docs/upstream-sync-2026-09-18.md,实施记录见 docs/upstream-followup-plan.md)。
上游默认分支 go-rewrite 自 2026-09-12 分叉后新增 49 个提交,其中 18 个属一次
缺陷审查批次。我们只回移了判定为「确有影响」的部分;访客投稿、Cap 校验、
裸机部署脚本等与我们定位不符的改动未跟进。
验证情况:go build、go vet 与全量 14 个包测试通过,gofmt 74 个文件 0 不合规,
windows/darwin/linux 交叉编译通过。仍未验证或未覆盖的部分:
- 并发正确性只在本机做了一半——本机没有 C 编译器,
go test -race由 CI 负责,
其中验证码求解器的加锁改动最需要它把关。 - 验证码浏览器路径没有实机跑通(本机无浏览器环境),相关改动只做了通读、编译与
既有用例不回归。 - 反代端口只绑回环是建议而非自动生效,需按自身部署调整 compose。
- 2.0.8-go 起的那项领取链路修复(手动领取补当日活跃上报)仍未经过线上真实账号
验证,若领取仍报「上游無投放套餐」,问题在自造device_mid上。