如何实现仅在Lambda函数第三次执行失败时触发Slack告警
零额外存储判定Lambda第三次执行的实现方案
核心原理
CloudWatch Event(EventBridge)调度触发的Lambda属于异步调用类型,Lambda默认对失败执行最多重试2次,合计总运行3次,和你提到的运行行为完全一致。整个重试过程的计数由Lambda服务原生维护,不需要你额外引入Redis这类存储做状态记录,重试相关信息会直接通过Lambda运行时上下文透传,完全无状态成本。
实现1:业务Lambda内部读取原生重试标记(不改动核心业务逻辑)
Lambda异步调用触发重试时,会在运行时上下文的client_context.custom字段中自动注入Retry-Attempt参数,不同运行轮次对应的取值完全匹配你的计数逻辑:
- 取值为0:首次执行(第1次运行)
- 取值为1:第一次重试(第2次运行)
- 取值为2:第二次重试(第3次运行,即最终失败的最后一次尝试)
直接在业务Lambda代码里读取该值就能判断是否为第三次执行,示例如下:
def lambda_handler(event, context): # 读取原生重试计数,首次执行默认取0 retry_count = context.client_context.custom.get('Retry-Attempt', 0) # 判定是否为第三次最终执行 is_final_run = (retry_count == 2) try: # 原有业务逻辑 pass except Exception as e: # 仅最后一次执行失败时,才触发Slack告警 if is_final_run: # 你原有的Slack发送逻辑可以直接嵌入在这里,前两次失败时不触发告警 send_slack_alert(f"Lambda最终执行失败: {str(e)}") # 非最终尝试直接抛出错误,交给Lambda按默认策略自动重试 raise e
实现2:调整CloudWatch告警规则(全程零代码改动)
如果不想修改原有业务Lambda的代码,也可以直接调整现有告警配置达到同样效果:
- 把原有“单次失败即触发”的CloudWatch告警阈值,修改为连续3次Lambda执行错误才触发告警
- 同步调整告警的统计评估窗口,确保窗口长度覆盖3次执行的总时长(包含两次重试的等待间隔),避免前两次重试失败时提前触发告警
- 调整完成后,只有Lambda三次执行全部失败时,才会通过Sns触发你现有的Slack告警Lambda,完全匹配你的触发要求,你原来的Slack发送代码不需要做任何修改。
注意事项
- 这套方案全程不依赖任何外部存储,所有重试计数逻辑由Lambda服务在运行时托管,没有额外运维成本,也不会出现多实例下计数不准的问题
- 注意区分调用类型:只有异步触发的Lambda(EventBridge调度、Sns/SQS触发等)才会自动注入
Retry-Attempt参数,同步触发的调用没有这个字段 - 后续如果调整了Lambda的默认重试次数,记得同步修改对应的判断逻辑或者告警阈值,避免告警触发时机偏移
内容的提问来源于stack exchange,提问作者Presley Cobb
相关产品推荐
相关产品推荐

