blog.dopana

Back

需要自动化定期任务如备份、邮件发送或数据处理?AWS Lambda结合CloudWatch Events/EventBridge是替代传统cron作业的无服务器完美解决方案。本指南专注于TypeScript/Node.js的生产级定时任务实现。

Lambda定时任务概述#

AWS Lambda是无服务器计算服务,允许您在不管理服务器的情况下运行代码。当与调度服务结合时,您可以:

  • 自动化任务:备份、报告生成、数据清理
  • 节省成本:仅在代码执行时付费
  • 自动扩展:无需配置即可处理负载增加
  • 高可用性:AWS确保可用性

[!NOTE] AWS目前推荐使用EventBridge Scheduler而不是传统的CloudWatch Events用于新的定时任务。

flowchart LR
    subgraph Scheduler["调度触发器"]
        direction TB
        EBS["EventBridge Scheduler<br/>(时区支持 / 重试 / 灵活时间窗口)"]
        CWE["CloudWatch Events<br/>(传统Cron)"]
    end

    subgraph Serverless["无服务器计算"]
        Lambda["AWS Lambda Function<br/>(Node.js / TypeScript)"]
        DLQ["Dead Letter Queue (SQS)<br/>(调用失败死信队列)"]
    end

    subgraph Targets["目标资源与监控"]
        DB[(数据库 / S3存储桶)]
        Log["CloudWatch Logs / 告警"]
    end

    EBS -->|定时触发| Lambda
    CWE -.->|基础触发| Lambda
    Lambda -.->|执行失败 / 超过重试上限| DLQ
    Lambda -->|读写数据| DB
    Lambda -->|记录日志与指标| Log

EventBridge Scheduler是现代调度服务,与CloudWatch Events相比具有增强功能。

EventBridge Scheduler的优势#

  • 时区支持:不仅限于UTC
  • 灵活时间窗口:在灵活时间范围内运行
  • 内置重试:失败时自动重试
  • 一次性调度:支持单次执行
  • 死信队列:更好的错误处理

步骤1: 创建TypeScript Lambda函数#

步骤2: 创建IAM角色#

Lambda需要权限来执行任务和写入日志:

trust-policy.json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
json

策略权限:

步骤3: 使用EventBridge Scheduler创建调度#

使用AWS控制台#

  1. 进入EventBridge Scheduler控制台
  2. 点击创建调度
  3. 选择定期调度
  4. 配置调度表达式:
# 每天上午9:00 UTC运行
cron(0 9 * * ? *)

# 每15分钟运行
rate(15 minutes)

# 每周一上午9:00运行
cron(0 9 ? * MON *)

# 每月第一天运行
cron(0 0 1 * ? *)
bash
  1. 选择Lambda函数作为目标
  2. 配置时区(如果需要):
# 东部时间上午9:00
cron(0 9 ? * MON *)
timezone: America/New_York
bash
  1. 配置灵活时间窗口(可选):
# 在调度时间后15分钟内运行
mode: FLEXIBLE
maximum_window_in_minutes: 15
bash
  1. 设置重试策略:
maximum_retry_attempts: 3
maximum_event_age_in_seconds: 3600
bash

使用AWS CLI#

aws scheduler create-schedule \
  --name daily-job \
  --schedule-expression 'cron(0 9 * * ? *)' \
  --schedule-expression-timezone 'UTC' \
  --target '{
    "Arn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
    "RoleArn": "arn:aws:iam::123456789012:role/scheduler-role"
  }' \
  --flexible-time-window '{
    "Mode": "FLEXIBLE",
    "MaximumWindowInMinutes": 15
  }'
bash

使用Terraform#

方法2: CloudWatch Events(传统)#

CloudWatch Events是传统方法,仍然支持但功能较少。

步骤1: 创建Lambda函数#

与Scheduler方法相同。

步骤2: 创建CloudWatch规则#

使用AWS控制台#

  1. 进入CloudWatch控制台
  2. 选择Events → Rules
  3. 点击创建规则
  4. 选择调度表达式
  5. 输入cron表达式:
# 每天上午9:00 UTC
0 9 * * ? *

# 每5分钟
rate(5 minutes)
bash
  1. 选择Lambda函数作为目标
  2. 配置权限(AWS将自动创建)

使用AWS CLI#

Cron表达式指南#

EventBridge使用6字段cron表达式:

cron(分钟 小时 日-月 月 星期-日 年)
text

Cron表达式示例#

字段值#

字段特殊字符
分钟0-59, - * /
小时0-23, - * /
日-月1-31, L, W, - * / ? L W
1-12, JAN-DEC, - * /
星期-日1-7, SUN-SAT, ?, L, #, - * / ? L #
1970-2199, - * /

[!WARNING] 当日-月或星期-日受约束时使用?,不要同时使用两个字段。

最佳实践#

1. 幂等性#

确保处理程序是幂等的,以便安全重试:

2. 死信队列(DLQ)#

设置DLQ来处理失败的调用:

3. 防止重叠执行#

使用DynamoDB锁防止重叠执行:

4. 监控和日志#

使用CloudWatch Logs和Metrics:

5. 错误处理#

优雅地处理错误:

比较: EventBridge Scheduler vs CloudWatch Events#

功能EventBridge SchedulerCloudWatch Events
调度类型cron + rate + one-timecron + rate
时区支持✅ 任何时区❌ 仅UTC
灵活窗口✅ 是❌ 否
内置重试✅ 是❌ 否(需要DLQ)
成本$1.00/M调用免费(前5M/月)
用例生产任务简单定期任务

实践示例: 每日数据库清理#

使用EventBridge Scheduler调度:

# 每天凌晨2:00 UTC运行
cron(0 2 * * ? *)
bash

故障排除#

任务不运行#

  1. 检查调度表达式:确保cron语法正确
  2. 验证IAM权限:Lambda具有必要权限
  3. 检查CloudWatch Logs:查找错误消息
  4. 验证目标ARN:确保Lambda函数ARN正确

任务运行但失败#

  1. 查看CloudWatch Logs:查找错误消息
  2. 检查超时:Lambda可能超时
  3. 验证资源权限:数据库、S3等访问权限
  4. 本地测试:本地运行Lambda进行调试

重叠执行#

  1. 实现锁机制:使用DynamoDB或Redis
  2. 使用预留并发:限制并发执行
  3. 添加幂等性:确保处理程序是幂等的

清理资源#

不再需要时,清理资源:

# 删除调度
aws scheduler delete-schedule --name daily-job

# 删除CloudWatch规则
aws events delete-rule --name daily-lambda-rule

# 删除Lambda函数
aws lambda delete-function --function-name my-function

# 删除IAM角色
aws iam delete-role --role-name scheduler-role
bash

结论#

AWS Lambda结合EventBridge Scheduler/CloudWatch Events为定时任务提供了强大的解决方案:

  • EventBridge Scheduler:用于具有时区支持、重试、灵活窗口的生产任务
  • CloudWatch Events:用于具有成本效益的简单定期任务

关键要点:

  1. 生产环境使用EventBridge Scheduler
  2. 实现幂等性和错误处理
  3. 使用CloudWatch设置监控
  4. 为失败的调用使用DLQ
  5. 防止重叠执行

参考文献#