blog.dopana

Back

Bạn cần tự động hóa các tác vụ định kỳ như backup, gửi email, hoặc xử lý dữ liệu? AWS Lambda kết hợp với CloudWatch Events/EventBridge là giải pháp serverless hoàn hảo để thay thế cron jobs truyền thống.

Tổng quan về Lambda Scheduled Jobs#

AWS Lambda là compute service serverless cho phép chạy code mà không cần quản lý server. Khi kết hợp với scheduling service, bạn có thể:

  • Tự động hóa tác vụ: Backup, report generation, data cleanup
  • Tiết kiệm chi phí: Chỉ trả tiền khi code thực thi
  • Scale tự động: Xử lý tăng tải mà không cần cấu hình
  • High availability: AWS đảm bảo tính sẵn sàng

[!NOTE] Hiện tại AWS khuyến nghị sử dụng EventBridge Scheduler thay vì CloudWatch Events cũ cho các scheduled jobs mới.

Phương pháp 1: EventBridge Scheduler (Khuyến nghị)#

EventBridge Scheduler là service scheduling hiện đại với nhiều tính năng nâng cao so với CloudWatch Events.

Ưu điểm của EventBridge Scheduler#

  • Hỗ trợ timezone: Không chỉ giới hạn UTC
  • Flexible time windows: Chạy trong khoảng thời gian linh hoạt
  • Built-in retry: Tự động retry khi thất bại
  • One-time schedules: Hỗ trợ chạy một lần
  • Dead Letter Queue: Xử lý failure tốt hơn

Bước 1: Tạo Lambda Function#

Bước 2: Tạo IAM Role#

Lambda cần permission để thực thi job và ghi log:

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

Policy permissions:

Bước 3: Tạo Schedule với EventBridge Scheduler#

Sử dụng AWS Console#

  1. Vào EventBridge Scheduler console
  2. Click Create schedule
  3. Chọn Recurring schedule
  4. Cấu hình schedule expression:
# Chạy hàng ngày lúc 9:00 AM UTC
cron(0 9 * * ? *)

# Chạy mỗi 15 phút
rate(15 minutes)

# Chạy hàng tuần vào Monday 9:00 AM
cron(0 9 ? * MON *)

# Chạy đầu mỗi tháng
cron(0 0 1 * ? *)
bash
  1. Select Lambda function làm target
  2. Cấu hình timezone (nếu cần):
# 9:00 AM Eastern Time
cron(0 9 ? * MON *)
timezone: America/New_York
bash
  1. Cấu hình flexible time window (optional):
# Chạy trong 15 phút sau thời gian schedule
mode: FLEXIBLE
maximum_window_in_minutes: 15
bash
  1. Setup retry policy:
maximum_retry_attempts: 3
maximum_event_age_in_seconds: 3600
bash

Sử dụng 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

Sử dụng Terraform#

Phương pháp 2: CloudWatch Events (Legacy)#

CloudWatch Events là phương pháp truyền thống, vẫn được hỗ trợ nhưng ít tính năng hơn.

Bước 1: Tạo Lambda Function#

Tương tự như phương pháp Scheduler.

Bước 2: Tạo CloudWatch Rule#

Sử dụng AWS Console#

  1. Vào CloudWatch console
  2. Chọn Events → Rules
  3. Click Create rule
  4. Chọn Schedule expression
  5. Nhập cron expression:
# 9:00 AM UTC hàng ngày
0 9 * * ? *

# Mỗi 5 phút
rate(5 minutes)
bash
  1. Select Lambda function làm target
  2. Configure permission (AWS sẽ tự động tạo)

Sử dụng AWS CLI#

Cron Expression Guide#

EventBridge sử dụng 6-field cron expression:

cron(Minutes Hours Day-of-month Month Day-of-week Year)
text

Ví dụ Cron Expressions#

Field Values#

