优质中转站,最难的其实不是转发,而是失败时候的处理过程
上一篇主要聊了路由,这几天又继续把后端重构了一下,其实刚开始做的时候,我也觉得中转站后端没那么复杂,一般就是针对请求,找一个支持对应模型的渠道,转发过去,拿到结果,扣费,结束。关键点在于我们需要考虑一下这几种情况:
-
间歇性的429如何处理?
-
首字延迟高如何处理?
-
上游已经吐了几十个 token,然后连接重置的情况咋办?
-
请求失败以后,应该重试同级渠道,还是降级重试?
-
同一个渠道几十个 Key,其中只有一个 Key 出问题,到底该封 Key 还是封整个渠道。
这个项目也是基于 New API 后端继续改的。New API 功能很多,协议兼容也做得很好,但是将他应用于高并发的生产环境,后端的逻辑还是需要修改。
第一个问题是 重试机制(重试机制和优先级耦合太严重了)
New API 目前的逻辑,本质上是:
retry0走第一个优先级的渠道 retry1走第二个优先级渠道 retry2走第三个优先级渠道
自动分组在这个基础上继续套一层组间的索引。
所以重试这个机制同时承担了1. 当前请求重试了多少次2.当前应该落到第几档位的优先级渠道3.auto 分组当前走到哪个组 4.什么时候该跨分组调用渠道。
这样并不适用于生产环境,因为如何有多个渠道都是有相同的优先级,如果第一个渠道突然链接重置以后,肯定要继续重试下一个相同优先级的第二个渠道,而不是发生了一次重试直接就到下一个优先级的渠道,这样显然不合理。
所以我的项目,每次请求会单独维护一个对应的状态:
{attempted channels last error remaining retry budget deadline stream committed current health snapshot}
第一次失败之后,Router 重新对剩余候选池重新做一次决策。
而且不同错误的重试策略不应该相同,429、连接超时、连接重置…本来就不应该使用同一种方式处理。
第二个问题是健康状态不能只有 enabled / disabled
New API 自己有自动测试、自动禁用和自动恢复的机制,但是整体还是比较简单。
某个错误命中了自动禁用规则,就:有启用变为自动禁用,后面如果在管理员指定的时间间隔测试成功,再由自动禁用变为启用。这种二极管的方式显然不适合于生产环境,针对单个渠道他的状态很有可能是:完全健康到开始少量的429再到TTFB升高,再到超时,再到恢复这个周期循环往复,如果在这个周期的其中一个环境就禁用渠道未免太过可惜。
我现在对渠道做的是加入第三个中间状态:
CLOSED OPEN HALF_OPEN
这样不是看到一个错误就改变全局状态,然后统计:
2xx 429 5xx timeout connection reset upstream disconnect TTFB total latency active requests rate limit remaining/reset
并且错误不是简单算成一个 error_count。因为 429 和 401不是同一种错误。渠道禁用以后是过指定时间先进 HALF_OPEN状态,连续成功以后再按照指定的时间间隔恢复。这样做以后,渠道恢复的时候不会突然被一波流量重新搞到自动禁用。
第三个问题是多节点部署之后需要考虑状态传播
我做了集群才认识到New API 的渠道的缓存本身是进程内的映射。按照指定的时间周期性的从数据库全量同步,默认就是几十秒这个量级。好像是20秒我记得。单节点完全没有问题,因为对应的就一个缓存,多节点就麻烦很多了。如果请求在第一个节点某个渠道发现 401,把它自动禁用了。但是 第二个节点,第三个节点并不会瞬间知道这件事情,它们还是要等下一轮的同步,我猜测newapi的作者应该是先照着单节点的模式去做的,后续考虑多节点同步的问题的时候,有点难以处理了,github目前还有相关的open issue等待解决。这段时间坏渠道仍然可能不断收到请求。而且自动恢复走的是另外一条链路,不是所有情况下都会马上把整个 候选的缓存重构一遍。
我现在更多考虑2种状态,配置状态属于:
渠道属于什么组 支持什么模型 成本统计 管理员优先级 静态写死的策略
运行时状态属于:
health circuit rate limit EWMA active requests last failure
当配置发生改变以后,通过版本号 + 事件通知所有节点失效。
这样其中一个节点的状态改变其他节点会立刻同步,而数据库负责持久化,不负责做实时消息的同步,这样数据库的压力也会少很多。
再聊一下 New API
针对这个大热的项目,我还是很认可的。
尤其是账号、Token、计费、渠道管理、各种协议 adaptor、模型映射、后台这些东西自己从头写一套非常的麻烦,而且这套东西除了sub2api做到差不多,市面上的开源的代码也没有再这些方面超过这两个项目的了,要么就是路由的架构以及逻辑做的很优秀但是少了账号计费,渠道管理,并发控制和集群部署,要么就是像newapi这样做的大而全但是有些功能需要优化。
我现在这套还远远谈不上完美,不过至少已经不是简单给 New API 换个皮然后挂几个渠道了。
改善这些点以后也推荐给大家我的项目
现在无论是路由,并发控制时的一致性,还是集群部署时出现的问题,以及上面提到的状态的加入,以及修改,以及重试的机制,整体已经非常完善了,我们也是对接了多家企业总共300+的用户使用这个平台,现在折扣是分档的,用户可以根据自己的需求选择不同的档位现在新用户注册即送测试额度,欢迎大家试用。 项目地址:api.smartrouter.asia