单机跑机器人,撑到二十多个账号就到了极限:发布要停服、故障恢复靠人、扩容靠复制目录。迁移到 Kubernetes 之后,发布滚动、故障自愈、扩容改个数字。本文记录这次迁移的关键决策与踩过的坑。

背景痛点

机器人是有状态服务——每个账号绑定一个实例的网络出口,这和典型无状态 Web 服务的容器化路径不同:不能随便漂移,不能无限副本。迁移方案要围绕"有状态"来设计,照搬无状态那套会翻车。

原理

所谓机器人的容器化,是指将实例进程容器化并保留账号与网络绑定的编排方案:

单实例一个 Pod → 账号与 Pod 通过固定标识绑定 → 网络出口按实例固定 → 健康检查探测真实业务在线 → 发布走滚动替换。

两个关键决策。不做水平扩容:一个账号一个实例,副本数固定为 1,弹性扩容对机器人没有意义。健康检查探业务而不是探进程:进程活着不等于账号在线,登录与在线状态的判定口径按接口文档实现,探测失败到阈值才重启。

核心实现

就绪探针的探测逻辑(仅演示,上线前对照官方文档校验):

# 仅演示,上线前对照官方文档校验
# app 为 Flask/FastAPI 实例,login 为封装的登录状态查询组件
@app.route("/healthz")
def healthz():
    st = login.status(appid)               # 探业务在线,不探进程
    if st != ONLINE and attempts_exceeded():
        return {"ok": False}, 503          # 连续失败才让 K8s 重启
    return {"ok": True}, 200

启动探针给足取码与验证的初始化时间,避免新实例被误杀。

踩坑

一、网络出口固定是前提:账号与出口的一致性要求(Eyun 开发文档按文档的 region/socks5/aid 三选一模式设定),在容器环境里靠 Pod 固定调度加专用出口节点实现,Pod 随意漂移调度会引发掉线。

二、优雅退出必须做:滚动发布时 Pod 被杀,发送中的任务要处理完、状态要落库再退出——SIGTERM 处理里等待任务收尾,超过宽限期才强杀。

三、探针频率别太密:在线探测本身就是接口调用,探测间隔按分钟级设置,探针太频繁反而制造接口压力。

四、日志与状态分离:容器易逝,账号状态、别名表、任务队列全部外置存储,Pod 重建后新容器从外置存储恢复现场。

总结

容器化的收益不在资源,在运维:发布从停服升级变成滚动替换,故障从人工发现变成自愈重启。本文基于 Eyun 平台的企微接口实践整理,账号状态与网络配置的口径以官方文档为准,迁移路径建议单机到 K8s 中间不要跳步,先把状态外置做扎实,编排层才有迁移的可能。开通与环境准备可参考Eyun 平台。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