FieldValuesSpecial Characters
Minutes0-59, - * /
Hours0-23, - * /
Day of month1-31, L, W, - * / ? L W
Month1-12, JAN-DEC, - * /
Day of week1-7, SUN-SAT, ?, L, #, - * / ? L #
Year1970-2199, - * /

[!WARNING] Use ? khi day-of-month hoặc day-of-week bị constraint, không được dùng cả hai field cùng lúc.

Best Practices#

1. Idempotency#

Đảm bảo handler của bạn idempotent để safe khi retry:

def lambda_handler(event, context):
    # Check nếu job đã chạy
    if is_job_already_processed(event):
        logger.info("Job already processed, skipping")
        return {"status": "skipped"}
    
    # Process job
    result = process_job(event)
    
    # Mark job as processed
    mark_job_as_processed(event)
    
    return result
python

2. Dead Letter Queue (DLQ)#

Setup DLQ để xử lý failed invocations:

import boto3
import json

sqs = boto3.client('sqs')

def send_to_dlq(error_message, event):
    """Gửi failed event đến DLQ"""
    sqs.send_message(
        QueueUrl='YOUR_DLQ_URL',
        MessageBody=json.dumps({
            'error': error_message,
            'event': event,
            'timestamp': str(datetime.utcnow())
        })
    )
python

3. Overlap Prevention#

Ngăn chặn overlapping executions với DynamoDB lock:

4. Monitoring và Logging#

Sử dụng CloudWatch Logs và Metrics:

5. Error Handling#

Xử lý error gracefully:

So sánh EventBridge Scheduler vs CloudWatch Events#

Tính năngEventBridge SchedulerCloudWatch Events
Schedule typescron + rate + one-timecron + rate
Timezone support✅ Any timezone❌ UTC only
Flexible windows✅ Yes❌ No
Built-in retry✅ Yes❌ No (need DLQ)
Cost$1.00/M invocationsFree (first 5M/month)
Use caseProduction jobsSimple recurring jobs

Ví dụ Thực tế: Daily Database Cleanup#

Schedule với EventBridge Scheduler:

# Chạy hàng ngày lúc 2:00 AM UTC
cron(0 2 * * ? *)
bash

Troubleshooting#

Job không chạy#

  1. Check schedule expression: Đảm bảo cron syntax đúng
  2. Verify IAM permissions: Lambda có permission cần thiết
  3. Check CloudWatch Logs: Xem error messages
  4. Verify target ARN: Đảm bảo Lambda function ARN đúng

Job chạy nhưng fail#

  1. Review CloudWatch Logs: Tìm error messages
  2. Check timeout: Lambda có thể timeout
  3. Verify resource permissions: Database, S3, etc. access
  4. Test locally: Chạy Lambda locally để debug

Overlapping executions#

  1. Implement lock mechanism: Sử dụng DynamoDB hoặc Redis
  2. Use reserved concurrency: Giới hạn concurrent executions
  3. Add idempotency: Đảm bảo handler idempotent

Cleanup Resources#

Khi không cần nữa, xóa resources:

# Delete schedule
aws scheduler delete-schedule --name daily-job

# Delete CloudWatch rule
aws events delete-rule --name daily-lambda-rule

# Delete Lambda function
aws lambda delete-function --function-name my-function

# Delete IAM role
aws iam delete-role --role-name scheduler-role
bash

Kết luận#

AWS Lambda kết hợp với EventBridge Scheduler/CloudWatch Events cung cấp giải pháp mạnh mẽ cho scheduled jobs:

  • EventBridge Scheduler: Cho production jobs với timezone support, retry, flexible windows
  • CloudWatch Events: Cho simple recurring jobs với cost hiệu quả

Key takeaways:

  1. Sử dụng EventBridge Scheduler cho production
  2. Implement idempotency và error handling
  3. Setup monitoring với CloudWatch
  4. Use DLQ cho failed invocations
  5. Prevent overlapping executions

Tài liệu tham khảo#