blog.dopana

Back

Cần tự động hóa các tác vụ định kỳ như sao lưu, 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ế các công việc cron truyền thống. Hướng dẫn này tập trung vào triển khai TypeScript/Node.js cho các công việc định kỳ sẵn sàng cho production.

Tổng quan về công việc định kỳ Lambda#

AWS Lambda là dịch vụ tính toán serverless cho phép bạn chạy mã mà không cần quản lý máy chủ. Khi kết hợp với các dịch vụ lập lịch, bạn có thể:

  • Tự động hóa tác vụ: Sao lưu, tạo báo cáo, dọn dẹp dữ liệu
  • Tiết kiệm chi phí: Chỉ trả tiền khi mã thực thi
  • Tự động mở rộng: Xử lý tải tăng mà không cần cấu hình
  • Tính sẵn sàng cao: AWS đảm bảo tính sẵn sàng

[!NOTE] AWS hiện đề xuất sử dụng EventBridge Scheduler thay vì CloudWatch Events truyền thống cho các công việc định kỳ mới.

flowchart LR
    subgraph Scheduler["Trình kích hoạt (Trigger)"]
        direction TB
        EBS["EventBridge Scheduler<br/>(Hỗ trợ múi giờ / Retry / Flexible)"]
        CWE["CloudWatch Events<br/>(Cron truyền thống)"]
    end

    subgraph Serverless["Xử lý Serverless"]
        Lambda["AWS Lambda Function<br/>(Node.js / TypeScript)"]
        DLQ["Dead Letter Queue (SQS)<br/>(Lưu trữ lỗi khi gọi thất bại)"]
    end

    subgraph Targets["Tác vụ & Dịch vụ liên quan"]
        DB[(Cơ sở dữ liệu / S3)]
        Log["CloudWatch Logs / Alarms"]
    end

    EBS -->|Invoke định kỳ| Lambda
    CWE -.->|Invoke cơ bản| Lambda
    Lambda -.->|Gặp sự cố / Retry hết| DLQ
    Lambda -->|Đọc / Ghi dữ liệu| DB
    Lambda -->|Ghi log giám sát| Log

EventBridge Scheduler là dịch vụ lập lịch hiện đại với các tính năng nâng cao so với CloudWatch Events.

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

  • Hỗ trợ múi giờ: Không bị giới hạn chỉ UTC
  • Cửa sổ thời gian linh hoạt: Chạy trong các phạm vi thời gian linh hoạt
  • Tự động thử lại: Tự động thử lại khi thất bại
  • Lịch trình một lần: Hỗ trợ thực thi đơn lẻ
  • Dead Letter Queue: Xử lý lỗi tốt hơn

Bước 1: Tạo hàm Lambda TypeScript#

Bước 2: Tạo vai trò IAM#

Lambda cần quyền để thực thi công việc và ghi log:

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

Quyền chính sách:

Bước 3: Tạo lịch trình với EventBridge Scheduler#

Sử dụng AWS Console#

  1. Đi đến EventBridge Scheduler console
  2. Nhấp vào Create schedule
  3. Chọn Recurring schedule
  4. Cấu hình biểu thức lịch trình:
# 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 Thứ Hai 9:00 AM
cron(0 9 ? * MON *)

# Chạy vào ngày đầu tiên của mỗi tháng
cron(0 0 1 * ? *)
bash
  1. Chọn hàm Lambda làm mục tiêu
  2. Cấu hình múi giờ (nếu cần):
# 9:00 AM Eastern Time
cron(0 9 ? * MON *)
timezone: America/New_York
bash
  1. Cấu hình cửa sổ thời gian linh hoạt (tùy chọn):
# Chạy trong vòng 15 phút sau thời gian định kỳ
mode: FLEXIBLE
maximum_window_in_minutes: 15
bash
  1. Thiết lập chính sách thử lại:
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 (Truyền thống)#

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

Bước 1: Tạo hàm Lambda#

Giống như phương pháp Scheduler.

Bước 2: Tạo quy tắc CloudWatch#

Sử dụng AWS Console#

  1. Đi đến CloudWatch console
  2. Chọn Events → Rules
  3. Nhấp vào Create rule
  4. Chọn Schedule expression
  5. Nhập biểu thức cron:
# 9:00 AM UTC hàng ngày
0 9 * * ? *

