Cloudflare Workers — "Não Bộ" Xử Lý Ở Phía Sau (Backend Runtime) 🧠¶
Workers Thực Chất Là Gì?¶
Bạn hãy tưởng tượng Cloudflare Workers như một đội ngũ nhân viên chạy việc (serverless) có thể hiểu được ngôn ngữ JavaScript/TypeScript. Điểm đặc biệt là đội ngũ này không ngồi ở một văn phòng cố định (máy chủ truyền thống), mà họ túc trực tại mạng lưới Edge — tức là hơn 200 trung tâm dữ liệu của Cloudflare trên toàn thế giới. Khách hàng ở đâu, nhân viên ở gần đó sẽ phục vụ ngay lập tức.
Nhớ kỹ: Nó không phải là Node.js đâu nhé!
Nhiều bạn hay nhầm Workers với Node.js. Thực tế, Workers dùng V8 Isolates — bộ não chạy JavaScript tương tự như trình duyệt Google Chrome, nhưng nó không bê nguyên hệ sinh thái API đồ sộ của Node.js sang.
Nguyên Lý Hoạt Động Của Nó Ra Sao?¶
Câu chuyện: V8 Isolates vs Máy chủ truyền thống (Processes)¶
Khi bạn thuê một máy chủ Node.js bình thường:
[Máy chủ Node.js] → Chạy ròng rã 24/7 không ngừng nghỉ
- Dù lúc nửa đêm không có ai vào web, nó vẫn ngốn RAM và tốn điện.
- Một máy chủ phải xếp hàng phục vụ từng người một.
- Lỡ bị sập (crash) → Toang, phải khởi động lại máy chủ bằng tay (hoặc nhờ công cụ như PM2).
Khi bạn xài Cloudflare Workers:
Có khách gọi đến → Cloudflare lập tức tạo ra một môi trường nhỏ (V8 Isolate) → Xử lý xong → Hủy luôn
- Tốc độ khởi động siêu tốc (chỉ khoảng 0 mili-giây), không bắt khách chờ (cold start) như mấy cái Lambda cũ.
- Mỗi một yêu cầu (request) của khách sẽ được nhốt trong một phòng riêng (isolate).
- Phòng này có cháy nổ (crash) thì các phòng khác vẫn chạy bình thường.
Tóm lại: V8 Isolate giống như một căn phòng làm việc siêu nhỏ, siêu nhẹ dành riêng cho mã JavaScript. Nó mở cửa nhanh hơn cả cái chớp mắt.
Cách nó đón khách (Mô hình Fetch Handler)¶
// Đây là bộ khung cơ bản nhất của một anh nhân viên Worker
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
// Nếu khách hỏi đường dẫn /health, trả lời là "ok"
if (url.pathname === '/health') {
return Response.json({ status: 'ok' });
}
// Nếu hỏi linh tinh, báo lỗi 404 (Không tìm thấy)
return new Response('Tới lộn địa chỉ rồi bạn ơi', { status: 404 });
}
}
request: Gói hàng khách gửi đến — chứa đường link, thông tin kẹp theo (headers), và dữ liệu (body).env: "Cái túi thần kỳ" chứa đồ nghề (kết nối Database D1, chỗ giấu mật khẩu...) do Cloudflare cấp cho bạn.ctx: Trợ lý giúp xử lý những việc vặt chạy ngầm (background tasks) sau khi đã trả lời khách xong.
Bật mí: Trong dự án này, mình dùng thư viện Hono cho nó nhàn chứ không tự viết tay như trên đâu, nhưng bản chất Hono bên dưới cũng y chang vậy đó.
Móc Nối Tài Nguyên (Env Bindings) 🔗¶
Làm sao để code của bạn nói chuyện được với Database hay lấy được mật khẩu? Mọi thứ đều qua cái túi env. Bạn khai báo nó trong "sổ hộ khẩu" wrangler.toml:
# api/wrangler.toml
name = "group-accounting-api"
main = "src/index.ts"
compatibility_date = "2024-07-25"
compatibility_flags = ["nodejs_compat"]
# Khai báo kết nối với kho dữ liệu D1
[[d1_databases]]
binding = "DB" # Tên gọi thân mật trong code: env.DB
database_name = "group-accounting-db"
database_id = "426266db-..."
# Các biến môi trường công khai (Ai xem cũng được)
[vars]
FRONTEND_URL = "[https://quythuchi.pages.dev](https://quythuchi.pages.dev)"
Còn với Bí mật quốc gia (Secrets) (mật khẩu, API key... tuyệt đối không để lộ trong code), bạn phải thì thầm qua cửa sổ lệnh (CLI):
Để lúc gõ code không bị nhầm lẫn, chúng ta dùng TypeScript để gom chúng lại cho dễ quản lý:
// api/src/types.ts
export interface Env {
DB: D1Database;
JWT_SECRET: string;
TURNSTILE_SECRET_KEY: string;
GOOGLE_CLIENT_ID: string;
GOOGLE_CLIENT_SECRET: string;
FRONTEND_URL: string;
}
Những Giới Hạn Cần Bỏ Túi ⚠️¶
Vì là đồ "xài chung" nên nó cũng có luật chơi riêng:
| Tài nguyên | Gói Miễn Phí (Free) | Gói Trả Phí (Paid) |
|---|---|---|
| Lượt gọi API / ngày | 100.000 lượt | 10 Triệu lượt (bao gồm sẵn) |
| Thời gian não bộ suy nghĩ (CPU time) | 10 mili-giây | 30 giây |
| Bộ nhớ RAM | 128MB | 128MB |
| Kích thước file code (đã nén) | 1MB | 10MB |
| Số lần Worker gọi ra ngoài (Subrequests) | 50 lần / 1 request | 1000 lần / 1 request |
Lưu ý cực mạnh: Thời gian CPU khác với Thời gian thực (Wall-clock time)
Bạn thấy "10 mili-giây CPU time" có vẻ ít? Đừng lo! Nó chỉ tính thời gian con chip CPU thực sự tính toán. Thời gian Worker đứng chờ database trả dữ liệu hay chờ gọi API bên ngoài (chờ I/O) sẽ không bị tính vào CPU time. Nghĩa là: Web của bạn có thể mất nửa giây (500ms) để tải xong, nhưng CPU chỉ phải làm việc có 2ms thôi. Nên gói Free xài rất thoải mái!
Cờ Tương Thích (Compatibility Flags) 🚩¶
Nãy mình nói Workers không phải Node.js đúng không? Nhưng vì nhiều thư viện trên mạng được viết cho Node.js, nên Cloudflare tạo ra cái cờ này. Nó giống như một "anh phiên dịch", giúp Worker hiểu được một vài tính năng cơ bản của Node.js (như Buffer, process.env), để bạn cài thư viện ngoài không bị lỗi.
Code Thử Tại Máy Nhà (Local Development) 💻¶
# Bật server thử nghiệm ở máy chạy tại: http://localhost:8787
wrangler dev
# Khúc này sướng lắm: Cứ ấn lưu code là hệ thống tự khởi động lại trong tíc tắc (hot-reload)
Khi bạn gõ lệnh wrangler dev, công cụ này sẽ "giả lập" toàn bộ hệ thống khổng lồ của Cloudflare ngay trên chiếc máy tính của bạn, bao gồm cả cái database D1 mini luôn. Bạn cứ thoải mái test ở nhà, khi nào hoàn hảo mới tung lên mạng!