blog.dopana

Back

需要自动化定期任务如备份、邮件发送或数据处理?AWS Lambda结合CloudWatch Events/EventBridge是替代传统cron作业的完美无服务器解决方案。

Lambda定时作业概述#

AWS Lambda是无服务器计算服务,允许您运行代码而无需管理服务器。与调度服务结合使用时,您可以:

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

[!NOTE] AWS目前推荐在新定时作业中使用EventBridge Scheduler而不是传统的CloudWatch Events。

方法1: EventBridge Scheduler(推荐)#

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

EventBridge Scheduler的优势#

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

步骤1: 创建Lambda函数#

步骤2: 创建IAM角色#

Lambda需要执行作业和写入日志的权限:

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

策略权限:

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

使用AWS控制台#

  1. 转到EventBridge Scheduler控制台
  2. 点击Create schedule
  3. 选择Recurring schedule
  4. 配置调度表达式:
# 每天UTC时间9:00 AM运行
cron(0 9 * * ? *)

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

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

# 每月1日运行
cron(0 0 1 * ? *)
bash
  1. 选择Lambda function作为目标
  2. 配置时区(如果需要):
# 9:00 AM Eastern Time
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. 点击Create rule
  4. 选择Schedule expression
  5. 输入cron表达式:
# 每天UTC时间9:00 AM
0 9 * * ? *

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

使用AWS CLI#

Cron表达式指南#

EventBridge使用6字段cron表达式:

cron(Minutes Hours Day-of-month Month Day-of-week Year)
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. 幂等性#

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

def lambda_handler(event, context):
    # 检查作业是否已运行
    if is_job_already_processed(event):
        logger.info("Job already processed, skipping")
        return {"status": "skipped"}
    
    # 处理作业
    result = process_job(event)
    
    # 将作业标记为已处理
    mark_job_as_processed(event)
    
    return result
python

2. 死信队列(DLQ)#

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

import boto3
import json

sqs = boto3.client('sqs')

def send_to_dlq(error_message, event):
    """将失败的事件发送到DLQ"""
    sqs.send_message(
        QueueUrl='YOUR_DLQ_URL',
        MessageBody=json.dumps({
            'error': error_message,
            'event': event,
            'timestamp': str(datetime.utcnow())
        })
    )
python

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调度:

# 每天UTC时间2:00 AM运行
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. 防止重叠执行

参考文献#