先把当时的情况摆出来。用 one-api 做统一入口,配了三个同模型渠道,主渠道返回 429 时请求直接失败,没有落到备用渠道,重试开关是打开的,日志里只有一次 upstream 429。

排查方向其实有限,先把可能性排一排。渠道的重试次数按渠道组算,默认不再切下一个。还有一种是429 被配置成不触发重试的状态码。

还有一种情况,渠道优先级相同,但负载均衡策略是固定权重。另外,备用渠道的模型名映射与主渠道不一致。

第一件事是看渠道列表和优先级

curl -s http://127.0.0.1:3000/api/channel/?p=0 -H "Authorization: Bearer $ONEAPI_TOKEN" | jq '.data[].group'

再往下把重试次数调大并允许跨渠道

curl -s http://127.0.0.1:3000/api/option/ -H "Authorization: Bearer $ONEAPI_TOKEN" -X PUT -d '{"key":"RetryTimes","value":"3"}'

人为让主渠道返回 429 观察落点

python failover_test.py --primary-key bad --rounds 5

末了核对备用渠道的模型映射字段

curl -s http://127.0.0.1:3000/api/channel/2 -H "Authorization: Bearer $ONEAPI_TOKEN" | jq '.model_mapping'

怎么算真的好了,看的是同一批现象。五次人为失败全部落到备用渠道并返回 200,日志里能看到渠道切换记录。

网关的重试默认只在同渠道内,跨渠道切换要单独打开,否则备用配置形同虚设。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189