# Mỗi 5 phút
rate(5 minutes)
bash
  1. Chọn hàm Lambda làm mục tiêu
  2. Cấu hình quyền (AWS sẽ tự động tạo)

Sử dụng AWS CLI#

Hướng dẫn biểu thức Cron#

EventBridge sử dụng biểu thức cron 6 trường:

cron(Phút Giờ Ngày-trong-tháng Tháng Ngày-trong-tuần Năm)
text

Ví dụ biểu thức Cron#

Giá trị trường#

TrườngGiá trịKý tự đặc biệt
Phút0-59, - * /
Giờ0-23, - * /
Ngày trong tháng1-31, L, W, - * / ? L W
Tháng1-12, JAN-DEC, - * /
Ngày trong tuần1-7, SUN-SAT, ?, L, #, - * / ? L #
Năm1970-2199, - * /

[!WARNING] Sử dụng ? khi ngày-trong-tháng hoặc ngày-trong-tuần bị giới hạn, không sử dụng cả hai trường cùng lúc.

Thực hành tốt nhất#

1. Định danh (Idempotency)#

Đảm bảo handler của bạn có tính định danh để thử lại an toàn:

2. Dead Letter Queue (DLQ)#

Thiết lập DLQ để xử lý các lượt gọi thất bại:

3. Ngăn chặn chồng chéo#

Ngăn chặn các lần thực thi chồng chéo với khóa DynamoDB:

4. Giám sát và ghi log#

Sử dụng CloudWatch Logs và Metrics:

5. Xử lý lỗi#

Xử lý lỗi một cách tinh tế:

So sánh: EventBridge Scheduler vs CloudWatch Events#

Tính năngEventBridge SchedulerCloudWatch Events
Loại lịch trìnhcron + rate + one-timecron + rate
Hỗ trợ múi giờ✅ Múi giờ bất kỳ❌ Chỉ UTC
Cửa sổ linh hoạt✅ Có❌ Không
Tự động thử lại✅ Có❌ Không (cần DLQ)
Chi phí$1.00/M lượt gọiMiễn phí (5M/tháng đầu)
Trường hợp sử dụngCông việc productionCông việc định kỳ đơn giản

Ví dụ thực tế: Dọn dẹp cơ sở dữ liệu hàng ngày#

Lịch trình với EventBridge Scheduler:

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

Khắc phục sự cố#

Công việc không chạy#

  1. Kiểm tra biểu thức lịch trình: Đảm bảo cú pháp cron đúng
  2. Xác minh quyền IAM: Lambda có quyền cần thiết
  3. Kiểm tra CloudWatch Logs: Tìm thông báo lỗi
  4. Xác minh ARN mục tiêu: Đảm bảo ARN hàm Lambda đúng

Công việc chạy nhưng thất bại#

  1. Xem lại CloudWatch Logs: Tìm thông báo lỗi
  2. Kiểm tra thời gian chờ: Lambda có thể đang hết thời gian
  3. Xác minh quyền tài nguyên: Truy cập cơ sở dữ liệu, S3, v.v.
  4. Kiểm tra cục bộ: Chạy Lambda cục bộ để debug

Các lần thực thi chồng chéo#

  1. Triển khai cơ chế khóa: Sử dụng DynamoDB hoặc Redis
  2. Sử dụng concurrency dự phòng: Giới hạn các lần thực thi đồng thời
  3. Thêm tính định danh: Đảm bảo handler có tính định danh

Dọn dẹp tài nguyên#

Khi không còn cần thiết, dọn dẹp tài nguyên:

# Xóa lịch trình
aws scheduler delete-schedule --name daily-job

# Xóa quy tắc CloudWatch
aws events delete-rule --name daily-lambda-rule

# Xóa hàm Lambda
aws lambda delete-function --function-name my-function

# Xóa vai trò IAM
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 các công việc định kỳ:

  • EventBridge Scheduler: Cho công việc production với hỗ trợ múi giờ, thử lại, cửa sổ linh hoạt
  • CloudWatch Events: Cho công việc định kỳ đơn giản với hiệu quả chi phí

Các điểm chính:

  1. Sử dụng EventBridge Scheduler cho production
  2. Triển khai tính định danh và xử lý lỗi
  3. Thiết lập giám sát với CloudWatch
  4. Sử dụng DLQ cho các lượt gọi thất bại
  5. Ngăn chặn các lần thực thi chồng chéo

Tài liệu tham khảo#