You need to enable JavaScript to run this app. 基于aiogram的Telegram机器人如何实现横向扩展,用Redis FSM存储能否部署多实例?
优惠活动
大模型
产品
解决方案
定价
更多

基于aiogram的Telegram机器人如何实现横向扩展,用Redis FSM存储能否部署多实例?

aiogram 机器人横向扩展实现方案

核心问题直接判定

仅搭配Redis集群作为FSM存储,完全可以支撑多机器人实例稳定运行、保障用户交互连续性,但光靠Redis FSM本身不足以实现正确的横向扩展,必须配套对应的更新分发机制,否则依然会出现交互异常。
之前大家觉得Telegram Bot没法像RESTful服务一样多副本部署,本质是对更新的拉取机制理解有偏差,和FSM的存储位置没有直接关系。

逻辑拆解

  • 传统单实例Bot的运行依赖两个核心能力:
    • 持续从Telegram获取用户交互产生的更新(长轮询)、或者接收Telegram主动推送的更新(Webhook)
    • 跨轮次保存用户的交互会话状态(也就是FSM需要存储的核心内容)
  • 多实例部署的两类核心问题,Redis + aiogram的组合刚好能分别解决:
    • 会话状态共享问题:aiogram 3.x 原生实现了支持原子读写的RedisStorage,不管哪个实例拿到了某用户的交互请求,都能从同一个Redis集群中读到对应的会话状态,不会出现“用户在A实例填了一半表单,下一条消息被B实例接收到、丢失之前输入进度”的问题。只要Redis集群本身可用性达标,状态读写的可靠性完全可以支撑生产场景。
    • 更新重复处理问题:如果没有配套的更新分发逻辑,哪怕FSM存在Redis里,多个实例同时开启长轮询拉取同一个Bot Token的更新时,会随机瓜分所有收到的事件,甚至因为竞争关系出现同一个更新被多个实例重复处理的情况,导致用户收到多条重复响应、交互逻辑混乱。

可落地的横向扩展实现路径

方案一:长轮询适配(无公网暴露场景适用)

轻量改造即可实现,不需要把机器人部署到有公网IP的环境:

  • 单独部署1个轻量化的更新拉取进程,仅负责从Telegram长轮询拉取全量更新,通过Redis的List队列把更新分发给后端的N个业务处理实例
  • 所有业务处理实例统一配置同一个Redis FSM存储,从队列中消费更新、执行业务逻辑、回写会话状态
  • 为了避免拉取进程成为单点,可以基于Redis分布式锁做拉取节点的高可用切换:所有候选拉取节点竞争锁,拿到锁的节点负责拉取更新,锁过期后自动完成主备切换

方案二:Webhook适配(生产环境推荐)

性能和可靠性最优的扩展方案:

  • 将Telegram配置的Webhook回调地址指向统一反向代理的公网入口,反向代理按照健康检查规则,把收到的Bot更新负载均衡转发给后端任意一个可用的机器人实例
  • 所有机器人实例统一配置同一个Redis FSM存储,不需要额外搭队列,只要基于update_id在Redis中做15分钟的短周期去重,就能完全避免网络重试导致的重复处理问题
  • 反向代理可以自动剔除故障实例,哪怕某个机器人副本临时宕机,请求会自动转发到其他健康实例,不会中断用户交互

必须注意的避坑点

  • 严禁多个实例同时开启长轮询:哪怕配置了共享的Redis FSM,没有分布式锁保障的多实例长轮询依然会导致更新随机分流、重复处理,是最常见的部署故障点
  • 所有跨会话的临时缓存必须存在Redis中:不要把用户上传的文件信息、表单临时字段等存在机器人实例的本地内存或者本地文件里,否则一旦请求被分发到其他实例,会出现缓存丢失导致的逻辑异常
  • Redis FSM的key结构不需要额外改造:aiogram默认按照fsm:{bot_id}:{chat_id}:{user_id}的规则生成存储key,本身就是按用户维度分片的,适配Redis集群的路由规则,不会出现跨分片读写异常
  • 做好异常重试的幂等性保障:不管是长轮询还是Webhook模式,所有发送给用户的消息逻辑都要做幂等处理,避免因为网络抖动重试导致用户收到重复的通知

内容的提问来源于stack exchange,提问作者SS_Rebelious

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.31 18:36:02