影刀RPA工程实战:打造店群自动化的监控告警与异常自愈闭环

影刀RPA工程实战:打造店群自动化的监控告警与异常自愈闭环

自动化系统最危险的时刻,不是它报错的那一秒。
而是它已经错了三天,却没有任何人知道。

前两篇文章我们把浏览器实例池和店铺环境隔离聊透了,系统终于能在几十个店铺的规模下稳定跑起来。但上线第二周,现实就给了我们一巴掌:一个TEMU采集流程因为页面改版,连续两天在同一个元素定位上失败,任务队列里积压了上千条失败记录。而我们还浑然不觉,直到运营同事来问“为什么这两天数据没更新”。

那次之后我们定了一条铁律:没有监控的自动化,就是在裸奔。

这篇文章专门讲我们怎么给影刀RPA执行集群搭一套完整的监控、告警与异常自愈体系,让系统真正做到无人值守也能及时发现病灶,并尝试自我修复。


一、监控对象:从“机器死了没”到“业务对不

很多团队做监控,第一反应是盯着服务器CPU、内存、磁盘。这些当然重要,但对一个店群自动化系统来说,真正的业务问题往往不会直接反映在机器负载上。

我们需要监控的东西,可以分成四层:

第一层:基础设施层

执行机在线状态、CPU、内存、磁盘、网络连通性。这类指标通过常规的Prometheus Exporter或者Windows性能计数器就能拿到。

第二层:浏览器池层

picture.image

picture.image 池内实例总数、空闲实例数、分配失败次数、实例销毁重建速率、端口占用情况。这些是我们自己定义的业务指标,反映池子是否健康。

第三层:任务执行层

任务提交速率、任务完成速率、队列堆积长度、任务平均耗时、任务失败率(按店铺、按流程类型拆分)。这是调度层的核心业务指标。

picture.image

第四层:业务结果层

这是最关键也最容易漏掉的一层。比如“采集到的订单数是否接近零”、“上货数量是否异常下降”、“消息回复成功率是否突然掉到50%以下”。这些指标必须和正常业务基线做对比,才能发现那种“流程明明在跑,但产出全是错的”的隐蔽故障。

机器没挂、任务没失败、流程跑完了,不等于业务正常。
业务结果异常,才是最终极的告警触发条件。

picture.image

二、日志架构:结构化与集中化

我们要求所有执行节点、调度中心、浏览器池管理器输出的日志都是结构化的JSON,并且包含统一的字段规范。

一条标准的任务执行日志长这样:

picture.image

{
  "timestamp": "2026-05-18T10:23:45.123Z",
  "node_id": "executor-03",
  "task_id": "abc-123",
  "shop_id": "temu_045",
  "flow_name": "order_collect",
  "status": "failed",
  "error_code": "ELEMENT_NOT_FOUND",
  "error_detail": "Selector .order-list-item not found at step 3",
  "duration_ms": 23450,
  "browser_port": 9225,
  "retry_count": 1
}

picture.image 日志通过Filebeat实时采集到Elasticsearch,在Kibana上做可视化和搜索。这让我们能快速回答任何关于“某个店铺在某个时间段发生了什么”的问题。

但我们很快发现一个问题:影刀自身的日志几乎是黑盒。 影刀流程内部如果抛了一个未捕获异常,命令行输出里只给一个笼统的退出码,根本没有上下文。

为此我们做了一个重要改造:所有影刀流程的起始和结束,都必须在调度层记录边界日志,并且在流程的关键步骤主动输出自定义日志(通过影刀的“写日志”指令或者直接调用Python插件写文件)。这样即使影刀内部挂了,我们也能根据边界日志推断出大致死在哪一步。


三、告警规则设计:不是报警越多越好

刚开始我们什么都想告警,浏览器池水位低于5个就告、单个任务失败就告、CPU超过70%就告。结果告警邮件一天能收200封,很快就变成了所有人自动归档的垃圾邮件。

后来我们定了三级告警策略:

一级告警(紧急):系统不可用,需要立刻人工介入。

  • 调度中心服务挂掉
  • 所有执行机同时掉线
  • 任务队列堆积超过2000条且持续增长
  • 浏览器池连续5分钟无可分配实例

这类告警通过企业微信、电话通知,并且如果15分钟未处理会自动升级通知范围。

二级告警(警告):局部功能受损,需关注。

  • 单个执行机掉线
  • 某个店铺连续失败超过5次
  • 代理出口批量失效
  • 磁盘空间低于10%

这类告警通过企业微信消息推送,工作时间处理即可。

三级告警(提示):性能波动或业务异常,不必立即处理。

  • 任务平均耗时超过基线20%
  • 某个流程类型的失败率突破3%
  • 浏览器实例回收速率异常升高

这类告警只推送到运维看板上,不主动骚扰人,供回顾时分析。

我们还专门做了一个“告警抑制”逻辑:如果同一个店铺同一个错误码在5分钟内触发了10次告警,只会发第一条,后面的合并到摘要里延迟通知。避免告警风暴。


四、异常自愈:能自动恢复的,就别叫人起床

监控告警只是发现问题,真正让系统变强的是它能自己处理一部分问题。

我们梳理出三类可自愈的异常:

4.1 进程级异常

比如浏览器崩溃、影刀执行器僵死、临时网络抖动导致的任务失败。

自愈策略:在调度Worker里增加一个内层的自动重试逻辑。任务失败后,根据错误类型决定是否重试。如果是元素超时、网络超时这类临时故障,最多重试2次,每次间隔递增(5秒、15秒)。超过重试上限或者遇到明确不可重试的错误(如登录过期),任务转人工队列。

