Mở đầu — vì sao bài này quan trọng
Trong những bài trước, bạn đã làm quen với RPA, các công cụ no-code/low-code như Zapier, Make, n8n, và bắt đầu hiểu sự khác nhau giữa workflow, orchestration và choreography. Nhưng khi hệ thống của bạn lớn lên — hàng chục microservices, hàng triệu giao dịch mỗi ngày, các quy trình kéo dài hàng giờ thậm chí hàng tuần — thì những công cụ kéo-thả kia bắt đầu "đuối". Bạn cần một thứ mạnh hơn, đáng tin cậy hơn, có thể chịu được việc server crash giữa chừng mà không làm hỏng cả quy trình kinh doanh.
Đó chính là lúc các workflow engine cấp doanh nghiệp như Temporal.io và Apache Airflow lên sân khấu. Đây là hai cái tên mà bất kỳ kỹ sư automation hay kiến trúc sư hệ thống nghiêm túc nào cũng phải biết. Chúng không phải là công cụ để nhân viên nghiệp vụ tự kéo-thả, mà là nền tảng để đội kỹ thuật xây dựng những luồng xử lý phức tạp, bền vững và có thể quan sát được.
Bài học hôm nay giúp bạn hiểu rõ: Temporal.io giải quyết bài toán gì, Airflow mạnh ở đâu, khi nào dùng cái nào, và quan trọng nhất — tư duy "durable execution" (thực thi bền vững) sẽ thay đổi cách bạn thiết kế hệ thống automation như thế nào. Đây là kiến thức nền tảng cho mọi kiến trúc hyperautomation mà chúng ta sẽ bàn ở các bài sau.
Khái niệm cốt lõi
Workflow engine là gì và vì sao cần nó
Hãy tưởng tượng một quy trình đặt hàng trên sàn thương mại điện tử: nhận đơn → trừ kho → tính phí ship → gọi cổng thanh toán → gửi email xác nhận → tạo lệnh giao hàng. Mỗi bước gọi sang một service khác nhau, và bất kỳ bước nào cũng có thể thất bại: mạng chập chờn, cổng thanh toán timeout, service kho đang deploy.
Nếu bạn viết logic này bằng code thông thường, bạn sẽ phải tự xử lý: retry khi lỗi, lưu trạng thái đang ở bước nào, khôi phục nếu server restart, tránh trừ kho hai lần (idempotency), timeout, bù trừ (compensation) khi cần hoàn tiền... Code "ống nước" (plumbing) này thường chiếm 80% công sức và là nơi sinh ra bug khó chịu nhất.
Workflow engine sinh ra để gánh phần "ống nước" đó cho bạn. Bạn chỉ tập trung mô tả cái gì cần làm theo thứ tự nào, còn engine lo làm sao để nó chạy đáng tin cậy.
Temporal.io — "durable execution" cho microservices
Temporal.io là một nền tảng orchestration cho microservices theo hướng code-first. Triết lý cốt lõi của nó gói gọn trong hai chữ: durable execution (thực thi bền vững).
Nghĩa là gì? Bình thường khi process của bạn chạy đến giữa chừng mà server crash, toàn bộ trạng thái trong bộ nhớ (biến đang chạy, đang ở dòng code nào) sẽ mất sạch. Với Temporal, trạng thái thực thi được lưu bền vững một cách tự động. Khi server sống lại, workflow tiếp tục đúng từ chỗ nó dừng, như thể chưa có gì xảy ra. Bạn có thể viết một hàm "ngủ 30 ngày rồi gửi email nhắc gia hạn" — và Temporal sẽ thực sự giữ workflow đó sống suốt 30 ngày, kể cả khi server được deploy lại hàng chục lần.
Cách Temporal làm được điều này là event sourcing: mọi sự kiện trong workflow (gọi activity nào, nhận kết quả gì) được ghi vào một "history". Khi cần khôi phục, engine "replay" lại lịch sử đó để dựng lại đúng trạng thái. Người ta gọi đây là cơ chế deterministic replay.
Vài đặc điểm bạn cần nhớ về Temporal:
- Code-first: bạn viết workflow bằng ngôn ngữ lập trình thật, với SDK cho Go, Java, TypeScript, Python, .NET, PHP. Không phải kéo-thả, không phải YAML — chỉ là code thông thường mà bạn có thể test, version, review như bất kỳ code nào.
- Workflow vs Activity: Code Temporal chia hai loại. Workflow là logic điều phối (phải deterministic — không gọi trực tiếp API, không random, không đọc giờ hệ thống bừa bãi). Activity là nơi làm việc bẩn với thế giới bên ngoài (gọi API, ghi DB, gửi email) — và Temporal tự retry activity khi nó thất bại.
- Hợp với quy trình dài và có trạng thái: đăng ký gói thuê bao, quy trình onboarding nhân viên kéo dài nhiều tuần, saga thanh toán nhiều bước có bù trừ.
Apache Airflow — orchestrator cho data pipeline
Apache Airflow là một câu chuyện khác. Ra đời tại Airbnb năm 2014 và nay là dự án Apache, Airflow là nền tảng điều phối (orchestration) thiên về data engineering, dùng để lập lịch (schedule) và giám sát các pipeline xử lý dữ liệu.
Khái niệm trung tâm của Airflow là DAG — Directed Acyclic Graph (đồ thị có hướng, không vòng lặp). Mỗi DAG là một tập các task với quan hệ phụ thuộc: task B chạy sau khi task A xong. Bạn định nghĩa DAG bằng Python, và Airflow lo việc lên lịch, chạy đúng thứ tự, retry, gửi cảnh báo khi lỗi.
Đặc điểm của Airflow:
- Schedule-driven: rất mạnh cho các job chạy theo lịch — "mỗi 2 giờ sáng kéo dữ liệu bán hàng hôm qua, làm sạch, đổ vào data warehouse, chạy báo cáo".
- Hệ sinh thái operator khổng lồ: có sẵn hàng trăm "operator" để kết nối với mọi thứ — BigQuery, Snowflake, Spark, S3, Postgres, Kafka, dbt...
- UI giám sát trực quan: bạn nhìn thấy từng task xanh/đỏ, log chi tiết, có thể chạy lại (re-run) một task lỗi.
- Batch chứ không phải real-time: Airflow sinh ra cho xử lý theo lô (batch), không phải cho phản ứng tức thời từng sự kiện.
So sánh nhanh: chọn cái nào?
Đây là phần nhiều người nhầm lẫn nhất. Hãy ghi nhớ nguyên tắc:
| Tiêu chí | Temporal.io | Apache Airflow |
|---|---|---|
| Mục đích chính | Orchestration microservices, business logic | Orchestration data pipeline (ETL/ELT) |
| Mô hình kích hoạt | Sự kiện, theo yêu cầu, dài hạn có trạng thái | Theo lịch (schedule), batch |
| Cách định nghĩa | Code (Go/Java/TS/Python/.NET) | Code Python (DAG) |
| Điểm mạnh độc nhất | Durable execution, sống sót qua crash | Hệ sinh thái data, giám sát batch |
| Hợp với | Đặt hàng, thanh toán, onboarding | Báo cáo hằng ngày, đồng bộ data warehouse |
Tình huống thực tế
Ví dụ 1 — Sàn thương mại điện tử Đông Nam Á dùng Temporal cho luồng đặt hàng
Hãy lấy bối cảnh một sàn TMĐT giả định nhưng rất sát thực tế — gọi là "ShopSEA", quy mô tương tự một sàn tầm trung tại Việt Nam, xử lý khoảng 200.000 đơn/ngày vào mùa cao điểm như đợt sale 11/11.
Trước đây, luồng checkout của họ viết bằng code Node.js thuần với hàng đống try/catch và một bảng database tự chế để lưu "đơn này đang ở bước nào". Vào ngày sale lớn, cổng thanh toán bị quá tải, nhiều request timeout. Hậu quả: có đơn trừ kho rồi nhưng không thu được tiền, có đơn thu tiền hai lần do retry sai, đội vận hành phải đối soát tay hàng nghìn đơn lúc nửa đêm.
Họ chuyển luồng checkout sang Temporal. Mỗi đơn hàng trở thành một workflow instance. Các bước trừ kho, gọi thanh toán, gửi email được viết thành các activity với chính sách retry rõ ràng (ví dụ: thử lại tối đa 5 lần, giãn cách tăng dần). Nếu thanh toán thất bại hẳn, workflow tự chạy bước bù trừ (compensation) để hoàn kho — đây là mô hình Saga mà Temporal hỗ trợ rất tự nhiên.
Kết quả: trong đợt sale tiếp theo, khi một node server bị restart giữa chừng, các workflow đang chạy tự khôi phục và tiếp tục đúng từ bước dang dở. Số đơn "kẹt trạng thái" cần đối soát tay giảm từ vài nghìn xuống gần như bằng không.
Bài học: Khi quy trình nghiệp vụ có nhiều bước, nhiều service và bắt buộc không được sai, durable execution của Temporal giúp bạn xóa bỏ phần lớn code xử lý lỗi thủ công và ngủ ngon hơn vào đêm sale.
Ví dụ 2 — Đội data của một ngân hàng số dùng Airflow cho báo cáo hằng ngày
Lấy bối cảnh một ngân hàng số tại Việt Nam — giả định tên "NeoBank" — có đội data engineering khoảng 8 người. Mỗi sáng, ban lãnh đạo cần một dashboard tổng hợp số dư, số giao dịch, tỷ lệ nợ xấu, và các chỉ số rủi ro của ngày hôm trước, sẵn sàng trước 7 giờ sáng.
Để làm ra dashboard đó, mỗi đêm cần chạy một chuỗi việc: kéo dữ liệu giao dịch thô từ core banking, làm sạch và chuẩn hóa, đối chiếu với dữ liệu thẻ, tính các chỉ số, đổ vào data warehouse (ví dụ BigQuery), rồi kích hoạt mô hình tính điểm rủi ro. Tất cả phải chạy đúng thứ tự — không thể tính chỉ số khi dữ liệu chưa làm sạch xong.
Họ dùng Airflow để định nghĩa toàn bộ chuỗi này thành một DAG lập lịch chạy lúc 2 giờ sáng. Mỗi bước là một task với operator tương ứng (operator kéo dữ liệu, operator chạy SQL trên BigQuery, operator gọi job dbt). Nếu bước "kéo dữ liệu core banking" lỗi vì hệ thống nguồn bảo trì, Airflow tự retry 3 lần, và nếu vẫn lỗi thì gửi cảnh báo qua Slack cho kỹ sư trực. Trên UI, đội data nhìn thấy ngay task nào đỏ, mở log ra xem nguyên nhân, và bấm chạy lại đúng task đó mà không phải chạy lại cả pipeline.
Bài học: Với các pipeline dữ liệu chạy theo lịch, có nhiều bước phụ thuộc nhau, Airflow cho bạn khả năng lập lịch + giám sát + chạy lại có chọn lọc mà nếu tự viết bằng cron job thì sẽ thành một mớ hỗn loạn không ai dám đụng vào.
Ví dụ 3 — Khi dùng nhầm công cụ
Một startup logistics (giả định tên "GiaoNhanh") ban đầu dùng Airflow để xử lý luồng theo dõi đơn giao hàng real-time: mỗi khi tài xế cập nhật vị trí, họ kích một DAG để cập nhật trạng thái và gửi thông báo cho khách. Vấn đề: Airflow vốn sinh ra cho batch theo lịch, không phải cho hàng nghìn sự kiện nhỏ đến liên tục. Hệ thống nhanh chóng quá tải scheduler, độ trễ thông báo có lúc lên đến vài phút — không chấp nhận được với khách đang chờ shipper.
Họ chuyển phần xử lý sự kiện real-time và quy trình giao hàng dài (từ lúc nhận hàng đến lúc giao thành công, có thể kéo dài cả ngày, qua nhiều trạng thái) sang Temporal, và giữ Airflow cho việc tổng hợp báo cáo vận hành cuối ngày. Đúng người đúng việc.
Bài học: Sai lầm phổ biến nhất không phải là chọn công cụ "dở", mà là dùng công cụ tốt cho sai bài toán. Hỏi trước: đây là quy trình nghiệp vụ có trạng thái và phản ứng theo sự kiện (→ Temporal), hay là job dữ liệu chạy theo lịch (→ Airflow)?
Hướng dẫn từng bước
Dưới đây là khung tư duy để bạn quyết định và triển khai, không lệ thuộc vào một ngôn ngữ cụ thể.
Bước 1 — Phân loại bài toán. Viết ra quy trình bạn muốn tự động hóa và trả lời ba câu: (a) Nó chạy theo lịch hay theo sự kiện? (b) Nó kéo dài bao lâu — vài giây, vài giờ, hay nhiều ngày/tuần? (c) Nó là xử lý dữ liệu hàng loạt hay điều phối nghiệp vụ qua nhiều service? Nếu là batch dữ liệu theo lịch → nghiêng Airflow. Nếu là nghiệp vụ dài, có trạng thái, phản ứng sự kiện → nghiêng Temporal.
Bước 2 — Vẽ ra luồng dưới dạng các bước rời. Liệt kê từng bước, xác định bước nào gọi ra thế giới bên ngoài (API, DB, email) — với Temporal đó sẽ là activity; với Airflow đó là task/operator. Đánh dấu bước nào cần bù trừ nếu thất bại.
Bước 3 — Dựng môi trường thử. Với Temporal: chạy thử bằng temporal server start-dev (server local) rồi viết một workflow đơn giản bằng SDK ngôn ngữ bạn quen (Python/TypeScript/Go). Với Airflow: dùng Docker Compose chính thức để dựng một instance local, rồi bỏ một file DAG Python vào thư mục dags/.
Bước 4 — Viết phiên bản nhỏ nhất chạy được. Với Temporal, viết một workflow gọi 2-3 activity, cố tình throw lỗi ở một activity để quan sát cơ chế retry và replay. Với Airflow, tạo một DAG 3 task nối tiếp, đặt schedule_interval, và xem nó chạy trên UI.
Bước 5 — Thêm độ bền và quan sát. Cấu hình retry policy, timeout cho từng bước. Với Temporal, thử kill server giữa chừng và xem workflow tự khôi phục — đây là khoảnh khắc "aha" giúp bạn thật sự hiểu durable execution. Với Airflow, gắn cảnh báo qua email/Slack khi task fail.
Bước 6 — Đưa lên môi trường thật từng phần. Đừng chuyển cả hệ thống một lúc. Chọn một luồng ít rủi ro, chạy song song với hệ thống cũ, so kết quả, rồi mới mở rộng.
Lỗi thường gặp & mẹo
- Nhầm Temporal với một message queue. Temporal dùng hàng đợi bên trong nhưng nó là orchestrator có trạng thái, không phải Kafka/RabbitMQ. Đừng dùng nó chỉ để truyền message.
- Viết code không deterministic trong workflow Temporal. Đây là lỗi kinh điển: gọi
random(), đọcdatetime.now(), hay gọi thẳng API bên trong workflow function. Replay sẽ ra kết quả khác và Temporal báo lỗi. Quy tắc: mọi thứ "bẩn" và không xác định phải nằm trong activity, không nằm trong workflow. - Dùng Airflow để xử lý real-time. Như ví dụ 3, Airflow là batch. Nếu bạn cần phản ứng từng sự kiện trong vài giây, đó là việc của Temporal hoặc một event-driven system.
- Nhồi logic xử lý dữ liệu nặng trực tiếp vào task Airflow worker. Airflow nên điều phối (gọi Spark, BigQuery, dbt làm việc nặng), không nên tự mình xử lý hàng GB dữ liệu trong process của worker — sẽ làm sập scheduler.
- Quên cấu hình idempotency. Vì cả hai engine đều retry, một activity/task gọi lại lần hai phải an toàn (không trừ tiền hai lần). Luôn thiết kế các bước có thể chạy lại mà không gây hậu quả nhân đôi.
- Mẹo chọn nhanh: Nếu bạn thấy mình đang viết một bảng database để "lưu workflow đang ở bước nào" — đó là dấu hiệu rõ ràng bạn nên dùng Temporal. Nếu bạn thấy mình viết một mớ cron job phụ thuộc lẫn nhau — đó là dấu hiệu nên dùng Airflow.
- Mẹo vận hành: Cả hai đều có UI giám sát mạnh. Hãy tận dụng nó từ ngày đầu — khả năng quan sát (observability) là một trong những lý do lớn nhất để rời bỏ code thủ công.
Bài tập thực hành
- Phân loại: Cho 5 bài toán sau, hãy quyết định nên dùng Temporal hay Airflow và giải thích ngắn gọn lý do: (a) mỗi đêm tổng hợp doanh thu từ 3 nguồn vào kho dữ liệu; (b) quy trình hoàn tiền nhiều bước kéo dài tới 7 ngày; (c) onboarding nhân viên mới qua 12 bước, có chờ phê duyệt của quản lý; (d) đồng bộ dữ liệu khách hàng từ CRM sang data warehouse mỗi 6 giờ; (e) xử lý đơn đặt phòng khách sạn với bước giữ chỗ tạm và hủy nếu không thanh toán trong 15 phút.
- Thiết kế Temporal: Vẽ sơ đồ workflow cho luồng checkout của ví dụ 1 (ShopSEA). Chỉ rõ đâu là workflow, đâu là các activity, bước nào cần compensation, và đặt retry policy hợp lý cho từng activity.
- Thực hành Airflow: Dựng Airflow local bằng Docker Compose, viết một DAG 3 task: task 1 in ra ngày hôm nay, task 2 chờ task 1 rồi tạo một file giả lập "dữ liệu đã làm sạch", task 3 chờ task 2 rồi in thông báo hoàn tất. Đặt lịch chạy hằng ngày và quan sát trên UI.
- Phản tư: Trong hệ thống nơi bạn đang làm (hoặc một hệ thống bạn biết), hãy chỉ ra một quy trình đang được xử lý bằng "code thủ công + bảng trạng thái tự chế". Lập luận xem chuyển nó sang Temporal sẽ xóa bỏ được những đoạn code nào.
Tóm tắt
- Workflow engine cấp doanh nghiệp gánh phần "ống nước" của automation: retry, lưu trạng thái, khôi phục sau crash, timeout — để bạn tập trung vào logic nghiệp vụ.
- Temporal.io là nền tảng orchestration microservices, code-first, với triết lý durable execution: workflow sống sót qua crash và tiếp tục đúng chỗ dừng nhờ event sourcing và deterministic replay. SDK đa ngôn ngữ (Go, Java, TypeScript, Python, .NET, PHP). Hợp với quy trình nghiệp vụ dài, có trạng thái, phản ứng theo sự kiện.
- Apache Airflow là orchestrator cho data pipeline, định nghĩa luồng bằng DAG Python, mạnh về lập lịch (schedule), batch và hệ sinh thái operator cho data engineering. Hợp với báo cáo hằng ngày, đồng bộ data warehouse.
- Nguyên tắc chọn: Airflow điều phối job dữ liệu theo lịch; Temporal điều phối giao dịch nghiệp vụ sống động, dài hạn. Nhiều tổ chức dùng cả hai song song.
- Lỗi chí mạng cần tránh: viết code không deterministic trong workflow Temporal, dùng Airflow cho real-time, và quên idempotency khi engine retry.