Syllabus messaging - workflow
GIAI ĐOẠN 0 - Distributed Systems, Concurrency, Reliability Foundations (Ngày 1–18)
Tuần 1 - Distributed Systems Core
Ngày 1: CAP Theorem & vì sao nó quan trọng với message broker
Mục tiêu: Giải thích được vì sao mọi broker (Kafka, RabbitMQ) đều phải đánh đổi giữa Consistency và Availability khi có Network Partition.
Lý thuyết: Consistency, Availability, Partition Tolerance; ví dụ thực tế CP (Kafka với
min.insync.replicas) vs AP (RabbitMQ classic mirrored queue cũ).Thực hành: Vẽ sơ đồ CAP cho 3 hệ thống bạn từng dùng (kể cả không phải messaging), tự phân loại và giải thích bằng 1 tình huống network partition cụ thể.
Ngày 2: PACELC & Consensus
Mục tiêu: Hiểu PACELC mở rộng CAP thế nào khi không có partition, và consensus giải quyết bài toán gì.
Lý thuyết: PACELC (Else: Latency vs Consistency); Paxos cơ bản, Raft cơ bản (leader election, log replication).
Thực hành: Đọc & tóm tắt Raft paper (phần Leader Election) bằng tay, vẽ lại state diagram Follower → Candidate → Leader.
Ngày 3: Leader Election & Replication
Mục tiêu: Nắm được cơ chế bầu leader và replicate dữ liệu dùng trong Kafka Controller, RabbitMQ Quorum Queue, Temporal.
Lý thuyết: Quorum, majority vote, split-brain, replication log, synchronous vs asynchronous replication.
Thực hành: Cài
etcdlocal (3 node bằng Docker Compose), kill leader, quan sát log bầu lại leader.
Ngày 4: Partitioning & Consistency Models
Mục tiêu: Phân biệt Eventual Consistency và Strong Consistency, hiểu tại sao Kafka partition lại theo key.
Lý thuyết: Sharding/partitioning strategies (hash, range, round-robin); Eventual vs Strong vs Causal consistency.
Thực hành: Viết script Python giả lập 3 node lưu key-value, đồng bộ eventual (delay ngẫu nhiên), quan sát stale read.
Ngày 5: Distributed Transactions
Mục tiêu: Hiểu vì sao 2PC không scale và tại sao messaging system thường tránh distributed transaction cổ điển.
Lý thuyết: Two-Phase Commit, Three-Phase Commit, vấn đề blocking, so sánh với Saga (sẽ học sâu ở Giai đoạn 2).
Thực hành: Đọc DDIA chương "Distributed Transactions" (hoặc tương đương), viết note 1 trang so sánh 2PC vs Saga.
Ngày 6: Ôn tập & Quiz Giai đoạn Distributed Systems
Mục tiêu: Củng cố toàn bộ tuần 1 trước khi sang Concurrency.
Lý thuyết: Tự làm flashcard cho: CAP, PACELC, Raft, Quorum, Partitioning, 2PC.
Thực hành: Tự đặt và trả lời 10 câu hỏi phỏng vấn system design cấp Senior liên quan đến các khái niệm trên (viết ra giấy, không tra cứu).
Tuần 2 - Concurrency
Ngày 7: Thread vs Process
Mục tiêu: Hiểu sự khác biệt về memory model và context-switching cost giữa thread và process - nền tảng để hiểu Consumer/Worker sau này.
Lý thuyết: Address space, GIL (Python), context switch, khi nào CPU-bound cần process, I/O-bound cần thread.
Thực hành: Viết benchmark Python so sánh
threadingvsmultiprocessingcho 1 tác vụ CPU-bound (tính số nguyên tố) và 1 tác vụ I/O-bound (gọi HTTP).
Ngày 8: Async I/O & Event Loop
Mục tiêu: Hiểu event loop hoạt động thế nào - cơ chế lõi của mọi broker hiệu năng cao (Erlang VM, Kafka network layer).
Lý thuyết: Blocking vs Non-blocking I/O, callback, event loop, coroutine.
Thực hành: Viết 1 TCP echo server bằng
asyncio(Python), đo throughput với 1000 kết nối đồng thời.
Ngày 9: Actor Model
Mục tiêu: Hiểu Actor Model - nền tảng thiết kế của RabbitMQ (Erlang) và Kafka Streams state store.
Lý thuyết: Actor = state + mailbox + behavior; message passing thay vì shared memory; supervision tree.
Thực hành: Cài Elixir/Erlang, viết 1 actor đơn giản dùng
GenServerxử lý message tuần tự.
Ngày 10: Thực hành Concurrency Python (1/2)
Mục tiêu: Thành thạo
threadingvàmultiprocessingở mức áp dụng thực tế.Lý thuyết: Lock, Queue,
ThreadPoolExecutor,ProcessPoolExecutor, race condition, deadlock.Thực hành: Build 1 worker pool xử lý job từ
queue.Queue, cố tình tạo deadlock rồi fix bằng lock ordering.
Ngày 11: Thực hành Concurrency Python (2/2) - asyncio
Mục tiêu: Dùng thành thạo
asynciocho pipeline xử lý message.Lý thuyết:
asyncio.Queue,gather,Semaphore, cancellation, timeout.Thực hành: Build 1 producer-consumer pipeline bất đồng bộ với
asyncio.Queue, giới hạn concurrency bằngSemaphore.
Ngày 12: Goroutine & Channel (Go)
Mục tiêu: Hiểu concurrency model của Go - dùng nhiều trong client library Kafka/NATS hiệu năng cao.
Lý thuyết: Goroutine (green thread), channel (buffered/unbuffered),
select, CSP (Communicating Sequential Processes).Thực hành: Viết worker pool bằng Go dùng channel làm queue nội bộ, so sánh code với bản Python ngày 10.
Tuần 3 - Reliability
Ngày 13: Delivery Semantics
Mục tiêu: Phân biệt rạch ròi At-most-once, At-least-once, Exactly-once - khái niệm sẽ gặp lại xuyên suốt toàn bộ lộ trình.
Lý thuyết: Trade-off giữa 3 loại; tại sao "Exactly-once" thực chất là "Effectively-once" (idempotent + at-least-once).
Thực hành: Viết 3 phiên bản demo (mất message/duplicate message/dedupe bằng idempotency key) bằng 1 script Python đơn giản.
Ngày 14: Retry & Exponential Backoff
Mục tiêu: Thiết kế retry strategy đúng cách, tránh "retry storm".
Lý thuyết: Exponential backoff, jitter, max retry, retry budget.
Thực hành: Viết decorator Python
@retry_with_backoffáp dụng cho 1 hàm gọi API giả lập fail ngẫu nhiên.
Ngày 15: Dead Letter Queue, Poison Message, Circuit Breaker, Bulkhead
Mục tiêu: Hiểu các pattern cô lập lỗi để tránh 1 message xấu làm sập cả hệ thống.
Lý thuyết: DLQ routing, poison message detection, Circuit Breaker (Closed/Open/Half-Open), Bulkhead isolation.
Thực hành: Implement Circuit Breaker đơn giản bằng Python (state machine 3 trạng thái) bọc quanh 1 call hay fail.
Ngày 16: Idempotency
Mục tiêu: Thiết kế API/consumer idempotent - kỹ năng bắt buộc cho at-least-once delivery.
Lý thuyết: Idempotency key, dedupe table, natural idempotency (upsert) vs enforced idempotency.
Thực hành: Viết consumer giả lập nhận message trùng lặp, dùng bảng
processed_message_idtrong SQLite để dedupe.
Ngày 17–18: Mini Project - Retry + DLQ Simulator
Mục tiêu: Ghép toàn bộ kiến thức Reliability tuần 3 thành 1 hệ thống nhỏ hoàn chỉnh.
Lý thuyết: Ôn lại retry/backoff/DLQ/idempotency/circuit breaker như 1 pipeline thống nhất.
Thực hành theo ngày:
Ngày 17: Build in-memory queue + worker xử lý job, job fail ngẫu nhiên 30%, áp dụng retry + backoff.
Ngày 18: Thêm DLQ cho job fail quá max retry, thêm dedupe table, viết report kết quả (tỉ lệ thành công, độ trễ trung bình).
GIAI ĐOẠN 0.5 - Networking & OS cho Message Broker (Ngày 19–24)
Ngày 19: TCP Fundamentals cho Broker
Mục tiêu: Hiểu các tham số TCP ảnh hưởng trực tiếp đến throughput/latency của Kafka/RabbitMQ.
Lý thuyết: TCP handshake, backlog queue, Nagle's algorithm (
TCP_NODELAY), keepalive, window scaling.Thực hành: Dùng
tcpdump/Wireshark bắt gói tin khi 1 client Python kết nối tới broker giả lập, quan sát handshake và ảnh hưởng củaTCP_NODELAY.
Ngày 20: I/O Multiplexing - epoll/kqueue
Mục tiêu: Hiểu vì sao Kafka/RabbitMQ xử lý hàng chục nghìn kết nối đồng thời mà không cần hàng nghìn thread.
Lý thuyết: select vs poll vs epoll (Linux) vs kqueue (BSD); reactor pattern.
Thực hành: Viết 1 server dùng
selectorsmodule (Python) xử lý nhiều kết nối trên 1 thread, benchmark với 500 client.
Ngày 21: Page Cache, mmap, Zero-Copy
Mục tiêu: Hiểu vì sao Kafka nhanh nhờ tận dụng OS page cache và
sendfile()- kiến thức lõi để hiểu Kafka Storage sau này.Lý thuyết: Page cache,
mmap, zero-copy transfer (sendfile), tại sao Kafka không tự quản memory cache riêng.Thực hành: Viết benchmark so sánh copy file qua user-space (
read/write) vssendfile()trong Python/C, đo throughput.
Ngày 22: Disk I/O - Sequential vs Random, fsync
Mục tiêu: Hiểu tại sao Kafka log là append-only và tại sao điều đó nhanh hơn nhiều so với random write.
Lý thuyết: Sequential write vs random write trên HDD/SSD,
fsynccost, write-ahead log pattern.Thực hành: Dùng
fiobenchmark sequential write vs random write trên máy/VM của bạn, ghi lại số liệu IOPS/throughput.
Ngày 23: Memory Management & GC - JVM cho Kafka/ActiveMQ
Mục tiêu: Hiểu ảnh hưởng của GC pause tới latency broker chạy trên JVM.
Lý thuyết: Heap vs off-heap, G1GC cơ bản, GC pause và tail latency, vì sao Kafka broker khuyến nghị heap nhỏ (tận dụng page cache thay vì heap).
Thực hành: Chạy 1 ứng dụng Java đơn giản, bật GC logging, quan sát pause time với các JVM flag khác nhau.
Ngày 24: Lab tổng hợp - Benchmark hạ tầng
Mục tiêu: Có baseline số liệu hạ tầng trước khi học broker cụ thể.
Lý thuyết: Ôn lại toàn bộ tuần: network, page cache, disk, memory.
Thực hành: Trên 1 VM (Compute Engine hoặc tương đương), chạy bộ benchmark
iperf3(network) +fio(disk) +sysbench(CPU/memory), viết báo cáo baseline capacity của máy.
GIAI ĐOẠN 1 - Queue & Messaging Fundamentals (Ngày 25–42)
Ngày 25: Point-to-Point vs Publish-Subscribe
Mục tiêu: Phân biệt rõ 2 mô hình giao tiếp nền tảng của mọi message broker.
Lý thuyết: Point-to-Point (Producer → Queue → 1 Consumer); Pub/Sub (Producer → Topic → N Consumer); khi nào dùng loại nào.
Thực hành: Vẽ sơ đồ kiến trúc cho 1 hệ thống thông báo (notification) dùng cả 2 mô hình cho 2 use case khác nhau trong cùng hệ thống.
Ngày 26: Fanout, Routing, Topic Exchange
Mục tiêu: Hiểu các chiến lược phân phối message phức tạp hơn point-to-point/pub-sub cơ bản.
Lý thuyết: Fanout (broadcast toàn bộ), Routing (theo key cố định), Topic Exchange (theo pattern wildcard).
Thực hành: Thiết kế (trên giấy) hệ thống log aggregation dùng Fanout, và hệ thống order routing theo region dùng Topic Exchange.
Ngày 27: Priority Queue, Delayed Queue, Scheduled Queue
Mục tiêu: Hiểu các biến thể queue và cách chúng thường được giả lập (vì phần lớn broker không hỗ trợ native).
Lý thuyết: Priority queue (xử lý theo độ ưu tiên), Delayed queue (dùng TTL + DLX pattern), Scheduled queue (cron-like).
Thực hành: Thiết kế cách giả lập Delayed Queue bằng TTL + Dead Letter Exchange (sẽ implement thật ở Giai đoạn 3).
Ngày 28–29: Message Lifecycle
Mục tiêu: Nắm vững toàn bộ vòng đời 1 message từ Producer đến khi bị xoá.
Lý thuyết: Serialize → Persist → Replicate → Consume → Acknowledge → Delete; tại sao thứ tự này quan trọng cho durability guarantee.
Thực hành theo ngày:
Ngày 28: Vẽ sequence diagram chi tiết lifecycle cho cả Kafka và RabbitMQ (dựa trên tài liệu chính thức), so sánh điểm khác biệt.
Ngày 29: Viết 1 broker "toy" cực đơn giản bằng Python (in-memory) implement đủ 6 bước lifecycle trên.
Ngày 30–31: Serialization - JSON
Mục tiêu: Hiểu trade-off của JSON làm message format.
Lý thuyết: Ưu/nhược JSON (human-readable, không có schema, size lớn); JSON Schema để validate.
Thực hành theo ngày:
Ngày 30: Viết JSON Schema cho 1 event "OrderCreated", validate message bằng
jsonschema(Python).Ngày 31: Benchmark size và serialize/deserialize speed của JSON so với raw dict.
Ngày 32–33: Serialization - Avro
Mục tiêu: Hiểu Avro và vì sao nó phổ biến trong hệ Kafka.
Lý thuyết: Avro schema (.avsc), binary encoding, schema-first design.
Thực hành theo ngày:
Ngày 32: Viết Avro schema cho "OrderCreated", serialize/deserialize bằng thư viện
fastavro.Ngày 33: So sánh size Avro vs JSON cho cùng 1 message.
Ngày 34–35: Serialization - Protobuf
Mục tiêu: Hiểu Protobuf, phổ biến nhất cho cả messaging lẫn gRPC (sẽ dùng lại ở Giai đoạn 7.5).
Lý thuyết:
.protofile, code generation, backward/forward compatibility qua field number.Thực hành theo ngày:
Ngày 34: Viết
.protocho "OrderCreated", generate code Python, serialize/deserialize.Ngày 35: Thử thêm 1 field mới, kiểm tra compatibility với consumer cũ.
Ngày 36: MessagePack & Apache Arrow
Mục tiêu: Biết thêm 2 format ít phổ biến hơn nhưng quan trọng trong 1 số hệ thống (MessagePack cho size nhỏ, Arrow cho columnar/analytics).
Lý thuyết: MessagePack = binary JSON; Apache Arrow = columnar in-memory format, dùng nhiều trong data pipeline.
Thực hành: Benchmark size/speed của 4 format đã học (JSON, Avro, Protobuf, MessagePack) trên cùng 1 bộ 10.000 message.
Ngày 37–38: Schema Evolution & Compatibility
Mục tiêu: Hiểu cách thay đổi schema mà không phá vỡ consumer cũ - vấn đề thực tế lớn nhất khi vận hành messaging lâu dài.
Lý thuyết: Backward compatibility, Forward compatibility, Full compatibility; thêm field có default, xoá field, đổi type.
Thực hành theo ngày:
Ngày 37: Với schema Avro ở ngày 32, thử 4 kịch bản thay đổi (thêm field có default, thêm field không default, xoá field, đổi type) và xác định kịch bản nào break compatibility.
Ngày 38: Viết note quy tắc "5 điều nên/không nên khi evolve schema" dựa trên thực nghiệm.
Ngày 39–42: Mini Project - Toy Pub/Sub Broker
Mục tiêu: Tổng hợp toàn bộ Giai đoạn 1 thành 1 broker nhỏ hoàn chỉnh, tự tay hiểu rõ từng bước trước khi học broker thật.
Lý thuyết: Ôn lại queue model, message lifecycle, serialization, schema evolution như 1 hệ thống thống nhất.
Thực hành theo ngày:
Ngày 39: Thiết kế kiến trúc (topic, partition giả lập, in-memory storage).
Ngày 40: Implement Producer API + serialize bằng Protobuf.
Ngày 41: Implement Consumer API (pub/sub, nhiều consumer đọc cùng topic) + ack.
Ngày 42: Thêm delayed queue giả lập bằng TTL, viết test end-to-end, viết README.
GIAI ĐOẠN 2 - Database As Queue (Ngày 43–60)
Ngày 43–44: Queue bằng PostgreSQL - FOR UPDATE SKIP LOCKED
Mục tiêu: Hiểu cách dùng database quan hệ làm queue an toàn dưới tải concurrent.
Lý thuyết: Row-level lock,
SELECT ... FOR UPDATE SKIP LOCKED, tại saoSKIP LOCKEDtránh được blocking giữa nhiều worker.Thực hành theo ngày:
Ngày 43: Tạo bảng
jobstrong Postgres, viết worker Python poll bằngFOR UPDATE SKIP LOCKED.Ngày 44: Chạy 10 worker song song, đo throughput, kiểm tra không có job bị xử lý 2 lần.
Ngày 45: Lock, Contention, Starvation, Throughput Limit
Mục tiêu: Hiểu giới hạn thực tế của việc dùng DB làm queue.
Lý thuyết: Lock contention khi table lớn, index bloat, vacuum overhead, throughput trần so với broker chuyên dụng.
Thực hành: Benchmark throughput của Postgres-queue ở các mức: 1, 10, 50 worker; vẽ biểu đồ throughput vs số worker, xác định điểm bão hoà.
Ngày 46–47: Outbox Pattern
Mục tiêu: Giải quyết bài toán "dual write" (ghi DB + publish message) một cách an toàn.
Lý thuyết: Outbox table trong cùng transaction với business data; luồng Service → DB Transaction → Outbox Table → CDC → Kafka.
Thực hành theo ngày:
Ngày 46: Thiết kế bảng
outboxcho service "Order", viết transaction ghi đồng thờiordersvàoutbox.Ngày 47: Viết 1 poller đơn giản đọc
outboxvà giả lập publish ra "Kafka" (log ra console), đánh dấu đã publish.
Ngày 48–50: Change Data Capture (CDC)
Mục tiêu: Hiểu cơ chế CDC thật (không cần poller thủ công) - nền tảng cho Debezium sẽ dùng xuyên suốt lộ trình.
Lý thuyết: WAL (Write-Ahead Log) của Postgres, Binlog của MySQL, LSN (Log Sequence Number), Offset tracking.
Thực hành theo ngày:
Ngày 48: Bật
wal_level = logicaltrên Postgres, tạo replication slot, quan sát WAL thay đổi khi insert/update.Ngày 49: Cài Debezium (Docker Compose) kết nối Postgres, xem CDC event JSON sinh ra khi insert vào bảng
orders.Ngày 50: So sánh Outbox Poller (ngày 47) vs Debezium CDC (ngày 49): độ trễ, độ phức tạp vận hành, tác động lên DB.
Ngày 51: Inbox Pattern
Mục tiêu: Giải quyết bài toán dedupe ở phía consumer một cách hệ thống (mở rộng từ idempotency ngày 16).
Lý thuyết: Inbox table lưu message đã xử lý, kết hợp với Outbox tạo thành "Transactional Messaging" đầy đủ 2 chiều.
Thực hành: Thêm bảng
inboxvào consumer viết ở ngày 47, đảm bảo consumer xử lý message trùng không gây side-effect kép.
Ngày 52–53: Transactional Messaging
Mục tiêu: Ghép Outbox + Inbox thành pattern hoàn chỉnh đảm bảo consistency giữa DB và message.
Lý thuyết: Tại sao Transactional Messaging thay thế được 2PC trong hệ microservices hiện đại.
Thực hành theo ngày:
Ngày 52: Vẽ sequence diagram đầy đủ Service A (outbox) → CDC → Broker → Service B (inbox).
Ngày 53: Implement end-to-end 2 service giả lập (A ghi order, B nhận và ghi inventory) dùng Outbox + Inbox.
Ngày 54–56: Saga Pattern
Mục tiêu: Giải quyết distributed transaction nghiệp vụ (nhiều service, cần rollback) mà không dùng 2PC.
Lý thuyết: Saga Orchestration (1 orchestrator điều phối) vs Saga Choreography (các service tự phản ứng theo event); Compensating Transaction.
Thực hành theo ngày:
Ngày 54: Thiết kế Saga cho luồng "Đặt vé máy bay" (Book Flight → Charge Payment → Reserve Seat), xác định compensating action cho từng bước.
Ngày 55: Implement bản Choreography (3 service giả lập giao tiếp qua event, tự rollback khi fail).
Ngày 56: Implement bản Orchestration (1 orchestrator gọi tuần tự, tự trigger compensation khi fail) - so sánh độ phức tạp code với bản Choreography.
Ngày 57–60: Mini Project - Postgres Queue + Worker Pool + Retry + DLQ
Mục tiêu: Tổng hợp toàn bộ Giai đoạn 2 thành 1 hệ thống queue chạy trên Postgres hoàn chỉnh, production-ready ở quy mô nhỏ.
Lý thuyết: Ôn lại
SKIP LOCKED, Outbox, Inbox, Retry/DLQ (từ Giai đoạn 0).Thực hành theo ngày:
Ngày 57: Thiết kế schema (
jobs,outbox,inbox,dead_letters).Ngày 58: Implement worker pool với
SKIP LOCKED, retry với exponential backoff.Ngày 59: Thêm DLQ cho job fail quá max retry, thêm dashboard đơn giản (query SQL) xem trạng thái queue.
Ngày 60: Load test với 100.000 job giả lập, viết báo cáo hiệu năng và giới hạn của giải pháp.
GIAI ĐOẠN 3 - RabbitMQ (Ngày 61–84)
Tuần 1 - AMQP Protocol & Exchange
Ngày 61–62: AMQP Protocol Cơ Bản
Mục tiêu: Hiểu giao thức tầng dưới mà RabbitMQ implement, không chỉ dùng API mà hiểu "vì sao".
Lý thuyết: Frame, Channel (multiplexing trên 1 connection), Connection lifecycle.
Thực hành theo ngày:
Ngày 61: Cài RabbitMQ (Docker), dùng
pika(Python) tạo connection + channel, quan sát AMQP frame bằng Wireshark.Ngày 62: Đọc AMQP 0-9-1 spec phần Connection/Channel, tóm tắt state machine của Channel.
Ngày 63: Exchange, Queue, Binding, Routing Key
Mục tiêu: Nắm vững 4 khái niệm lõi cấu thành mọi topology RabbitMQ.
Lý thuyết: Exchange nhận message từ producer, Binding nối Exchange với Queue theo Routing Key, Queue lưu và phục vụ consumer.
Thực hành: Vẽ topology cho hệ thống "Order Processing" gồm 3 exchange, 5 queue, đầy đủ binding.
Ngày 64–65: Exchange - Direct, Topic, Fanout, Headers
Mục tiêu: Thành thạo 4 loại exchange và biết chọn đúng loại cho từng use case.
Lý thuyết: Direct (exact match routing key), Topic (wildcard
*/#), Fanout (broadcast, bỏ qua routing key), Headers (match theo header thay vì routing key).Thực hành theo ngày:
Ngày 64: Implement Direct Exchange + Fanout Exchange bằng
pika, test với nhiều consumer.Ngày 65: Implement Topic Exchange với routing key dạng
order.us.priorityvà test wildcard bindingorder.*.priorityvsorder.#.
Tuần 2 - Reliability & HA
Ngày 66–67: Reliability - Publisher Confirm, Ack, Nack, Requeue, Prefetch
Mục tiêu: Đảm bảo message không mất, và consumer không bị "ngợp" khi tải cao.
Lý thuyết: Publisher Confirm (đảm bảo broker nhận message), Consumer Ack/Nack,
basic.qosprefetch count, requeue on nack.Thực hành theo ngày:
Ngày 66: Bật Publisher Confirm, viết test kill broker giữa chừng, kiểm tra publisher phát hiện được message chưa confirm.
Ngày 67: Set prefetch = 1 vs prefetch = 100, benchmark throughput và độ công bằng (fairness) giữa các consumer.
Ngày 68–69: High Availability - Classic, Quorum, Stream Queue
Mục tiêu: Chọn đúng loại queue cho yêu cầu durability/HA khác nhau.
Lý thuyết: Classic Mirrored Queue (deprecated dần), Quorum Queue (Raft-based, khuyến nghị hiện tại), Stream Queue (append-only log, giống Kafka).
Thực hành theo ngày:
Ngày 68: Setup RabbitMQ cluster 3 node (Docker Compose), tạo Quorum Queue, kill 1 node, kiểm tra queue vẫn hoạt động.
Ngày 69: Tạo Stream Queue, so sánh use case với Quorum Queue (replay message vs xoá sau khi ack).
Tuần 3 -
Ngày 70–72: Erlang Actor Model, Mnesia, Queue Storage, Replication
Mục tiêu: Hiểu vì sao RabbitMQ được xây trên Erlang/OTP và điều đó ảnh hưởng gì đến hành vi vận hành.
Lý thuyết: Mỗi Queue là 1 Erlang process (actor); Mnesia lưu metadata; cơ chế replicate giữa các node trong cluster.
Thực hành theo ngày:
Ngày 70: Đọc tài liệu RabbitMQ, vẽ sơ đồ 1 message đi qua Erlang process nào từ lúc publish đến lúc consume.
Ngày 71: Dùng
rabbitmqctlinspect Erlang process của 1 queue cụ thể, quan sát memory/message count.Ngày 72: Thử nghiệm restart 1 node trong cluster, quan sát Mnesia đồng bộ lại metadata thế nào.
Ngày 73: Flow Control, Memory Alarm, Disk Alarm
Mục tiêu: Hiểu cơ chế tự bảo vệ của RabbitMQ khi tài nguyên cạn kiệt - kỹ năng debug production quan trọng.
Lý thuyết:
vm_memory_high_watermark, disk free limit, flow control (block publisher khi quá tải).Thực hành: Cấu hình memory watermark thấp, cố tình publish flood để trigger memory alarm, quan sát publisher bị block, viết note cách phát hiện triệu chứng này trong log thật.
Tuần 4 - Mini Project
Ngày 74–84: Mini Project - Order System với RabbitMQ
Mục tiêu: Xây dựng hệ thống Order Processing hoàn chỉnh, chịu lỗi, có priority/delayed queue - mô phỏng production thực tế.
Lý thuyết: Ôn lại toàn bộ Giai đoạn 3 (exchange, HA, reliability) áp dụng vào 1 hệ thống thống nhất.
Thực hành theo ngày:
Ngày 74–75: Thiết kế kiến trúc (Order Service → Exchange → Payment Queue, Inventory Queue, Notification Queue).
Ngày 76–77: Implement Retry Queue (dùng TTL + Dead Letter Exchange để giả lập exponential backoff).
Ngày 78: Implement Dead Letter Queue thật cho message fail vượt max retry.
Ngày 79–80: Implement Priority Queue (
x-max-priority) cho order VIP.Ngày 81: Implement Delayed Queue (plugin
rabbitmq-delayed-message-exchangehoặc TTL+DLX) cho order cần xử lý sau N phút.Ngày 82: Deploy lên cluster 3 node, cấu hình Quorum Queue cho toàn bộ queue.
Ngày 83: Chaos test - kill từng node lần lượt trong lúc đang có traffic, đo message loss (kỳ vọng = 0).
Ngày 84: Viết báo cáo kiến trúc + runbook vận hành (cách debug khi queue đầy, khi node down).
GIAI ĐOẠN 4 - ActiveMQ & JMS (Ngày 85–96)
Ngày 85–86: JMS - Queue, Topic, Message Selector
Mục tiêu: Hiểu chuẩn JMS (Java Message Service) - vẫn phổ biến trong hệ thống enterprise/ngân hàng.
Lý thuyết: JMS Queue (point-to-point) vs Topic (pub/sub); Message Selector (SQL-like filter trên message header).
Thực hành theo ngày:
Ngày 85: Cài ActiveMQ Artemis (Docker), viết producer/consumer Java cơ bản dùng JMS API.
Ngày 86: Dùng Message Selector lọc message theo header (vd:
priority > 5), test với nhiều consumer khác selector.
Ngày 87: Transaction & Acknowledgement Modes
Mục tiêu: Hiểu các mode ack trong JMS và ảnh hưởng tới delivery guarantee.
Lý thuyết:
AUTO_ACKNOWLEDGE,CLIENT_ACKNOWLEDGE,DUPS_OK_ACKNOWLEDGE, Session Transacted.Thực hành: Test 4 mode trên, cố tình crash consumer giữa chừng, quan sát message có bị mất/duplicate không.
Ngày 88–90: ActiveMQ Artemis - Paging, Journal
Mục tiêu: Hiểu cách Artemis lưu trữ message trên disk, khác gì so với Kafka log-based storage.
Lý thuyết: Journal (append-only file cho durability), Paging (khi queue vượt quá memory limit thì page ra disk).
Thực hành theo ngày:
Ngày 88: Đọc tài liệu Artemis Journal, vẽ sơ đồ ghi/đọc message qua Journal.
Ngày 89: Cấu hình paging threshold thấp, publish flood để trigger paging, quan sát log và hiệu năng giảm.
Ngày 90: So sánh Journal (Artemis) vs Log Segment (Kafka, sẽ học sâu ở Giai đoạn 5) - viết note khác biệt thiết kế.
Ngày 91–92: Cluster, Bridge, Federation
Mục tiêu: Hiểu cách kết nối nhiều broker ActiveMQ với nhau - quan trọng cho kiến trúc multi-datacenter.
Lý thuyết: Cluster (chia tải giữa các broker cùng cấp), Bridge (kết nối point-to-point giữa 2 broker), Federation (đồng bộ topic giữa các cluster).
Thực hành theo ngày:
Ngày 91: Setup 2 broker Artemis, cấu hình cluster, test message được load-balance giữa 2 broker.
Ngày 92: Cấu hình Bridge giữa 2 broker ở 2 "region" giả lập, test message forward.
Ngày 93–94: Kafka khác JMS ở đâu
Mục tiêu: Có khả năng giải thích rành mạch trong phỏng vấn/thiết kế: khi nào chọn JMS broker, khi nào chọn Kafka.
Lý thuyết: JMS = message-oriented, xoá sau khi consume, hỗ trợ transaction phức tạp; Kafka = log-oriented, replay được, throughput cao hơn nhưng model đơn giản hơn.
Thực hành theo ngày:
Ngày 93: Viết bảng so sánh chi tiết (throughput, durability, replay, transaction, ecosystem) giữa JMS/ActiveMQ và Kafka.
Ngày 94: Chọn 3 use case thực tế (core banking, event streaming analytics, order processing) và giải thích chọn broker nào, vì sao.
Ngày 95–96: Mini Lab Tổng Hợp
Mục tiêu: Củng cố kỹ năng thực chiến với JMS trước khi chuyển sang Kafka.
Lý thuyết: Ôn lại toàn bộ Giai đoạn 4.
Thực hành theo ngày:
Ngày 95: Build 1 service Java đơn giản: nhận order qua JMS Queue, publish notification qua JMS Topic.
Ngày 96: Viết test đo throughput Artemis với các cấu hình Journal khác nhau (sync vs async), tổng kết bằng báo cáo ngắn.
GIAI ĐOẠN 5 - Kafka (Ngày 97–150)
Tuần 1 (97–102) - Kafka Architecture
Ngày 97: Broker, Topic, Partition
Mục tiêu: Nắm vững 3 khái niệm nền tảng nhất của Kafka.
Lý thuyết: Broker (1 node trong cluster), Topic (đơn vị logic), Partition (đơn vị song song hoá + thứ tự message).
Thực hành: Cài Kafka (KRaft mode, Docker Compose), tạo topic với 3 partition, publish message với các key khác nhau, quan sát message rơi vào partition nào (
kafka-console-producer, xem quakafka-console-consumer --partition).
Ngày 98: Replica & ISR
Mục tiêu: Hiểu cơ chế nhân bản dữ liệu và "In-Sync Replica set" đảm bảo durability.
Lý thuyết: Replication Factor, Leader replica, Follower replica, ISR (In-Sync Replica).
Thực hành: Tạo topic replication factor = 3 trên cluster 3 broker, kill 1 broker, quan sát ISR co lại và leader mới được bầu.
Ngày 99: Controller
Mục tiêu: Hiểu vai trò của Controller trong việc quản lý metadata cluster.
Lý thuyết: Controller chịu trách nhiệm bầu leader cho partition, quản lý broker join/leave.
Thực hành: Dùng
kafka-metadata-shell(KRaft) hoặc log controller để quan sát quá trình bầu leader khi 1 broker down.
Ngày 100–101: So sánh với các mô hình đã học
Mục tiêu: Đặt Kafka vào bức tranh tổng thể so với RabbitMQ/ActiveMQ đã học.
Lý thuyết: Kafka = distributed commit log, không phải traditional queue; partition = đơn vị song song hoá giống Postgres table partition (Giai đoạn 2).
Thực hành theo ngày:
Ngày 100: Viết lại topology "Order System" (đã làm ở Giai đoạn 3 với RabbitMQ) bằng Kafka, so sánh khác biệt thiết kế.
Ngày 101: Benchmark throughput publish của Kafka vs RabbitMQ (đã build ở Giai đoạn 3) trên cùng 1 workload.
Ngày 102: Ôn tập Kiến trúc
Mục tiêu: Củng cố tuần 1 trước khi vào Storage.
Lý thuyết: Tự vẽ lại toàn bộ kiến trúc Kafka cluster (Broker/Topic/Partition/Replica/ISR/Controller) không nhìn tài liệu.
Thực hành: Tự đặt 10 câu hỏi debug production kiểu "Partition mất leader, ISR chỉ còn 1 replica - bạn làm gì?" và trả lời.
Tuần 2 (103–108) - Storage
Ngày 103: Log Segment
Mục tiêu: Hiểu cách Kafka lưu message trên disk dưới dạng file.
Lý thuyết: Mỗi partition = nhiều segment file, segment mới được tạo khi đạt size/time threshold.
Thực hành: Publish nhiều message vào 1 topic, dùng
ls/kafka-dump-logxem file.logsinh ra trên disk broker.
Ngày 104: Offset Index & Time Index
Mục tiêu: Hiểu cách Kafka tìm nhanh 1 message theo offset hoặc timestamp mà không cần scan toàn bộ log.
Lý thuyết: File
.index(offset → vị trí byte), file.timeindex(timestamp → offset).Thực hành: Dùng
kafka-dump-log --print-data-logphân tích file index, thửkafka-console-consumer --offsetvới 1 offset cụ thể và đo tốc độ seek.
Ngày 105–106: Compaction
Mục tiêu: Hiểu Log Compaction - cơ chế đặc biệt của Kafka để giữ "trạng thái mới nhất" thay vì toàn bộ lịch sử.
Lý thuyết: Compacted topic (dùng cho changelog/state), tombstone message (xoá bằng value=null), so sánh với Retention theo thời gian.
Thực hành theo ngày:
Ngày 105: Tạo topic với
cleanup.policy=compact, publish nhiều update cho cùng 1 key, trigger compaction, quan sát log chỉ còn giá trị mới nhất.Ngày 106: Test tombstone message (publish value=null), xác nhận key bị xoá sau khi compact.
Ngày 107–108: Retention
Mục tiêu: Hiểu chính sách xoá dữ liệu theo thời gian/size - quản lý storage cost thực tế.
Lý thuyết:
retention.ms,retention.bytes, khác biệt giữa retention và compaction.Thực hành theo ngày:
Ngày 107: Cấu hình
retention.msngắn (vd 1 phút), quan sát segment cũ bị xoá.Ngày 108: Tính toán storage cần thiết cho 1 topic có throughput 1000 msg/s, size trung bình 1KB, retention 7 ngày (bài tập capacity planning sơ bộ - sẽ đào sâu ở Giai đoạn 9.6).
Tuần 3 (109–114) - Producer
Ngày 109: Batching & Compression
Mục tiêu: Hiểu cách producer tối ưu throughput bằng cách gom batch trước khi gửi.
Lý thuyết:
batch.size,linger.ms, compression codec (gzip, snappy, lz4, zstd).Thực hành: Benchmark throughput producer với các giá trị
linger.mskhác nhau (0, 5, 50ms) và các compression codec khác nhau.
Ngày 110: Acks
Mục tiêu: Hiểu trade-off giữa durability và latency qua tham số
acks.Lý thuyết:
acks=0(fire and forget),acks=1(leader only),acks=all(toàn bộ ISR).Thực hành: Đo latency và data-loss risk (bằng cách kill leader giữa chừng) với 3 giá trị acks.
Ngày 111: Retries ở Producer
Mục tiêu: Hiểu cơ chế retry built-in của Kafka producer và rủi ro message ra sai thứ tự.
Lý thuyết:
retries,delivery.timeout.ms,max.in.flight.requests.per.connectionvà ảnh hưởng đến ordering khi retry.Thực hành: Test tình huống retry gây message reorder khi
max.in.flight.requests.per.connection > 1và không bật idempotence.
Ngày 112–113: Idempotent Producer
Mục tiêu: Hiểu cách Kafka tự dedupe ở tầng producer, giải quyết vấn đề ngày 111.
Lý thuyết:
enable.idempotence=true, Producer ID (PID), Sequence Number per partition.Thực hành theo ngày:
Ngày 112: Bật idempotence, lặp lại test ngày 111, xác nhận không còn duplicate/reorder.
Ngày 113: Đọc log broker để quan sát PID và sequence number thực tế qua
kafka-dump-log.
Ngày 114: Transactions ở Producer
Mục tiêu: Hiểu cách Kafka hỗ trợ transaction xuyên nhiều partition/topic (nền tảng cho EOS ở tuần 6).
Lý thuyết: Transactional Producer API (
beginTransaction,commitTransaction,abortTransaction), transaction.id.Thực hành: Viết producer transactional ghi vào 2 topic cùng lúc, test abort transaction và xác nhận consumer (với
isolation.level=read_committed) không thấy dữ liệu abort.
Tuần 4 (115–120) - Consumer
Ngày 115: Consumer Group
Mục tiêu: Hiểu cách Kafka phân phối partition cho các consumer trong cùng group.
Lý thuyết: Consumer Group = đơn vị scale-out của consumer; mỗi partition chỉ được 1 consumer trong group đọc tại 1 thời điểm.
Thực hành: Chạy 3 consumer cùng group đọc 1 topic 6 partition, quan sát phân bổ partition, thêm consumer thứ 4 và quan sát rebalance.
Ngày 116: Offset Commit
Mục tiêu: Hiểu các chiến lược commit offset và ảnh hưởng tới delivery semantics.
Lý thuyết: Auto commit vs manual commit, commit sync vs async, commit trước/sau khi xử lý (ảnh hưởng at-least-once vs at-most-once).
Thực hành: Test 3 kịch bản commit khác nhau, cố tình crash consumer giữa chừng, xác nhận message có bị mất/duplicate không.
Ngày 117–118: Rebalance
Mục tiêu: Hiểu cơ chế rebalance - nguồn gốc phổ biến nhất của latency spike trong production Kafka.
Lý thuyết: Eager Rebalance (stop-the-world, mọi consumer dừng xử lý), nguyên nhân trigger rebalance (consumer join/leave, session timeout).
Thực hành theo ngày:
Ngày 117: Trigger rebalance bằng cách kill 1 consumer, đo "thời gian chết" (không consumer nào xử lý message) trong lúc rebalance.
Ngày 118: Tune
session.timeout.ms,max.poll.interval.msđể giảm rebalance không cần thiết.
Ngày 119: Cooperative Rebalance
Mục tiêu: Hiểu cải tiến giảm downtime khi rebalance.
Lý thuyết: Cooperative Sticky Assignor - chỉ revoke partition cần thiết, không stop-the-world toàn bộ.
Thực hành: Đổi
partition.assignment.strategysangCooperativeStickyAssignor, lặp lại test ngày 117, so sánh thời gian downtime.
Ngày 120: Sticky Assignment
Mục tiêu: Hiểu tại sao giữ nguyên phân bổ partition cũ càng nhiều càng tốt khi rebalance.
Lý thuyết: Sticky Assignor giảm số partition bị di chuyển giữa các consumer khi rebalance, giảm cache invalidation ở downstream (đặc biệt quan trọng với Kafka Streams state store).
Thực hành: Viết báo cáo tổng kết tuần: so sánh 3 assignment strategy (Range, RoundRobin, CooperativeSticky) về số partition bị di chuyển khi thêm/bớt consumer.
Tuần 5 (121–126) - Replication & KRaft
Ngày 121–122: Leader, Follower, HW, LEO
Mục tiêu: Hiểu cơ chế đồng bộ dữ liệu chi tiết giữa leader và follower.
Lý thuyết: LEO (Log End Offset), HW (High Watermark = offset thấp nhất được toàn bộ ISR xác nhận), consumer chỉ đọc được đến HW.
Thực hành theo ngày:
Ngày 121: Vẽ sơ đồ LEO/HW thay đổi qua từng bước khi producer gửi message và follower fetch.
Ngày 122: Dùng
kafka-topics --describevà log broker quan sát HW/LEO thực tế khi có độ trễ replicate.
Ngày 123–124: KRaft - Từ ZooKeeper Sang Metadata Quorum
Mục tiêu: Hiểu kiến trúc mới của Kafka (không còn phụ thuộc ZooKeeper).
Lý thuyết: Vì sao Kafka bỏ ZooKeeper; KRaft dùng Raft consensus riêng cho metadata; Controller Quorum.
Thực hành theo ngày:
Ngày 123: Đọc KIP-500 (tóm tắt), vẽ sơ đồ so sánh kiến trúc cũ (ZooKeeper) vs mới (KRaft).
Ngày 124: Setup cluster KRaft 3-controller, kill controller leader, quan sát bầu lại qua log.
Ngày 125–126: Lab tổng hợp Replication
Mục tiêu: Củng cố hiểu biết về đảm bảo durability của Kafka.
Thực hành theo ngày:
Ngày 125: Thiết kế thí nghiệm "mất bao nhiêu broker thì mất data" với các cấu hình
replication.factorvàmin.insync.replicaskhác nhau.Ngày 126: Chạy thí nghiệm thực tế, ghi lại kết quả, viết khuyến nghị cấu hình cho hệ thống "không được mất dữ liệu tài chính".
Tuần 6 (127–132) - EOS & Kafka Connect
Ngày 127–128: Exactly-Once Semantics (EOS)
Mục tiêu: Hiểu Kafka đạt EOS thế nào khi kết hợp Transactional Producer + Idempotence + Consumer read_committed.
Lý thuyết: Transaction Coordinator, Producer ID, Sequence Number, cách EOS hoạt động end-to-end trong Kafka Streams.
Thực hành theo ngày:
Ngày 127: Vẽ sơ đồ đầy đủ luồng EOS: producer transaction → transaction coordinator → consumer read_committed.
Ngày 128: Viết ứng dụng "consume-process-produce" dùng EOS (transactional), test crash giữa chừng và xác nhận không duplicate ở output topic.
Ngày 129–130: Kafka Connect
Mục tiêu: Hiểu cách tích hợp Kafka với hệ thống bên ngoài mà không cần viết code producer/consumer thủ công.
Lý thuyết: Source Connector (đưa data vào Kafka), Sink Connector (đưa data ra khỏi Kafka), SMT (Single Message Transform).
Thực hành theo ngày:
Ngày 129: Cài Debezium Postgres Source Connector qua Kafka Connect, xác nhận CDC event tự động chảy vào Kafka.
Ngày 130: Cài JDBC Sink Connector đẩy data từ Kafka vào 1 bảng Postgres khác, thêm SMT để mask 1 field nhạy cảm.
Ngày 131–132: Ôn tập & Lab
Mục tiêu: Củng cố EOS và Connect trước khi sang Streams.
Thực hành theo ngày:
Ngày 131: Viết lại Outbox Pattern (Giai đoạn 2) dùng Debezium + Kafka Connect thay vì poller thủ công, so sánh độ phức tạp vận hành.
Ngày 132: Viết báo cáo: khi nào dùng Kafka Connect, khi nào tự viết producer/consumer.
Tuần 7 (133–138) - Schema Registry & Kafka Streams
Ngày 133: Schema Registry
Mục tiêu: Hiểu cách quản lý schema Avro tập trung, tránh incompatible schema phá vỡ hệ thống.
Lý thuyết: Schema Registry lưu version schema theo subject, kiểm tra compatibility khi register schema mới.
Thực hành: Cài Confluent Schema Registry, đăng ký schema Avro cho "OrderCreated" (từ Giai đoạn 1), thử đăng ký 1 schema breaking change và quan sát bị từ chối.
Ngày 134–135: Kafka Streams - State Store & RocksDB
Mục tiêu: Hiểu cách Kafka Streams lưu trạng thái local để xử lý stateful (aggregation, join).
Lý thuyết: State Store backed bởi RocksDB (embedded key-value store), changelog topic để phục hồi state khi crash.
Thực hành theo ngày:
Ngày 134: Viết 1 Kafka Streams app đếm số lượng order theo
customer_iddùngKTable, quan sát state store trên disk.Ngày 135: Kill app giữa chừng, restart, xác nhận state được khôi phục từ changelog topic.
Ngày 136: Windowing
Mục tiêu: Hiểu cách xử lý aggregation theo cửa sổ thời gian.
Lý thuyết: Tumbling Window, Hopping Window, Session Window; Grace Period cho late-arriving event.
Thực hành: Viết Kafka Streams app tính tổng doanh thu theo Tumbling Window 1 phút, test với event đến trễ.
Ngày 137: Join & Aggregation
Mục tiêu: Hiểu cách join 2 stream/table trong Kafka Streams.
Lý thuyết: Stream-Stream Join, Stream-Table Join, KTable-KTable Join; co-partitioning requirement.
Thực hành: Viết app join stream "Order" với table "Customer" (KTable) để enrich thông tin khách hàng vào mỗi order event.
Ngày 138: Ôn tập Kafka Streams
Mục tiêu: Củng cố toàn bộ tuần trước khi đọc source code.
Thực hành: Viết lại toàn bộ pipeline "Event Driven Ecommerce" (sẽ build ở tuần 9) bằng sơ đồ Kafka Streams topology, không code, chỉ thiết kế.
Tuần 8 (139–144) - Đọc Source Code Kafka
Ngày 139–141: Đọc "Kafka: The Definitive Guide" - phần Broker & Controller
Mục tiêu: Hiểu sâu hơn implementation thực tế đằng sau lý thuyết đã học 7 tuần qua.
Lý thuyết: Đọc kỹ chương liên quan đến Broker và Controller trong sách.
Thực hành theo ngày: Mỗi ngày đọc 1 chương, tóm tắt bằng sơ đồ + viết 3 câu hỏi tự đặt ra và tự trả lời bằng cách đọc thêm source code Apache Kafka (module
core).
Ngày 142–144: Đọc Source Code - Consumer Group Coordinator
Mục tiêu: Hiểu implementation thật của rebalance protocol đã học ở tuần 4.
Lý thuyết: Đọc source
GroupCoordinator,PartitionAssignortrong repo Apache Kafka.Thực hành theo ngày: Trace code từ lúc consumer gửi
JoinGroupRequestđến lúc nhận được partition assignment, vẽ lại sequence diagram từ chính source code (không phải từ tài liệu).
Tuần 9 (145–150) - Mini Projects Lớn
Ngày 145–147: Build Event Driven E-commerce
Mục tiêu: Xây dựng hệ thống thương mại điện tử event-driven hoàn chỉnh trên Kafka.
Lý thuyết: Luồng Order → Payment → Inventory → Shipping → Notification, mỗi service là 1 consumer group riêng.
Thực hành theo ngày:
Ngày 145: Thiết kế topic (bao nhiêu topic, bao nhiêu partition, key là gì để đảm bảo ordering theo order_id).
Ngày 146: Implement 5 service (Order, Payment, Inventory, Shipping, Notification) dùng Kafka Streams hoặc consumer thường.
Ngày 147: Test end-to-end, thêm EOS cho luồng Payment → Inventory (2 bước phải atomic).
Ngày 148–150: Build CDC Pipeline - Postgres → Debezium → Kafka → ClickHouse
Mục tiêu: Xây dựng pipeline phân tích dữ liệu real-time từ OLTP sang OLAP.
Lý thuyết: CDC pipeline pattern, ClickHouse Kafka Engine để consume trực tiếp từ Kafka.
Thực hành theo ngày:
Ngày 148: Setup Debezium capture toàn bộ thay đổi trên bảng
orders(Postgres) đẩy vào Kafka.Ngày 149: Cài ClickHouse, tạo table với Kafka Engine consume trực tiếp từ topic CDC.
Ngày 150: Viết query phân tích real-time trên ClickHouse (vd: doanh thu theo giờ), đo end-to-end latency từ lúc insert Postgres đến lúc thấy trong ClickHouse.
GIAI ĐOẠN 5.5 - NATS & Pulsar (Ngày 151–153)
Ngày 151: NATS Core & JetStream
Mục tiêu: Hiểu 1 broker "nhẹ" thiết kế khác triết lý với Kafka/RabbitMQ - quan trọng để biết khi nào KHÔNG cần Kafka.
Lý thuyết: NATS Core (fire-and-forget, cực nhanh, không persistence), JetStream (thêm persistence + at-least-once trên nền NATS Core).
Thực hành: Cài NATS server (Docker) bật JetStream, publish/subscribe cơ bản, so sánh độ trễ với Kafka đã benchmark ở ngày 101.
Ngày 152: Apache Pulsar Architecture
Mục tiêu: Hiểu kiến trúc tách biệt compute/storage - khác biệt lớn nhất so với Kafka.
Lý thuyết: Broker (stateless, xử lý) tách khỏi BookKeeper (storage layer, ledger-based); ưu điểm khi scale (scale broker và storage độc lập) và multi-tenancy built-in.
Thực hành: Đọc kiến trúc Pulsar, vẽ sơ đồ so sánh trực tiếp với kiến trúc Kafka (nơi broker vừa xử lý vừa lưu trữ).
Ngày 153: Lab So Sánh & Decision Matrix
Mục tiêu: Có khả năng chọn đúng broker cho đúng bài toán trong phỏng vấn/thiết kế thực tế - tổng kết toàn bộ Giai đoạn 1–5.5.
Lý thuyết: Tổng hợp Kafka, RabbitMQ, ActiveMQ/JMS, Postgres-queue, NATS, Pulsar.
Thực hành: Xây dựng bảng decision matrix (throughput, latency, ordering guarantee, replay, ops complexity, multi-tenancy, cost) và áp dụng chọn broker cho 5 use case giả định (fintech ledger, IoT telemetry, chat app, ETL analytics, đơn giản CRUD app).
GIAI ĐOẠN 6 - Event Streaming Architecture (Ngày 154–177)
Ngày 154–156: Event Sourcing
Mục tiêu: Hiểu pattern lưu trạng thái bằng chuỗi event thay vì lưu state hiện tại - nền tảng cho nhiều workflow engine ở Giai đoạn 8.
Lý thuyết: Command → Event → State; Event Store; Replay để tái tạo state; Snapshot để tối ưu replay dài.
Thực hành theo ngày:
Ngày 154: Thiết kế Event Sourcing cho "Bank Account" (event:
AccountOpened,MoneyDeposited,MoneyWithdrawn).Ngày 155: Implement bằng Kafka làm Event Store (compacted topic + full history topic).
Ngày 156: Implement Snapshot mechanism, test replay từ snapshot + event sau đó thay vì replay toàn bộ lịch sử.
Ngày 157–159: CQRS
Mục tiêu: Hiểu cách tách biệt write model và read model để tối ưu độc lập.
Lý thuyết: Command Query Responsibility Segregation; Write Model (event sourced) → Projection → Read Model (denormalized, tối ưu query).
Thực hành theo ngày:
Ngày 157: Thiết kế Read Model cho "Bank Account" (số dư hiện tại, lịch sử giao dịch) từ event ở ngày 154–156.
Ngày 158: Implement Projection consumer đọc event từ Kafka, cập nhật Read Model trong Postgres/Redis.
Ngày 159: Test eventual consistency giữa Write Model và Read Model (đo độ trễ projection).
Ngày 160–162: Saga - Orchestration vs Choreography (Ôn tập & Mở rộng)
Mục tiêu: Áp dụng Saga (đã học Giai đoạn 2) trong bối cảnh event streaming quy mô lớn hơn.
Lý thuyết: Ôn lại Saga, mở rộng với Event Sourcing (Saga state cũng được event-source hoá).
Thực hành theo ngày:
Ngày 160: Thiết kế Saga cho luồng "Ecommerce Checkout" gồm 5 bước (đã có ở ngày 145–147), lần này dùng Event Sourcing cho Saga state.
Ngày 161–162: Implement, test đầy đủ happy path và 3 kịch bản fail khác nhau với compensation.
Ngày 163–165: Stream Processing - Ôn tập Kafka Streams & So sánh
Mục tiêu: Củng cố Kafka Streams trong bối cảnh kiến trúc lớn hơn.
Lý thuyết: Ôn lại Kafka Streams topology, DSL vs Processor API.
Thực hành theo ngày:
Ngày 163: Viết lại 1 pipeline đã làm bằng DSL sang Processor API (low-level), so sánh độ linh hoạt.
Ngày 164–165: Thiết kế topology cho bài toán "phát hiện gian lận real-time" (fraud detection) dùng windowing + join.
Ngày 166–168: Apache Flink
Mục tiêu: Biết thêm 1 stream processing engine mạnh hơn Kafka Streams cho bài toán phức tạp (không cần gắn với Kafka).
Lý thuyết: Flink DataStream API, Event Time vs Processing Time, Watermark, State Backend (RocksDB).
Thực hành theo ngày:
Ngày 166: Cài Flink local, viết job đơn giản đọc từ Kafka topic, đếm số event theo window.
Ngày 167: So sánh Watermark/Event Time handling của Flink với Kafka Streams.
Ngày 168: Viết lại bài toán fraud detection (ngày 164–165) bằng Flink, so sánh code/độ phức tạp.
Ngày 169–171: Spark Streaming
Mục tiêu: Biết thêm 1 lựa chọn phổ biến trong hệ sinh thái Data/ML (sẽ liên quan tới Giai đoạn 9).
Lý thuyết: Structured Streaming, micro-batch model (khác với true streaming của Flink/Kafka Streams).
Thực hành theo ngày:
Ngày 169: Cài Spark, viết Structured Streaming job đọc từ Kafka, tính aggregation đơn giản.
Ngày 170: So sánh micro-batch (Spark) vs true streaming (Flink/Kafka Streams): latency, throughput, use case phù hợp.
Ngày 171: Viết báo cáo tổng kết 3 stream processing engine (Kafka Streams, Flink, Spark Streaming) - khi nào chọn cái nào.
Ngày 172–174: Khi nào dùng Kafka/RabbitMQ/Database Queue
Mục tiêu: Tổng hợp toàn bộ kiến thức messaging (Giai đoạn 1–6) thành 1 framework quyết định rõ ràng.
Lý thuyết: Ma trận quyết định dựa trên: throughput, ordering, replay, latency, transaction requirement, team ops maturity.
Thực hành theo ngày:
Ngày 172–173: Viết document "Messaging Decision Framework" đầy đủ, kèm flowchart quyết định.
Ngày 174: Áp dụng framework vào 5 case study thực tế khác (tìm trên blog engineering của các công ty lớn, đọc và đối chiếu quyết định của họ với framework của bạn).
Ngày 175–177: Mock Design Review #1
Mục tiêu: Luyện phản xạ thiết kế hệ thống dưới áp lực thời gian như phỏng vấn Senior/Staff thật.
Lý thuyết: Không có lý thuyết mới - đây là buổi tổng hợp áp dụng.
Thực hành theo ngày:
Ngày 175: Tự đặt đề bài "Thiết kế hệ thống đặt vé xem phim real-time, 10 triệu user, tránh overselling". Thiết kế trên giấy trong 45 phút (giới hạn thời gian).
Ngày 176: Tự phản biện thiết kế của chính mình - liệt kê 5 điểm yếu, 5 câu hỏi follow-up khó mà 1 interviewer sẽ hỏi.
Ngày 177: Viết lại thiết kế hoàn chỉnh (không giới hạn thời gian), so sánh với bản đầu tiên, rút kinh nghiệm.
GIAI ĐOẠN 7 - Workflow Theory (Ngày 178–195)
Ngày 178–179: Finite State Machine & Hierarchical State Machine
Mục tiêu: Nắm nền tảng toán học của mọi workflow engine sẽ học ở Giai đoạn 8.
Lý thuyết: FSM (state, transition, event); HFSM (state lồng nhau, giảm bùng nổ số lượng state).
Thực hành theo ngày:
Ngày 178: Thiết kế FSM cho "Order Status" (Created → Paid → Shipped → Delivered/Cancelled), implement bằng Python (dict-based state machine).
Ngày 179: Thiết kế HFSM cho cùng bài toán khi thêm sub-state (vd: "Shipped" có sub-state "InTransit"/"OutForDelivery"), so sánh độ phức tạp với FSM phẳng.
Ngày 180–181: Directed Acyclic Graph (DAG)
Mục tiêu: Hiểu cấu trúc dữ liệu nền tảng của Airflow, Argo, và phần lớn workflow engine dữ liệu.
Lý thuyết: DAG = node (task) + edge (dependency), topological sort để xác định thứ tự thực thi.
Thực hành theo ngày:
Ngày 180: Implement thuật toán topological sort bằng tay (Python, không dùng thư viện).
Ngày 181: Thiết kế DAG cho pipeline ETL đơn giản (Extract → Transform → Load, với 2 nhánh Transform song song), vẽ và code hoá bằng dict.
Ngày 182–183: Workflow Concepts - Task, Activity, Job, Process, Case, Human Task
Mục tiêu: Thống nhất thuật ngữ dùng xuyên suốt các workflow engine khác nhau (mỗi engine gọi khác nhau nhưng bản chất giống nhau).
Lý thuyết: Task/Activity (đơn vị công việc), Job (instance thực thi), Process/Case (1 lần chạy toàn bộ workflow), Human Task (bước cần người phê duyệt).
Thực hành theo ngày:
Ngày 182: Lập bảng ánh xạ thuật ngữ giữa BPMN (Activity), Temporal (Activity), Airflow (Task), Camunda (Task) - nhận diện chúng thực chất là 1 khái niệm.
Ngày 183: Thiết kế workflow "Duyệt vay ngân hàng" có Human Task (nhân viên duyệt hồ sơ), vẽ sơ đồ.
Ngày 184–186: Orchestration vs Choreography (Đào sâu)
Mục tiêu: Nắm cực kỳ chắc phân biệt này - nền tảng chọn kiến trúc cho Giai đoạn 8.
Lý thuyết: Orchestration (1 "nhạc trưởng" điều phối, dễ quan sát/debug nhưng single point of coordination), Choreography (các service tự phản ứng theo event, loose coupling nhưng khó trace).
Thực hành theo ngày:
Ngày 184: Liệt kê 5 ưu, 5 nhược của mỗi mô hình dựa trên kinh nghiệm thực tế từ Giai đoạn 2 (Saga) và Giai đoạn 6.
Ngày 185: Vẽ lại workflow "Duyệt vay ngân hàng" (ngày 183) theo cả 2 mô hình.
Ngày 186: Viết note quyết định: đội nhóm nhỏ nên chọn mô hình nào, đội nhóm lớn/nhiều team nên chọn mô hình nào - vì sao.
Ngày 187–188: Business Process Management (BPM)
Mục tiêu: Hiểu BPM như 1 lĩnh vực rộng hơn workflow engine kỹ thuật - góc nhìn từ business.
Lý thuyết: BPM lifecycle (Design → Model → Execute → Monitor → Optimize); vai trò của Business Analyst trong việc mô hình hoá quy trình.
Thực hành: Chọn 1 quy trình doanh nghiệp thực tế (vd: quy trình onboarding nhân viên mới), áp dụng BPM lifecycle để phân tích và đề xuất cải tiến.
Ngày 189–192: BPMN 2.0
Mục tiêu: Thành thạo ký hiệu chuẩn quốc tế để mô hình hoá workflow - dùng trực tiếp trong Camunda ở Giai đoạn 8.
Lý thuyết: Gateway (Exclusive/Parallel/Inclusive), Event (Start/End/Intermediate), Activity, Subprocess, Timer Event, Message Event, Signal Event, Compensation.
Thực hành theo ngày:
Ngày 189: Học ký hiệu Gateway, vẽ workflow "Duyệt vay" với Exclusive Gateway (rẽ nhánh approve/reject).
Ngày 190: Học Timer Event & Message Event, thêm "nếu sau 3 ngày không duyệt thì escalate" vào workflow.
Ngày 191: Học Subprocess & Compensation, thêm subprocess "Kiểm tra tín dụng" với compensation nếu bước sau fail.
Ngày 192: Vẽ hoàn chỉnh workflow "Duyệt vay" bằng công cụ BPMN modeler (vd: bpmn.io), đủ toàn bộ ký hiệu đã học.
Ngày 193–195: Đọc BPMN Specification & Thực hành Modeling
Mục tiêu: Củng cố kiến thức BPMN bằng cách đọc tài liệu gốc thay vì chỉ qua tutorial.
Lý thuyết: Đọc phần liên quan trong BPMN 2.0 Specification (OMG) về Gateway semantics và Event semantics.
Thực hành theo ngày:
Ngày 193: Đọc spec phần Gateway, làm rõ khác biệt tinh tế giữa Inclusive và Exclusive Gateway (nhiều người hiểu sai).
Ngày 194: Đọc spec phần Event, làm rõ khác biệt Signal Event vs Message Event (broadcast vs point-to-point).
Ngày 195: Model lại 3 workflow thực tế khác nhau (approval, order fulfillment, incident escalation) bằng BPMN, chuẩn bị dùng lại ở Giai đoạn 8 (Camunda).
GIAI ĐOẠN 7.5 - gRPC & Service Mesh (Ngày 196–201)
Ngày 196: gRPC Fundamentals
Mục tiêu: Hiểu giao tiếp đồng bộ hiệu năng cao - thứ luôn tồn tại song song với hệ event-driven trong thực tế.
Lý thuyết: Protobuf (đã học Giai đoạn 1) làm IDL, 4 kiểu RPC (unary, server streaming, client streaming, bidirectional streaming), HTTP/2 làm transport.
Thực hành: Viết 1 service gRPC đơn giản (unary) bằng Python/Go, sau đó thử bidirectional streaming cho 1 chat demo nhỏ.
Ngày 197: gRPC vs REST vs Async Messaging
Mục tiêu: Có framework rõ ràng để chọn kiểu giao tiếp cho từng cặp service.
Lý thuyết: REST (đơn giản, phổ biến, không strict schema), gRPC (nhanh, strict schema, tốt cho internal service), Async Messaging (decoupled, tốt cho event-driven, nhưng thêm độ trễ/độ phức tạp).
Thực hành: Viết bảng quyết định: với kiến trúc "Event Driven Ecommerce" đã build (ngày 145–147), xác định cặp service nào nên đổi sang gRPC (vd: real-time inventory check) và giải thích vì sao.
Ngày 198: Service Mesh Cơ Bản
Mục tiêu: Hiểu khái niệm sidecar proxy - hạ tầng giao tiếp thường thấy trong hệ microservice lớn.
Lý thuyết: Sidecar pattern, Envoy proxy cơ bản, Istio kiến trúc tổng quan (control plane vs data plane).
Thực hành: Đọc tài liệu Istio/Envoy, vẽ sơ đồ traffic đi qua sidecar giữa 2 service.
Ngày 199: mTLS & Observability trong Mesh
Mục tiêu: Hiểu service mesh giải quyết vấn đề bảo mật và quan sát ở tầng hạ tầng, không cần sửa code từng service.
Lý thuyết: mTLS tự động giữa các service, distributed tracing tự động qua sidecar (liên hệ tới OpenTelemetry sẽ học ở Giai đoạn 10).
Thực hành: Cài Istio demo (hoặc đọc kỹ tài liệu nếu hạn chế tài nguyên máy), quan sát Kiali/dashboard traffic giữa các service.
Ngày 200–201: Lab - Hybrid Architecture
Mục tiêu: Ghép sync (gRPC) và async (Kafka) trong cùng 1 kiến trúc thực tế.
Lý thuyết: Ôn lại toàn bộ Giai đoạn 7.5.
Thực hành theo ngày:
Ngày 200: Thêm 1 gRPC service "Inventory Check" (đồng bộ, real-time) vào hệ thống "Event Driven Ecommerce", gọi trực tiếp từ Order Service trước khi publish event.
Ngày 201: Test toàn bộ luồng hybrid, đo latency của phần sync vs độ trễ eventual consistency của phần async, viết note khi nào pattern này hợp lý.
GIAI ĐOẠN 8 - Workflow Engines (Ngày 202–249)
Tuần 1–2 (202–215) - Camunda
Ngày 202–203: Execution Tree & Token
Mục tiêu: Hiểu cơ chế lõi Camunda thực thi 1 BPMN process.
Lý thuyết: Execution Tree (cấu trúc phản ánh trạng thái process instance), Token (đại diện cho "luồng thực thi" di chuyển qua các node BPMN).
Thực hành theo ngày:
Ngày 202: Cài Camunda Platform (Docker), deploy 1 process BPMN đơn giản (đã vẽ ở ngày 195), quan sát Execution Tree qua Cockpit UI.
Ngày 203: Chạy process có Parallel Gateway, quan sát nhiều Token tồn tại đồng thời trong Execution Tree.
Ngày 204: Job Executor
Mục tiêu: Hiểu cơ chế xử lý bất đồng bộ (async continuation, timer) trong Camunda.
Lý thuyết: Job Executor = thread pool polling database tìm job đến hạn (Timer, Async Before/After) - thực chất là 1 dạng "Database as Queue" đã học ở Giai đoạn 2.
Thực hành: Cấu hình Timer Event trong process, quan sát Job Executor pick up job qua log/Cockpit.
Ngày 205–206: Persistence & State Transition
Mục tiêu: Hiểu cách Camunda lưu trạng thái process vào database quan hệ.
Lý thuyết: Schema database Camunda (
ACT_RU_EXECUTION,ACT_RU_TASK...), mỗi state transition = 1 database transaction.Thực hành theo ngày:
Ngày 205: Query trực tiếp vào database Camunda khi process đang chạy, đối chiếu với Execution Tree trên Cockpit.
Ngày 206: Kill Camunda giữa lúc process đang chạy (ở 1 Timer Event), restart, xác nhận process tiếp tục đúng từ state đã lưu.
Ngày 207: BPMN Engine - Tổng hợp
Mục tiêu: Kết nối lý thuyết BPMN (Giai đoạn 7) với engine thật.
Lý thuyết: Ôn lại toàn bộ ký hiệu BPMN đã học, đối chiếu cách Camunda implement từng loại Gateway/Event.
Thực hành: Deploy lại cả 3 workflow đã vẽ ở ngày 195 (approval, order fulfillment, incident escalation) lên Camunda, test end-to-end.
Ngày 208–209: DMN & FEEL
Mục tiêu: Hiểu cách tách business rule ra khỏi process flow.
Lý thuyết: DMN (Decision Model and Notation) - decision table; FEEL (Friendly Enough Expression Language) - ngôn ngữ biểu thức trong DMN.
Thực hành theo ngày:
Ngày 208: Thiết kế DMN decision table cho "Xét duyệt vay" (input: điểm tín dụng, thu nhập → output: approve/reject/manual review).
Ngày 209: Tích hợp DMN vào workflow "Duyệt vay" (Business Rule Task gọi DMN), test với nhiều bộ input.
Ngày 210–211: External Task Pattern
Mục tiêu: Hiểu cách worker bên ngoài (không chạy trong Camunda engine) thực thi task - pattern phổ biến nhất trong production.
Lý thuyết: External Task = engine tạo job chờ, worker bên ngoài poll (
fetch and lock) và complete.Thực hành theo ngày:
Ngày 210: Viết 1 External Task Worker bằng Python, xử lý task "Kiểm tra tín dụng" (gọi API giả lập).
Ngày 211: Test worker bị crash giữa chừng, xác nhận lock timeout và task được worker khác pick up lại (giống consumer rebalance đã học).
Ngày 212–213: Zeebe
Mục tiêu: Biết Zeebe - engine thế hệ mới của Camunda, thiết kế lại hoàn toàn cho cloud-native/horizontal scaling (khác Camunda 7 chạy trên RDBMS).
Lý thuyết: Zeebe dùng event-sourced log (tương tự Kafka) thay vì RDBMS, partition để scale horizontal.
Thực hành theo ngày:
Ngày 212: Cài Zeebe (Docker), deploy lại workflow "Duyệt vay" lên Zeebe.
Ngày 213: So sánh kiến trúc Camunda 7 (RDBMS-based) vs Zeebe (log-based) - liên hệ lại với kiến thức Kafka Storage đã học.
Ngày 214–215: Ôn tập Camunda
Mục tiêu: Củng cố trước khi làm mini project.
Thực hành theo ngày:
Ngày 214: Tự đặt 10 câu hỏi debug production ("Process instance bị stuck ở 1 task, không chạy tiếp - bạn debug thế nào?") và trả lời bằng cách tra Cockpit/database.
Ngày 215: Viết checklist vận hành Camunda production (monitoring job executor, xử lý incident, scaling).
Tuần 3 (216–221) - Mini Project: Loan Approval Workflow
Ngày 216–221: Camunda Mini Project
Mục tiêu: Xây dựng hệ thống Duyệt Vay hoàn chỉnh, dùng toàn bộ kiến thức Camunda đã học.
Lý thuyết: Ôn lại BPMN + DMN + External Task như 1 hệ thống thống nhất.
Thực hành theo ngày:
Ngày 216: Hoàn thiện BPMN process đầy đủ (Start → Kiểm tra tín dụng (External Task) → DMN Decision → Human Task duyệt thủ công nếu cần → Timer escalation → End).
Ngày 217: Implement External Task Worker cho "Kiểm tra tín dụng" (gọi API credit score giả lập).
Ngày 218: Implement Human Task UI đơn giản (dùng Camunda Tasklist hoặc tự build form) cho nhân viên duyệt.
Ngày 219: Tích hợp DMN decision table thật (từ ngày 208).
Ngày 220: Test toàn bộ kịch bản: auto-approve, auto-reject, manual review, escalation timeout.
Ngày 221: Viết báo cáo kiến trúc + demo end-to-end.
Tuần 4–5 (222–235) - Temporal
Ngày 222–223: Workflow Replay & Determinism
Mục tiêu: Hiểu cơ chế cốt lõi và khác biệt lớn nhất của Temporal so với Camunda - Workflow Code phải deterministic vì được "replay" để khôi phục state.
Lý thuyết: Workflow function chạy trên Worker (không phải server), Temporal Server lưu History Event, khi Worker crash/restart, Workflow được "replay" từ History để khôi phục đúng vị trí; do đó code Workflow không được có side-effect ngẫu nhiên (random, thời gian hệ thống, network call trực tiếp).
Thực hành theo ngày:
Ngày 222: Cài Temporal (Docker Compose
temporalitehoặc full stack), viết 1 Workflow "Hello World" bằng Python/Go SDK.Ngày 223: Cố tình viết Workflow non-deterministic (dùng
random()trực tiếp trong Workflow), gây lỗi replay, quan sát Temporal phát hiện và báo lỗi thế nào.
Ngày 224: History Event
Mục tiêu: Hiểu cấu trúc dữ liệu lưu lại toàn bộ lịch sử thực thi 1 Workflow.
Lý thuyết: Mỗi quyết định của Workflow (gọi Activity, sleep, nhận Signal) được ghi thành 1 Event trong History; History chính là "nguồn sự thật" để replay - liên hệ trực tiếp với Event Sourcing đã học ở Giai đoạn 6.
Thực hành: Dùng Temporal Web UI xem History Event của Workflow đã chạy ở ngày 222, đối chiếu từng dòng code với từng Event.
Ngày 225–226: Task Queue & Worker
Mục tiêu: Hiểu cách Temporal phân phối công việc cho Worker - mô hình pull-based giống Kafka Consumer.
Lý thuyết: Task Queue (không phải message queue truyền thống, chỉ là "địa chỉ" để Worker poll), Worker chạy cả Workflow Task và Activity Task.
Thực hành theo ngày:
Ngày 225: Chạy 3 Worker cùng poll 1 Task Queue, quan sát load-balancing giữa các Worker.
Ngày 226: Kill 1 Worker giữa lúc đang xử lý Activity, xác nhận Activity được retry trên Worker khác (visibility timeout tương tự SQS/RabbitMQ).
Ngày 227: Sticky Cache
Mục tiêu: Hiểu tối ưu hiệu năng để tránh replay toàn bộ History mỗi lần có event mới.
Lý thuyết: Sticky Execution - Worker giữ Workflow state trong memory cache, chỉ cần Temporal Server gửi incremental event thay vì toàn bộ History.
Thực hành: Đọc metric Temporal Web UI về Sticky Cache hit rate, thử nghiệm khi cache miss (restart Worker) so với cache hit.
Ngày 228–229: Signal, Query, Update API
Mục tiêu: Nắm vững 3 cách tương tác với Workflow đang chạy - kỹ năng thực chiến quan trọng nhất khi build ứng dụng thật trên Temporal.
Lý thuyết: Signal (gửi dữ liệu bất đồng bộ vào Workflow đang chạy, không trả kết quả ngay), Query (đọc state hiện tại của Workflow, không làm thay đổi state), Update (kết hợp Signal + trả kết quả đồng bộ, mới hơn 2 API kia).
Thực hành theo ngày:
Ngày 228: Viết Workflow "Order" nhận Signal "CancelOrder" giữa chừng, xử lý logic huỷ đơn.
Ngày 229: Thêm Query để FE có thể hỏi "trạng thái hiện tại của order" bất kỳ lúc nào, thêm Update để "đổi địa chỉ giao hàng" và trả kết quả ngay có thành công hay không.
Ngày 230–231: Retry Policy & Timeout trong Temporal
Mục tiêu: Hiểu Temporal có retry/timeout built-in mạnh hơn nhiều so với tự viết tay (Giai đoạn 0).
Lý thuyết:
RetryPolicy(backoff coefficient, max attempts),StartToCloseTimeout,ScheduleToCloseTimeout,HeartbeatTimeoutcho Activity chạy lâu.Thực hành theo ngày:
Ngày 230: Cấu hình RetryPolicy cho 1 Activity gọi API hay fail, test các loại timeout.
Ngày 231: Implement Activity chạy lâu (vd: xử lý file lớn) với Heartbeat để Temporal biết Activity vẫn "sống".
Ngày 232–233: Child Workflow & Continue-As-New
Mục tiêu: Hiểu cách xử lý workflow phức tạp/dài hạn mà không làm History phình to vô hạn.
Lý thuyết: Child Workflow (tách 1 phần logic thành workflow con, có thể chạy trên Worker khác), Continue-As-New (workflow tự "làm mới" History khi chạy quá lâu, vd workflow chạy vô hạn kiểu subscription).
Thực hành theo ngày:
Ngày 232: Tách 1 phần Workflow "Order" (ngày 228) thành Child Workflow "PaymentProcessing".
Ngày 233: Viết 1 Workflow vô hạn (vd: theo dõi subscription hàng tháng) dùng Continue-As-New sau mỗi chu kỳ.
Ngày 234–235: Ôn tập Temporal
Mục tiêu: Củng cố trước khi làm mini project lớn.
Thực hành theo ngày:
Ngày 234: So sánh Temporal vs Camunda bằng bảng chi tiết (deployment model, ngôn ngữ viết workflow - code vs BPMN visual, determinism requirement, scaling model).
Ngày 235: Tự đặt 10 câu hỏi debug production Temporal ("Workflow bị stuck, History rất dài - bạn debug thế nào?") và trả lời.
Tuần 6 (236–241) - Mini Project: E-commerce Fulfillment
Ngày 236–241: Temporal Mini Project
Mục tiêu: Xây dựng luồng fulfillment đơn hàng hoàn chỉnh bằng Temporal, thể hiện đúng thế mạnh (long-running, phức tạp, cần Signal/Query).
Thực hành theo ngày:
Ngày 236: Thiết kế Workflow chính "OrderFulfillment" (Reserve Inventory → Charge Payment → Ship → Notify), xác định Activity nào cần retry policy riêng.
Ngày 237: Implement Activities (gọi các service giả lập Payment/Inventory/Shipping).
Ngày 238: Thêm Signal "CancelOrder" xử lý được ở bất kỳ bước nào (kèm compensation logic - liên hệ lại Saga Giai đoạn 2/6).
Ngày 239: Thêm Child Workflow cho "Return/Refund" (có thể trigger sau khi Order đã Delivered - long-running).
Ngày 240: Test toàn bộ kịch bản (happy path, cancel giữa chừng, activity fail liên tục vượt retry, return sau khi delivered).
Ngày 241: Viết báo cáo so sánh: nếu build lại hệ thống này bằng Camunda hoặc bằng Saga tự viết tay (Giai đoạn 2), độ phức tạp code sẽ khác thế nào.
Tuần 7 (242–245) - Argo Workflows
Ngày 242–243: Argo Workflows - Kubernetes Native
Mục tiêu: Hiểu workflow engine thiết kế riêng cho Kubernetes, dùng nhiều trong CI/CD và data pipeline.
Lý thuyết: Workflow định nghĩa bằng CRD YAML, mỗi step chạy trong 1 Pod riêng; DAG template vs Steps template.
Thực hành theo ngày:
Ngày 242: Cài Argo Workflows trên Kubernetes local (kind/minikube), chạy workflow "Hello World" dạng Steps template.
Ngày 243: Viết workflow dạng DAG template cho pipeline ETL (đã thiết kế ở ngày 181), mỗi bước là 1 container riêng.
Ngày 244–245: So sánh Argo với Temporal/Camunda
Mục tiêu: Hiểu vì sao Argo phù hợp cho batch/CI-CD nhưng không phù hợp cho long-running business workflow.
Lý thuyết: Argo = mỗi lần chạy tạo Pod mới (tốt cho task ngắn hạn, chạy 1 lần), Temporal/Camunda = process long-running với state phong phú.
Thực hành theo ngày:
Ngày 244: Thử implement lại 1 phần workflow "OrderFulfillment" (ngày 236) bằng Argo, nhận ra hạn chế (không có Signal/Human Task tự nhiên).
Ngày 245: Viết bảng so sánh 3 engine (Camunda, Temporal, Argo) theo use case phù hợp nhất.
Tuần 8 (246–249) - Netflix Conductor & Mock Design Review #2
Ngày 246–247: Netflix Conductor
Mục tiêu: Biết thêm 1 workflow engine dạng JSON-based orchestration, phổ biến trong hệ thống microservice lớn.
Lý thuyết: Task định nghĩa dạng JSON, Conductor Server điều phối, Worker poll task (tương tự External Task của Camunda).
Thực hành theo ngày:
Ngày 246: Cài Conductor (Docker), định nghĩa 1 workflow JSON đơn giản, viết Worker Python poll task.
Ngày 247: So sánh model JSON-based (Conductor) vs code-based (Temporal) vs visual BPMN (Camunda) - ưu nhược từng cách định nghĩa workflow.
Ngày 248–249: Mock Design Review #2
Mục tiêu: Luyện thiết kế hệ thống có workflow phức tạp dưới áp lực thời gian.
Thực hành theo ngày:
Ngày 248: Tự đặt đề "Thiết kế hệ thống xử lý claim bảo hiểm, có nhiều bước duyệt thủ công, SLA từng bước, escalation". Thiết kế trong 45 phút, chọn workflow engine phù hợp và giải thích vì sao.
Ngày 249: Tự phản biện, viết lại thiết kế hoàn chỉnh, so sánh với phương án dùng engine khác.
GIAI ĐOẠN 9 - Data & ML Workflow (Ngày 250–273)
Ngày 250–253: Airflow
Mục tiêu: Hiểu kiến trúc Airflow - công cụ orchestration phổ biến nhất cho data pipeline.
Lý thuyết: Scheduler (đọc DAG, quyết định task nào chạy khi nào), DAG Parser (parse file Python thành DAG object), Metadata DB (lưu trạng thái task/DAG run), Worker (thực thi task), Triggerer (xử lý deferred task, async sensor).
Thực hành theo ngày:
Ngày 250: Cài Airflow (Docker Compose, LocalExecutor), viết 1 DAG đơn giản (dùng lại pipeline ETL ngày 181).
Ngày 251: Quan sát Metadata DB (bảng
dag_run,task_instance) khi DAG chạy, đối chiếu với UI.Ngày 252: Viết DAG có Sensor chờ file xuất hiện, so sánh Sensor thường (chiếm worker slot) vs Deferrable Sensor (dùng Triggerer, không chiếm slot).
Ngày 253: Đọc source code Scheduler cơ bản, hiểu vòng lặp "scan DAG folder → tạo DagRun → schedule Task".
Ngày 254–256: Executors - Sequential, Local, Celery, Kubernetes
Mục tiêu: Hiểu các cách Airflow scale việc thực thi task, chọn đúng executor cho quy mô hệ thống.
Lý thuyết: SequentialExecutor (dev only), LocalExecutor (multi-process trên 1 máy), CeleryExecutor (dùng Celery + broker như RabbitMQ/Redis để scale nhiều máy - liên hệ trực tiếp Giai đoạn 3), KubernetesExecutor (mỗi task = 1 Pod riêng, giống triết lý Argo).
Thực hành theo ngày:
Ngày 254: Đổi sang CeleryExecutor với RabbitMQ làm broker (dùng lại kiến thức Giai đoạn 3), chạy nhiều task song song trên "nhiều worker" (giả lập bằng nhiều container).
Ngày 255: Đổi sang KubernetesExecutor trên cluster local, so sánh resource isolation với CeleryExecutor.
Ngày 256: Viết bảng so sánh 4 executor (throughput, resource isolation, độ phức tạp vận hành).
Ngày 257–259: Mini Project - ETL Platform
Mục tiêu: Xây dựng nền tảng ETL production-grade bằng Airflow.
Thực hành theo ngày:
Ngày 257: Thiết kế DAG multi-stage (Extract từ Postgres → Transform bằng Pandas/Spark → Load vào ClickHouse, dùng lại pipeline Giai đoạn 5).
Ngày 258: Thêm retry, alerting (on_failure_callback gửi thông báo), SLA miss handling.
Ngày 259: Thêm dynamic task mapping (tạo task động dựa trên danh sách file/nguồn dữ liệu), test end-to-end.
Ngày 260–262: MLflow
Mục tiêu: Hiểu công cụ quản lý vòng đời ML - thường được orchestrate bởi Airflow/Kubeflow.
Lý thuyết: Tracking (log metric/parameter mỗi lần train), Registry (quản lý version model), Artifact Store (lưu model file), Serving (deploy model thành API), Experiment Management.
Thực hành theo ngày:
Ngày 260: Cài MLflow, viết script train model đơn giản (scikit-learn), log vào MLflow Tracking.
Ngày 261: Đăng ký model vào Registry, chuyển version qua các stage (Staging → Production).
Ngày 262: Serve model qua MLflow Serving, gọi thử API dự đoán, tích hợp bước train này vào 1 DAG Airflow (Airflow trigger train job → log MLflow → nếu metric đạt ngưỡng thì auto-promote).
Ngày 263–265: Kubeflow
Mục tiêu: Biết nền tảng ML full-stack trên Kubernetes, thay thế/bổ sung cho tổ hợp Airflow+MLflow ở quy mô lớn.
Lý thuyết: Kubeflow Pipeline (định nghĩa ML pipeline dạng DAG chạy trên Kubernetes, tương tự Argo - thực ra dùng Argo bên dưới), Katib (hyperparameter tuning tự động), KServe (model serving trên Kubernetes).
Thực hành theo ngày:
Ngày 263: Cài Kubeflow Pipelines (hoặc dùng managed nếu hạn chế tài nguyên), viết 1 pipeline đơn giản, nhận ra nó chạy trên Argo Workflow đã học ở Giai đoạn 8.
Ngày 264: Cấu hình 1 thí nghiệm Katib tune hyperparameter cho model ở ngày 260.
Ngày 265: Deploy model qua KServe, so sánh trải nghiệm với MLflow Serving.
Ngày 266–267: Feast - Feature Store
Mục tiêu: Hiểu vấn đề "training-serving skew" và cách Feature Store giải quyết.
Lý thuyết: Offline Store (dùng để train, thường là data warehouse) vs Online Store (dùng để serve real-time, thường là Redis); Feast đồng bộ 2 store này.
Thực hành theo ngày:
Ngày 266: Cài Feast, định nghĩa 1 feature view, materialize từ offline (Postgres) sang online (Redis).
Ngày 267: Viết demo lấy feature real-time từ Online Store để phục vụ inference, so sánh với việc tự query DB trực tiếp (chậm hơn, dễ lệch giữa train và serve).
Ngày 268–273: Lab tích hợp - Airflow + MLflow + Kafka
Mục tiêu: Ghép toàn bộ Giai đoạn 9 thành 1 pipeline ML end-to-end có streaming input.
Thực hành theo ngày:
Ngày 268: Thiết kế kiến trúc: Kafka (event mua hàng, đã có từ Giai đoạn 5) → Airflow DAG (batch feature engineering hàng giờ) → Feast (feature store) → MLflow (train + registry).
Ngày 269: Implement DAG đọc dữ liệu từ Kafka (qua Kafka Connect Sink đã học, đổ vào warehouse) để tính feature.
Ngày 270: Implement bước materialize feature vào Feast Online Store.
Ngày 271: Implement training job trong DAG, log vào MLflow, auto-promote nếu đạt ngưỡng metric.
Ngày 272: Implement inference service đơn giản (gRPC - liên hệ Giai đoạn 7.5) lấy feature từ Feast Online Store + model từ MLflow.
Ngày 273: Test end-to-end, viết báo cáo kiến trúc toàn bộ pipeline.
GIAI ĐOẠN 9.5 - Testing cho Hệ Thống Async/Event-Driven (Ngày 274–279)
Ngày 274: Contract Testing (Pact)
Mục tiêu: Đảm bảo producer và consumer không phá vỡ nhau khi thay đổi schema/API - đặc biệt quan trọng khi nhiều team cùng dùng chung topic Kafka.
Lý thuyết: Consumer-Driven Contract Testing; Pact Broker; áp dụng cho cả HTTP API lẫn message-based contract (event schema).
Thực hành: Viết contract test bằng Pact cho cặp Producer/Consumer "OrderCreated" (đã dùng từ Giai đoạn 1), test contract fail khi producer đổi schema không tương thích.
Ngày 275: Chaos Testing - Tư duy kiểu Jepsen
Mục tiêu: Học cách tư duy kiểm chứng tính đúng đắn của hệ phân tán dưới lỗi (network partition, node crash).
Lý thuyết: Jepsen testing methodology (inject fault + kiểm tra linearizability/invariant); các loại fault phổ biến: network partition, clock skew, process pause.
Thực hành: Đọc 1 báo cáo Jepsen công khai về 1 hệ thống bạn đã học (Kafka hoặc RabbitMQ hoặc Postgres), tóm tắt phương pháp luận và phát hiện chính.
Ngày 276: Testing Idempotency & EOS
Mục tiêu: Viết được test tự động xác minh idempotency/exactly-once thay vì kiểm tra thủ công như đã làm ở các giai đoạn trước.
Lý thuyết: Kỹ thuật test: gửi duplicate message có chủ đích, đo invariant (vd: tổng số dư tài khoản không đổi khi replay).
Thực hành: Viết test tự động (pytest) cho hệ thống "Bank Account" (Giai đoạn 6): replay toàn bộ event 3 lần, assert state cuối cùng không đổi.
Ngày 277: Load Testing Message Broker
Mục tiêu: Biết công cụ và phương pháp đo hiệu năng broker dưới tải thực tế.
Lý thuyết: k6/Gatling cho HTTP; cho Kafka dùng
kafka-producer-perf-test/kafka-consumer-perf-test; đo throughput, p50/p95/p99 latency.Thực hành: Chạy load test Kafka topic đã dùng ở Giai đoạn 5 với
kafka-producer-perf-test, tăng dần tải, tìm điểm bão hoà (throughput ngừng tăng, latency tăng vọt).
Ngày 278–279: Lab - Chaos Test RabbitMQ Cluster
Mục tiêu: Áp dụng chaos testing thực chiến lên hệ thống đã build ở Giai đoạn 3.
Lý thuyết: Toxiproxy để giả lập network partition/latency có kiểm soát.
Thực hành theo ngày:
Ngày 278: Cài Toxiproxy trước cluster RabbitMQ 3 node (ngày 74–84), inject network partition giữa 1 node và 2 node còn lại, quan sát Quorum Queue xử lý thế nào.
Ngày 279: Inject latency cao giữa các node, đo ảnh hưởng đến publisher confirm latency; viết báo cáo "failure mode analysis" đầy đủ.
GIAI ĐOẠN 9.6 - Cost & Capacity Planning (Ngày 280–283)
Ngày 280: Kafka Partition & Broker Sizing
Mục tiêu: Tính toán được số lượng partition/broker cần thiết cho 1 workload cụ thể - kỹ năng thường bị bỏ qua nhưng cực kỳ thực tế.
Lý thuyết: Công thức ước lượng: throughput mong muốn/throughput mỗi partition; số partition tối đa hợp lý mỗi broker (ảnh hưởng đến thời gian leader election, file handle); trade-off quá nhiều partition vs quá ít.
Thực hành: Với yêu cầu "50.000 msg/s, message 2KB, retention 3 ngày, replication factor 3", tính số partition, số broker, tổng dung lượng disk cần thiết.
Ngày 281: RabbitMQ/Temporal Capacity Planning
Mục tiêu: Mở rộng kỹ năng sizing sang các hệ thống khác đã học.
Lý thuyết: RabbitMQ - sizing theo số queue, message size, consumer throughput; Temporal - sizing theo số Workflow đồng thời, History size ảnh hưởng tới Server + Database.
Thực hành: Tính capacity plan cho hệ thống "Order Processing" (RabbitMQ, Giai đoạn 3) với 5.000 order/phút, và cho hệ thống Temporal (Giai đoạn 8) với 100.000 Workflow đang chạy song song.
Ngày 282: Storage & Retention Cost Modeling
Mục tiêu: Chuyển capacity plan thành con số chi phí thực tế - kỹ năng cần khi trình bày với stakeholder không kỹ thuật.
Lý thuyết: Chi phí storage (SSD vs HDD, cloud block storage pricing), chi phí network egress, trade-off giữa retention dài và chi phí.
Thực hành: Viết bảng Excel/Sheet ước lượng chi phí hàng tháng cho hệ thống Kafka đã tính ở ngày 280, dùng bảng giá cloud provider công khai.
Ngày 283: Lab - Capacity Plan cho Hệ 100k msg/s
Mục tiêu: Tổng hợp toàn bộ Giai đoạn 9.6 thành 1 bản capacity plan hoàn chỉnh, đúng chuẩn tài liệu thiết kế thực tế.
Thực hành: Viết document capacity plan đầy đủ (broker sizing, partition strategy, storage cost, network cost, growth projection 12 tháng) cho hệ thống giả định "nền tảng IoT 100.000 msg/s".
GIAI ĐOẠN 10 - Production (Ngày 284–331)
Tuần 1 (284–289) - Reliability
Ngày 284–285: Retry & Backoff Cross-System
Mục tiêu: Thiết kế retry strategy nhất quán xuyên suốt hệ thống nhiều thành phần (Kafka + RabbitMQ + Temporal + Airflow), tránh retry storm lan truyền.
Lý thuyết: Retry budget toàn hệ thống, correlation giữa retry ở tầng application và retry built-in của broker/engine (dễ gây retry x N lần chồng chéo nếu không phối hợp).
Thực hành theo ngày:
Ngày 284: Audit toàn bộ retry logic trong hệ thống "Event Driven Ecommerce" (đã build), vẽ sơ đồ tất cả các tầng có retry.
Ngày 285: Redesign retry strategy tránh chồng chéo (vd: tắt retry built-in ở tầng dưới nếu tầng trên đã handle).
Ngày 286–287: DLQ & Poison Queue ở Quy Mô Lớn
Mục tiêu: Thiết kế quy trình vận hành DLQ thực tế (không chỉ code, mà cả runbook cho on-call).
Lý thuyết: Alerting khi DLQ tăng bất thường, quy trình replay message từ DLQ sau khi fix bug, phân loại lỗi transient vs permanent.
Thực hành theo ngày:
Ngày 286: Viết script "replay DLQ" tự động cho hệ Kafka (đọc DLQ topic, re-publish vào topic gốc sau khi fix).
Ngày 287: Viết runbook đầy đủ: "DLQ tăng đột biến - checklist debug từng bước".
Ngày 288–289: Bulkhead & Circuit Breaker ở Kiến Trúc Microservices
Mục tiêu: Áp dụng pattern cô lập lỗi (đã học Giai đoạn 0) ở quy mô nhiều service thật.
Thực hành theo ngày:
Ngày 288: Thêm Circuit Breaker (dùng thư viện như
pybreakerhoặc tương đương) bọc quanh mọi external call trong hệ thống Ecommerce.Ngày 289: Thiết kế Bulkhead (tách connection pool/thread pool riêng cho từng downstream dependency), test 1 dependency chậm không làm ảnh hưởng dependency khác.
Tuần 2 (290–295) - Observability
Ngày 290–291: Prometheus & Grafana
Mục tiêu: Thiết lập monitoring cho toàn bộ hệ thống đã build.
Lý thuyết: Metric types (Counter, Gauge, Histogram), PromQL cơ bản, JMX Exporter cho Kafka/Kafka Connect/Camunda.
Thực hành theo ngày:
Ngày 290: Cài Prometheus + Grafana, scrape metric từ Kafka broker (qua JMX Exporter) và RabbitMQ (Prometheus plugin built-in).
Ngày 291: Build dashboard Grafana cho Kafka (consumer lag, throughput, ISR shrink) và RabbitMQ (queue depth, message rate).
Ngày 292–293: OpenTelemetry
Mục tiêu: Chuẩn hoá tracing/metric xuyên suốt hệ thống polyglot (Python, Go, Java) đã build.
Lý thuyết: OTel SDK, Trace/Span/Context Propagation qua message header (quan trọng cho hệ event-driven - trace phải "nhảy" được qua Kafka message).
Thực hành theo ngày:
Ngày 292: Instrument OTel cho 2-3 service trong hệ Ecommerce, xuất trace ra console trước.
Ngày 293: Implement Context Propagation qua Kafka message header, xác nhận trace liên tục từ Order Service → Payment Service dù đi qua Kafka.
Ngày 294–295: Jaeger
Mục tiêu: Trực quan hoá distributed trace để debug latency thực tế.
Lý thuyết: Jaeger UI, cách đọc waterfall trace, xác định bottleneck.
Thực hành theo ngày:
Ngày 294: Cài Jaeger, đẩy trace từ ngày 293 vào, quan sát toàn bộ hành trình 1 order qua các service.
Ngày 295: Cố tình tạo 1 bottleneck (thêm sleep giả lập), dùng Jaeger xác định chính xác service nào chậm.
Tuần 3 (296–301) - Scaling
Ngày 296–297: Horizontal vs Vertical Scaling
Mục tiêu: Ra quyết định đúng khi hệ thống cần scale - áp dụng cho từng thành phần đã học.
Lý thuyết: Khi nào vertical đủ (đơn giản, nhanh), khi nào bắt buộc horizontal (Kafka partition, RabbitMQ cluster, Temporal Worker pool).
Thực hành: Với hệ thống đã build, liệt kê từng thành phần và xác định chiến lược scale phù hợp, giới hạn của mỗi chiến lược.
Ngày 298–299: Partition Scaling
Mục tiêu: Hiểu rủi ro và quy trình an toàn khi tăng số partition Kafka topic đang chạy production.
Lý thuyết: Tăng partition không tự động rebalance dữ liệu cũ, ảnh hưởng đến ordering theo key (message cùng key có thể rơi vào partition khác sau khi tăng).
Thực hành: Test tăng partition topic đang có dữ liệu, quan sát vấn đề ordering theo key mô tả ở trên, viết note quy trình an toàn để tăng partition trong production.
Ngày 300–301: Workflow Scaling
Mục tiêu: Hiểu cách scale Temporal Worker và Airflow Worker khi tải tăng.
Lý thuyết: Temporal Worker scale ngang tự nhiên (nhiều Worker cùng poll 1 Task Queue); Airflow scale phụ thuộc Executor (CeleryExecutor thêm worker, KubernetesExecutor tự động theo Pod).
Thực hành: Load test hệ thống Temporal (Giai đoạn 8) với số lượng Workflow tăng dần, thêm Worker và đo cải thiện throughput.
Tuần 4 (302–307) - Disaster Recovery
Ngày 302–303: Backup & Restore
Mục tiêu: Có quy trình backup/restore đã test cho từng hệ thống đã build.
Lý thuyết: Kafka (MirrorMaker 2 cho cross-cluster replication, không có "backup" truyền thống), Postgres (
pg_dump/WAL archiving), Temporal (database backup).Thực hành theo ngày:
Ngày 302: Setup backup tự động cho Postgres (dùng ở nhiều giai đoạn) bằng WAL archiving, test restore point-in-time.
Ngày 303: Setup Kafka MirrorMaker 2 replicate topic sang 1 cluster Kafka thứ 2 (giả lập DR site).
Ngày 304–305: Cross-Region & Multi-Cluster
Mục tiêu: Hiểu kiến trúc active-active/active-passive cho hệ thống messaging đa vùng.
Lý thuyết: Active-Passive (failover thủ công/tự động), Active-Active (cả 2 region đều nhận traffic, cần giải quyết conflict); độ trễ giữa các region ảnh hưởng consistency.
Thực hành: Thiết kế (trên giấy) kiến trúc multi-region cho hệ thống Ecommerce đã build, xác định thành phần nào active-active được, thành phần nào bắt buộc active-passive (vd: nơi cần strong consistency).
Ngày 306–307: DR Drill
Mục tiêu: Thực chiến 1 buổi diễn tập DR hoàn chỉnh - kỹ năng vận hành thực tế quan trọng nhất giai đoạn này.
Thực hành theo ngày:
Ngày 306: Giả lập "mất toàn bộ cluster Kafka chính", thực hiện failover sang cluster DR (ngày 303), đo RTO (Recovery Time Objective) thực tế đạt được.
Ngày 307: Viết báo cáo sau diễn tập (post-mortem format): RTO/RPO đạt được, điểm nghẽn, cải tiến cần làm.
Tuần 5 (308–313) - Security
Ngày 308–309: mTLS & SASL
Mục tiêu: Bảo mật giao tiếp giữa client và broker.
Lý thuyết: mTLS (mutual TLS, cả client và server xác thực lẫn nhau), SASL (SCRAM, PLAIN, Kerberos) cho authentication ở Kafka/RabbitMQ.
Thực hành theo ngày:
Ngày 308: Bật SASL/SCRAM cho Kafka cluster, cấu hình producer/consumer dùng credential.
Ngày 309: Bật mTLS cho RabbitMQ, generate certificate, test connection bị từ chối nếu thiếu client cert.
Ngày 310: RBAC
Mục tiêu: Phân quyền chi tiết theo vai trò cho từng thành phần.
Lý thuyết: Kafka ACL (ai được produce/consume topic nào), RabbitMQ permission (configure/write/read theo vhost), Camunda/Temporal namespace-level RBAC.
Thực hành: Cấu hình Kafka ACL giới hạn Payment Service chỉ được produce vào topic
payment.*, test service khác bị từ chối khi cố produce vào topic đó.
Ngày 311–312: Secrets Management & Encryption
Mục tiêu: Quản lý credential/secret an toàn, không hardcode.
Lý thuyết: Secret manager (Vault/cloud KMS), Encryption at rest (disk-level), Encryption in transit (đã có qua TLS).
Thực hành theo ngày:
Ngày 311: Cài Vault (hoặc dùng Kubernetes Secret nếu hạn chế), migrate toàn bộ credential (DB password, Kafka SASL) đang hardcode sang Vault.
Ngày 312: Bật encryption at rest cho volume Postgres/Kafka (tuỳ hạ tầng), viết note về key rotation.
Ngày 313: Security Review Tổng Hợp
Mục tiêu: Tổng kết toàn bộ security posture của hệ thống đã build suốt lộ trình.
Thực hành: Viết security checklist đầy đủ (authentication, authorization, encryption in-transit/at-rest, secret management) và tự audit hệ thống Ecommerce theo checklist đó, liệt kê gap còn tồn tại.
Tuần 6–8 (314–331) - Mock Design Review & On-Call Simulation
Ngày 314–319: Mock Design Review #3 - Hệ Thống Quy Mô Lớn
Mục tiêu: Luyện thiết kế ở quy mô "Big Tech interview" thực sự, tích hợp mọi kiến thức đã học.
Thực hành theo ngày:
Ngày 314–315: Đề bài "Thiết kế hệ thống ride-hailing real-time matching, 1 triệu request/phút". Thiết kế trong 60 phút, sau đó tự phản biện.
Ngày 316–317: Đề bài "Thiết kế hệ thống thanh toán xuyên biên giới, cần audit trail đầy đủ, exactly-once bắt buộc". Áp dụng Event Sourcing + Saga đã học.
Ngày 318–319: Đề bài "Thiết kế nền tảng workflow duyệt hồ sơ đa cấp cho 1 tập đoàn, hàng chục nghìn quy trình đồng thời". Chọn giữa Camunda/Temporal, giải thích trade-off.
Ngày 320–325: On-Call Simulation
Mục tiêu: Luyện phản xạ xử lý sự cố production dưới áp lực - kỹ năng khác hẳn với thiết kế hệ thống.
Thực hành theo ngày:
Ngày 320: Kịch bản "Consumer lag Kafka tăng vọt đột ngột lúc 2h sáng" - tự inject sự cố vào hệ thống đã build, debug và fix trong thời gian giới hạn.
Ngày 321: Kịch bản "RabbitMQ cluster mất quorum" - debug và khôi phục.
Ngày 322: Kịch bản "Temporal Workflow bị stuck hàng loạt sau khi deploy code mới" (non-determinism error) - debug và fix.
Ngày 323: Kịch bản "Airflow Scheduler ngừng schedule task dù service vẫn chạy" - debug.
Ngày 324: Kịch bản "Disk đầy trên Kafka broker do retention config sai" - xử lý khẩn cấp không mất dữ liệu.
Ngày 325: Viết lại toàn bộ 5 kịch bản trên thành runbook chuẩn cho đội on-call thực tế.
Ngày 326–331: Mock Design Review #4–5 & Tổng Kết Giai Đoạn 10
Mục tiêu: Hoàn thiện kỹ năng thiết kế + vận hành trước khi vào phần đọc source code và Capstone.
Thực hành theo ngày:
Ngày 326–328: Đề bài tự chọn (lấy từ 1 hệ thống thật bạn quan tâm, vd: hệ thống đặt đồ ăn, hệ thống chat), thiết kế đầy đủ có Data Flow Diagram, Capacity Plan, DR Plan, Security Review.
Ngày 329–331: Trình bày lại thiết kế đó như 1 buổi "design review" thật (viết thành document + thuyết trình cho chính mình hoặc 1 người khác góp ý), chỉnh sửa dựa trên phản biện.
GIAI ĐOẠN 11 - Source Code & (Ngày 332–343)
Ngày 332–334: Đọc Source Code Kafka - Broker, Controller, Consumer Group
Mục tiêu: Đào sâu hơn nữa (sau lần đọc sơ bộ ở Giai đoạn 5) với góc nhìn của người đã vận hành thực chiến qua Giai đoạn 10.
Thực hành theo ngày:
Ngày 332: Đọc lại
KafkaControllersource, đối chiếu với các sự cố đã debug ở ngày 320–325.Ngày 333: Đọc
ReplicaManager, trace luồng code xử lý khi 1 replica out-of-sync.Ngày 334: Đọc lại
GroupCoordinator, lần này chú ý vào phần xử lý lỗi/edge case thay vì happy path.
Ngày 335–336: Đọc Source Code RabbitMQ - Queue Process, Exchange
Mục tiêu: Hiểu implementation Erlang thực tế của các khái niệm đã học ở Giai đoạn 3.
Thực hành theo ngày:
Ngày 335: Đọc module
rabbit_queue_process(hoặc tương đương trong version hiện tại), đối chiếu với hành vi quan sát được ở ngày 70–73.Ngày 336: Đọc module xử lý Exchange routing, trace code cho Topic Exchange wildcard matching.
Ngày 337–339: Đọc Source Code Temporal - History Service, Matching Service
Mục tiêu: Hiểu kiến trúc microservice nội bộ của Temporal Server.
Lý thuyết: Temporal Server gồm nhiều service nội bộ: Frontend, History Service (quản lý History Event), Matching Service (match Task với Worker).
Thực hành theo ngày:
Ngày 337: Đọc code History Service, trace luồng ghi Event khi Workflow gọi Activity.
Ngày 338: Đọc code Matching Service, hiểu cách Task Queue thực sự được implement (không phải database table đơn giản, mà có cơ chế forwarding phức tạp).
Ngày 339: Viết lại sơ đồ kiến trúc Temporal Server dựa trên source code, so với sơ đồ đã học ở Giai đoạn 8 (đã chính xác hơn chưa).
Ngày 340–341: Đọc Source Code Airflow - Scheduler, Executor
Mục tiêu: Hiểu chi tiết vòng lặp Scheduler đã dùng nhiều ở Giai đoạn 9 và 10.
Thực hành theo ngày:
Ngày 340: Đọc
SchedulerJob, trace vòng lặp chính (_do_scheduling).Ngày 341: Đọc
BaseExecutorvà implementation củaCeleryExecutor, đối chiếu với hành vi đã quan sát ở ngày 254.
Ngày 342–343: Tổng Hợp & Viết Bài Chia Sẻ
Mục tiêu: Chốt kiến thức bằng cách diễn đạt lại theo ngôn ngữ của chính mình - cách học sâu nhất.
Thực hành theo ngày:
Ngày 342: Viết 1 bài blog kỹ thuật (internal note hoặc public) về "Cách Kafka đạt được durability qua ISR/HW/LEO" hoàn toàn bằng lời của bạn, dựa trên source code đã đọc.
Ngày 343: Viết 1 bài blog thứ 2 về "So sánh 3 workflow engine (Camunda/Temporal/Argo) qua lăng kính implementation, không chỉ tính năng".
CAPSTONE - Nền Tảng Production Hoàn Chỉnh (Ngày 344–367)
Kiến trúc mục tiêu:
Postgres
|
Debezium
|
Kafka
|
Kafka Streams
|
Temporal
|
Microservices
|
MLflow
|
Airflow
Các bài toán bắt buộc phải giải quyết trong Capstone: CDC, Event Sourcing, CQRS, Saga, Retry/DLQ, Workflow (Temporal + Camunda cho 1 phần cần Human Task), ML Pipeline, Monitoring, Disaster Recovery, Multi-Region.
Ngày 344–346: Architecture Design Document
Mục tiêu: Trước khi code, có 1 document thiết kế hoàn chỉnh như thật ở công ty lớn.
Thực hành theo ngày:
Ngày 344: Chọn 1 domain nghiệp vụ cụ thể (khuyến nghị: nền tảng "cho vay tiêu dùng online" - tận dụng được cả Event Sourcing, Saga, Human Task duyệt hồ sơ, ML risk scoring). Viết Problem Statement + Requirements (functional/non-functional).
Ngày 345: Vẽ toàn bộ Data Flow Diagram, xác định service boundary, topic/queue cần thiết, chọn nơi dùng Temporal vs Camunda vs Kafka Streams.
Ngày 346: Viết Capacity Plan (áp dụng Giai đoạn 9.6) và Security Design (áp dụng Giai đoạn 10) cho toàn bộ hệ thống.
Ngày 347–350: CDC + Kafka Pipeline
Mục tiêu: Dựng nền tảng data streaming layer.
Thực hành theo ngày:
Ngày 347: Setup Postgres cho các service lõi (Loan Application, Customer, Payment), thiết kế schema.
Ngày 348: Setup Debezium capture toàn bộ thay đổi, đẩy vào Kafka (áp dụng Outbox Pattern cho các sự kiện nghiệp vụ quan trọng, CDC thuần cho phần còn lại).
Ngày 349: Thiết kế topic strategy đầy đủ (naming convention, partition key, retention/compaction policy cho từng loại topic).
Ngày 350: Setup Schema Registry, đăng ký schema Avro cho toàn bộ event nghiệp vụ.
Ngày 351–353: Kafka Streams Processing Layer
Mục tiêu: Xử lý stream real-time cho các nhu cầu tính toán liên tục.
Thực hành theo ngày:
Ngày 351: Implement Kafka Streams app tính toán "risk score sơ bộ" real-time từ hành vi giao dịch (windowed aggregation).
Ngày 352: Implement CQRS Read Model (Projection) cho "Loan Application Status" phục vụ dashboard.
Ngày 353: Test toàn bộ streaming layer với dữ liệu giả lập throughput cao (dùng kỹ thuật load test Giai đoạn 9.5).
Ngày 354–357: Temporal Workflow Orchestration Layer
Mục tiêu: Xây dựng luồng nghiệp vụ chính bằng Temporal, có phần cần Human Task tích hợp Camunda.
Thực hành theo ngày:
Ngày 354: Implement Temporal Workflow chính "LoanApplicationProcess" (Submit → Auto Risk Check → Credit Bureau Check (Activity) → Decision).
Ngày 355: Với nhánh cần con người duyệt thủ công (risk score ở vùng "manual review"), tích hợp gọi sang Camunda process (Temporal Activity trigger Camunda process, chờ callback qua Signal khi nhân viên duyệt xong).
Ngày 356: Implement Saga/Compensation đầy đủ cho luồng giải ngân (Disburse Fund → nếu fail ở bước sau thì reverse).
Ngày 357: Test toàn bộ workflow với đầy đủ kịch bản (auto-approve, manual-review approve/reject, fail giữa chừng cần compensation).
Ngày 358–360: Microservices Integration
Mục tiêu: Hoàn thiện các service còn thiếu và giao tiếp hybrid (sync + async).
Thực hành theo ngày:
Ngày 358: Implement Customer Service, Notification Service (async, consume Kafka event).
Ngày 359: Implement gRPC call đồng bộ giữa Loan Service và Credit Bureau Service giả lập (áp dụng Giai đoạn 7.5) cho phần cần real-time.
Ngày 360: Đảm bảo toàn bộ giao tiếp có Idempotency (Inbox pattern) và Contract Test (Pact, Giai đoạn 9.5).
Ngày 361–362: MLflow Integration
Mục tiêu: Đưa risk scoring model vào vòng đời ML hoàn chỉnh thay vì hard-code logic.
Thực hành theo ngày:
Ngày 361: Train model risk scoring thật (dữ liệu giả lập), log vào MLflow, đăng ký Registry.
Ngày 362: Tích hợp model serving vào Temporal Activity "Auto Risk Check" (gọi model qua MLflow Serving hoặc gRPC service riêng).
Ngày 363–364: Airflow Integration
Mục tiêu: Thêm batch layer cho retraining định kỳ và báo cáo.
Thực hành theo ngày:
Ngày 363: Implement DAG retrain model hàng ngày (đọc dữ liệu mới từ warehouse, train, đánh giá, auto-promote nếu tốt hơn model hiện tại - dùng lại toàn bộ Giai đoạn 9).
Ngày 364: Implement DAG báo cáo vận hành hàng ngày (số đơn vay, tỉ lệ approve, DLQ status) gửi qua Notification Service.
Ngày 365: Monitoring & Disaster Recovery Setup
Mục tiêu: Hoàn thiện observability và DR cho toàn bộ nền tảng.
Thực hành: Setup Prometheus/Grafana/Jaeger cho toàn bộ hệ thống (áp dụng Giai đoạn 10), setup backup Postgres + MirrorMaker 2 cho Kafka, viết DR runbook.
Ngày 366: Multi-Region Simulation
Mục tiêu: Test khả năng chịu lỗi ở quy mô vùng địa lý.
Thực hành: Giả lập 2 region (2 Docker Compose stack riêng biệt kết nối qua Kafka MirrorMaker 2), test failover Loan Application đang xử lý dở khi region chính "sập" (dùng Toxiproxy inject fault).
Ngày 367: Final Review, Retro & Portfolio Writeup
Mục tiêu: Đóng gói toàn bộ 367 ngày thành 1 tài sản nghề nghiệp thực sự có thể dùng để phỏng vấn Senior/Staff.
Thực hành:
Viết Architecture Decision Record (ADR) cho 10 quyết định thiết kế quan trọng nhất trong Capstone (vd: "vì sao chọn Temporal thay vì Camunda cho luồng chính", "vì sao chọn Outbox thay vì CDC thuần cho event nghiệp vụ").
Viết retro cá nhân: 5 khái niệm khó nhất đã chinh phục, 5 điều sẽ làm khác nếu bắt đầu lại.
Đóng gói toàn bộ code + document thành 1 repository portfolio, viết README giới thiệu tổng quan để dùng khi phỏng vấn hoặc trình bày.