def run_with_retry(task, max_retries=2):
    last_exc = None
    for attempt in range(max_retries + 1):
        try:
            execute_task(task)
            return
        except RetryableError as e:
            last_exc = e
            logger.warning(f"Task {task.task_id} retryable error, attempt {attempt+1}")
            time.sleep(5 * (attempt + 1))
        except NonRetryableError as e:
            raise  # 直接抛出,不重试
    raise MaxRetryExceededError(last_exc)

4.2 环境级异常

比如浏览器实例健康检查失败、代理不通、用户数据目录损坏。

自愈策略:浏览器池的健康巡检线程一旦发现实例不可用,立即将其标记为“不可用”并尝试销毁重建。代理不通的问题通过一个独立的代理检测脚本(在实例启动前跑一次curl测试)来提前发现,直接换备用代理。

4.3 流程级异常

比如页面改版导致元素定位失败,这是最难自愈的一类。我们目前在尝试的方法是将这类失败自动截图并记录DOM快照,然后由人工或未来的AI分析模块来生成修复补丁。目前还无法做到全自动修复,但至少让定位问题的成本降到最低。


五、任务队列积压的自愈闭环

队列积压是我们最怕的一种故障模式。一个流程挂了,任务不停往队列里塞,消费者处理不过来,队列长度指数级增长,最终把Redis内存撑爆,然后所有服务跟着连锁崩溃。

我们做的防护手段有三层:

第一层:生产端限流。 调度中心下发任务前,先检查队列长度。如果超过阈值,暂停该店铺的新任务提交,并触发告警。

第二层:消费者端动态扩容。 执行节点池有空闲容量时,调度中心会拉取积压任务加速消费。不过这个受限于机器数量,我们目前还是手动加节点,自动扩容需要容器化支持,后续再做。

第三层:队列尾部丢弃+回溯。 在极端情况下(比如队列已经堆了上万条),我们会启用应急模式:保留最新的一部分任务,丢弃最旧的重复任务(如同店铺同类型的重复采集任务),并记录丢弃清单,事后通过补跑机制回溯。这个逻辑在Redis里用Lua脚本原子化执行,避免竞态。


六、看板设计:让系统状态一目了然

我们用Kibana做了三块看板,对应不同角色。

运维看板:展示所有执行机的健康状态、浏览器池水位、队列堆积、告警趋势。这是一个大屏,挂在办公室墙上,运维扫一眼就知道现在系统是否正常。

业务看板:按店铺维度展示成功率、耗时、采集量趋势。业务运营同学看这个就知道今天自动化产出如何。

调试看板:工程师专用,可以按任务ID、店铺ID、时间段检索原始日志和截图,快速定位失败原因。

这三块看板极大降低了沟通成本。以前运营老是问“今天数据怎么没出来”,现在他们自己先看业务看板,确认是系统问题还是流程问题,再决定找谁。


七、自愈策略的安全边界

在做自动恢复的时候,有一条线我们始终不敢越:涉及金钱、订单状态变更的操作,绝对不能自动重试。

比如改价、报活动、确认发货,这些操作一旦出现异常,只允许挂起人工处理,绝不允许自动回滚或重试。因为自动重试可能导致重复扣款、价格多次覆盖等致命后果。

我们在任务定义里加了一个 safety_level 字段:

  • safe:可自动重试,失败后自愈
  • caution:可自动重试一次,失败后人工介入
  • critical:绝不自动重试,直接挂起并电话告警

所有流程上线前都必须标注安全等级,调度器在执行时严格遵守。


八、演练:把故障常态化

监控和自愈体系上线之后,我们并没有直接高枕无忧。我们每两周会做一次“混沌工程演练”——主动注入故障,看系统反应是否符合预期。

比如:

  • 随机kill掉一个执行机上的浏览器实例
  • 拔掉一台执行机的网线
  • 向任务队列注入一批必然失败的脏任务
  • 修改某个店铺的代理配置为无效地址

每次演练都会暴露一堆问题。比如有一次我们手动kill掉一个浏览器进程,池子巡检线程正常发现了异常并重建,但重建后没有恢复 env.json 指纹文件——因为重建逻辑调错了初始化函数。这种边界bug在正常运行时根本碰不到,只有故意制造混乱才能揪出来。

让系统在可控的混乱中成长,比在生产环境里被动崩溃要好得多。


九、这套体系最终给团队带来了什么

有数字能说话:接入这套监控自愈体系后,我们的MTTD(平均故障发现时间)从原本的“运营反馈才知道”的数小时,缩短到了分钟级。MTTR(平均故障恢复时间)从人工登录服务器手动杀进程、重启流程的30分钟以上,压缩到大部分问题在5分钟内自动恢复。

更重要的是,团队的心态变了。以前大家时不时就要瞄一眼服务器,生怕出问题;现在即使半夜收到告警,也会先看一眼自愈状态,多数情况已经自己处理掉了,可以翻个身继续睡。


十、未完的话

监控和自愈是一个永远做不完的工程。我们目前最头疼的问题有两个:一是流程失败截图如何自动分析并给出修复建议,二是当业务逻辑本身出问题(比如平台改了规则)时,怎么在自愈框架里优雅地引入人工决策节点,而不是完全靠人去排查。这些是我们接下来要啃的骨头。

自动化系统成熟度的标志,不是它能跑多少流程。
而是出问题时,它能用多快的速度告诉你,并尝试把自己修好。

作者:林焱
一个持续在自动化工程一线填坑的工程师

0
0
0
0
评论
未登录
暂无评论