---
title: "Thiết kế ứng dụng realtime và offline-first - WebSocket, SSE, đồng bộ dữ liệu và CRDT"
description: "Khóa học thiết kế app realtime và offline-first giúp bạn làm chủ WebSocket, SSE, kiến trúc gateway phân tán và CRDT. Bạn sẽ biết cách giữ kết nối ổn định, khôi phục tin nhắn không bị trùng lặp và gộp dữ liệu mượt mà sau khi offline, thay vì vội vã nâng cấp hạ tầng tốn kém."
canonical: "https://200lab.io/courses/thiet-ke-ung-dung-realtime-va-offline-first-websocket-sse-dong-bo-du-lieu-va-crdt"
type: "course"
course_type: "course"
learning_type: "free_form"
published: "2026-10-13T08:03:34Z"
students: 23
---

## Khóa học này mang lại gì cho bạn

Ứng dụng chat nhóm mà bạn phát triển cùng AI agent đang chạy tốt với đầy đủ tính năng nhắn tin, chấm online, dòng “đang gõ…” và số tin chưa đọc trên cả web lẫn mobile. Khi lượng người dùng tăng lên, các sự cố bắt đầu xuất hiện: người dùng đi thang máy ra thấy thiếu tin, tin nhắn gửi lúc mạng yếu bị nhảy hai lần, bình luận livestream trễ cả chục giây và ghi chú sửa lúc offline bị ghi đè mất. AI agent thường đưa ra câu trả lời quen thuộc là chuyển hết sang WebSocket hoặc thêm server, nhưng giải pháp đó không giải quyết được gốc rễ nếu bạn chưa nắm rõ tin nhắn đang hỏng ở chặng nào khi dữ liệu dạng byte gửi qua mạng.

- **Chọn giao thức truyền tin** — Bạn phân biệt rõ polling, long-polling, SSE và WebSocket dựa trên hướng đi của dữ liệu và tần suất cập nhật, đồng thời nhận biết chính xác khi nào kỹ thuật polling đơn giản vẫn đủ đáp ứng mà chưa cần dựng gateway.
- **Duy trì kết nối ổn định** — Bạn làm chủ cơ chế heartbeat với chu kỳ ping pong chuẩn xác để dọn dẹp connection ma, cấu hình nhịp drain connection khi deploy nhằm tránh gián đoạn đồng loạt, và chuyển trạng thái presence sang soft state có TTL để chấm online tự tắt khi người dùng ngắt mạng.
- **Khôi phục tin nhắn** — Bạn hiểu rõ vì sao mở lại socket thành công mà client vẫn mất tin hoặc nhận tin hai lần, từ đó thiết kế sequence tăng dần theo kênh để client resume chính xác bằng cursor, kết hợp `client_msg_id` sinh tại client để database chặn đứng tin gửi trùng.
- **Điều phối qua nhiều gateway** — Bạn áp dụng nguyên tắc lưu database trước khi publish sang pub/sub, xử lý bù tin cho các kênh im lặng bằng `last_seq`, xây dựng connection registry tập trung trên Redis để gửi push notification đúng người, và tính số tin chưa đọc bằng hiệu hai số thay vì ghi đè cho từng người nhận.
- **Kiểm soát tài nguyên kênh** — Bạn thiết lập ngưỡng bộ đệm trên từng connection để client chậm không làm gateway cạn kiệt RAM, mã hóa payload một lần cho nhiều người nhận, chỉ gửi nội dung đầy đủ cho người đang mở kênh, và gom đợt thả tim để giải phóng hàng đợi cho bình luận.
- **Đồng bộ dữ liệu offline** — Bạn biến client thành replica với hàng đợi thao tác bền bỉ mang `op_id` sinh tại thiết bị, nắm vững ranh giới giữa LWW, OT và CRDT để chọn đúng giải pháp gộp văn bản, đồng thời thiết lập chính sách dọn dẹp tombstone an toàn theo mốc đồng bộ của các thiết bị.
- **Thẩm định đề xuất kỹ thuật** — Bạn biết chính xác các số liệu cần đo đạc và câu hỏi cốt lõi cần đặt ra trước khi đồng ý với đề xuất thay đổi kiến trúc từ agent, từ tỉ lệ polling rỗng, số connection ma trong bộ nhớ đến lượng thao tác bị loại bỏ khi gộp dữ liệu.

Khóa học tập trung vào nền tảng thiết kế hệ thống độc lập công nghệ thông qua các trường hợp thực tế của app chat, livestream và ghi chú cộng tác, với mã nguồn minh họa bằng TypeScript và SQL cùng demo kit kiểm thử trực tiếp trên Docker.

## Khóa học cung cấp những nền tảng nào

Toàn bộ khóa học được xây dựng xoay quanh đường đi của tin nhắn và các sự kiện: dữ liệu mới đi qua những chặng nào từ client gửi đến client nhận, và khi một chặng bị gián đoạn, trễ hay gửi trùng thì điều gì diễn ra ở database, gateway và thiết bị. Hệ thống phát triển tuần tự theo bậc thang năm nấc của app chat, từ một process backend dùng polling trên Postgres cho đến app offline-first hoàn chỉnh. Bạn có thể tham khảo tài liệu [Gateway của Discord](https://docs.discord.com/developers/events/gateway) về việc cấp sequence để client resume sau khi connection đứt, bài viết kỹ thuật [Real-time Messaging của Slack](https://slack.engineering/real-time-messaging/) về cách tách gateway giữ WebSocket khỏi server lưu lịch sử kênh, cùng bài tiểu luận [Local-first software của Ink & Switch](https://www.inkandswitch.com/essay/local-first/) về nguyên lý lưu trữ dữ liệu tại thiết bị và dùng CRDT để tự động gộp các bản sửa.

### 1. Polling, SSE hay WebSocket, và giữ connection luôn mở trên một gateway

Khi hệ thống có 12.000 người online cùng lúc khiến endpoint kiểm tra tin mới nhận tới 6.000 request mỗi giây nhưng 95% phản hồi trả về rỗng, database sẽ kiệt quệ vì những truy vấn không có dữ liệu. Bạn sẽ đặt 4 giải pháp polling, long-polling, SSE và WebSocket lên bàn cân với 5 tiêu chí kỹ thuật để chọn đúng giao thức theo hướng truyền dữ liệu: dữ liệu hai chiều liên tục dùng WebSocket, dữ liệu một chiều từ server đẩy xuống dùng SSE, và giữ nguyên polling khi lượng truy cập nhỏ và dữ liệu cập nhật thưa. Để quản lý hàng chục nghìn connection luôn mở trên một gateway, bạn thiết lập nhịp heartbeat định kỳ 25 giây gửi ping và chờ pong trong 10 giây nhằm đóng connection ma chậm nhất sau 35 giây, phối hợp với idle timeout của load balancer và quy trình drain connection rải đều trong 30 giây khi deploy. Chấm online được thiết kế lại dưới dạng soft state tự hết hạn theo TTL 60 giây kết hợp bộ lọc debounce 10 giây giúp giao diện không bị nhấp nháy mỗi khi thiết bị đổi mạng, còn dòng “đang gõ…” gửi tối đa một lần mỗi 3 giây và tự động ẩn sau 5 giây nếu không nhận event mới mà không cần lệnh tắt riêng biệt.

### 2. Reconnect mà không thiếu tin, gửi lại mà không trùng tin

Connection mở lại thành công chỉ giải quyết tầng transport, trong khi việc lấy lại các tin nhắn bị lỡ trong quãng thời gian mất mạng đòi hỏi cơ chế resume ở tầng app. Bạn sẽ cấp sequence tăng dần cho từng sự kiện ngay trên dòng của kênh trong bảng `channels` thay vì dùng ID tự tăng của bảng tin nhắn, giúp client xác định chính xác cursor là số thứ tự liên tục cuối cùng đã xử lý an toàn để yêu cầu gateway phát bù đúng đoạn dữ liệu thiếu từ database. Nhằm xử lý tình trạng tin nhắn hiện hai lần khi mạng chập chờn, client sẽ sinh `client_msg_id` duy nhất cho mỗi tin trước lần gửi đầu và giữ nguyên qua mọi lượt retry, kết hợp ràng buộc `UNIQUE` trên database và quy tắc gateway chỉ trả ack sau khi transaction commit thành công. Nhóm bài học khép lại bằng tình huống thực tế khi laptop mất mạng 5 giây giữa lúc cả nhóm đang nhắn tin, đối chiếu giải pháp chắp vá tải lại 200 tin gần nhất với quy trình chuẩn hóa: resume bằng cursor cho tin thiếu, `client_msg_id` cho tin trùng, và debounce cho presence.

### 3. Chạy nhiều gateway mà tin vẫn tới mọi thiết bị

Khi mở rộng hệ thống lên nhiều gateway sau load balancer, hai người dùng ở cùng một kênh nhưng kết nối tới hai gateway khác nhau sẽ không thể nhận được tin nhắn của nhau nếu thiếu trục giao tiếp trung gian. Bạn sẽ giải quyết triệt để vấn đề này bằng cách thiết lập thứ tự ghi tin an toàn vào Postgres trước rồi mới publish sang topic pub/sub của kênh, kết hợp cơ chế gửi `last_seq` định kỳ và gửi ngay sau khi subscribe lại để client ở các kênh im lặng chủ động phát hiện khoảng trống dữ liệu cần bù. Để ngăn chặn tình trạng 48% push notification gửi nhầm tới điện thoại của người đang trực tiếp đọc tin trên laptop, hệ thống sử dụng connection registry tập trung trên Redis có gắn TTL để phân biệt thiết bị đang hoạt động trong 60 giây gần nhất với thiết bị đang chạy nền, đồng thời tự động thu hồi quyền nhận tin của connection khi thành viên bị xóa khỏi kênh. Vấn đề nghẽn ghi khi đếm số tin chưa đọc ở kênh đông người được tháo gỡ bằng cách lưu tổng số tin của kênh (`msg_count`) và mốc đọc của người dùng (`last_read_msg_no`) để tính số tin chưa đọc qua phép trừ, khép lại bằng ca xử lý sự cố cụm pub/sub restart 8 giây và hiện tượng reconnect storm của 9.000 client sau deploy.

### 4. Giữ gateway chạy ổn khi kênh hay phòng có hàng nghìn người

Một gateway dù xử lý tốt hàng chục nghìn connection vẫn có thể cạn kiệt bộ nhớ nếu gặp phải vài trăm client đọc chậm do sóng yếu trong các kênh chat hoặc phòng livestream đông người. Bạn sẽ thiết lập hàng chờ có giới hạn với ngưỡng trần 1 MB cho mỗi connection, phân loại hành vi xử lý theo từng loại dữ liệu: bỏ qua typing, giữ giá trị mới nhất cho presence, cộng dồn lượt thả tim, và chủ động ngắt kết nối kèm mã yêu cầu client resume lại bằng cursor đối với tin nhắn quan trọng. Ở các kênh thông báo quy mô lớn, gateway tối ưu hóa hiệu năng bằng cách mã hóa payload một lần duy nhất, chỉ gửi nội dung đầy đủ cho những connection đang trực tiếp mở kênh, gửi event nhẹ cho người đang xem kênh khác, và chia nhóm 500 connection nhường nhịp cho event loop để không làm tê liệt các kênh xung quanh. Với phòng livestream 30.000 người xem, bạn gom bình luận theo lô mỗi 250 ms, gộp lượt thả tim thành bộ đếm tích lũy riêng của từng gateway rồi đồng bộ qua phép lấy giá trị lớn nhất trên pub/sub, giảm tải số lượng frame truyền tải xuống hơn 110 lần.

### 5. Client cũng là replica của dữ liệu khi app phải dùng được offline

Khi sản phẩm đòi hỏi người dùng phải tiếp tục ghi chú hoặc thao tác bình thường ngay cả khi không có kết nối mạng, client bắt buộc phải đảm nhận vai trò là một replica chứa dữ liệu cục bộ thay vì chỉ là giao diện hiển thị thụ động. Bạn sẽ thiết lập hàng đợi thao tác bền bỉ lưu trên bộ nhớ thiết bị, gắn `op_id` dạng UUIDv7 sinh tại client cho từng hành động để chống trùng lặp, và tuân thủ quy trình đồng bộ chuẩn: kéo các thay đổi mới từ server về trước rồi mới tuần tự gửi các thao tác đang chờ đi. Hai bài học nền tảng đi kèm sẽ vạch rõ giới hạn của các cơ chế gộp dữ liệu: chiến lược Last-Write-Wins âm thầm ghi đè và làm mất dữ liệu khi đồng hồ hệ thống bị lệch hoặc phát sinh thao tác đồng thời, trong khi kiểu dữ liệu phân tán CRDT dù tự động hội tụ dữ liệu bộ đếm mà không cần điều phối nhưng vẫn làm vượt hạn mức mã giảm giá nếu thiếu cơ chế hạn ngạch chia trước.

### 6. OT, sequence CRDT và ký tự đã xóa trong ghi chú dùng chung

Khi hai người cùng chỉnh sửa một đoạn văn bản lúc offline, việc áp dụng thao tác dựa trên chỉ số vị trí thông thường sẽ khiến văn bản bị lệch ký tự và hiển thị khác nhau trên từng thiết bị. Bạn sẽ so sánh hai hướng giải quyết cốt lõi: giải thuật OT sử dụng server trung tâm để biến đổi vị trí thao tác cho app trực tuyến, và sequence CRDT gán định danh duy nhất cho từng ký tự để các thiết bị tự do gộp dữ liệu độc lập. Để giải quyết nghịch lý tài liệu chỉ dài ba trang nhưng dữ liệu đồng bộ phình to gần 5 MB do tích tụ ký tự đã xóa, bạn sẽ thiết lập chính sách dọn dẹp tombstone thận trọng: chỉ xóa hẳn định danh khi mốc đồng bộ của mọi replica hoạt động đều vượt qua sequence của lệnh xóa và tạo snapshot mới cho các client offline quá 30 ngày. Khóa học khép lại bằng tình huống thực tế khi chuyến bay 3 tiếng làm mất sạch dữ liệu do cơ chế Last-Write-Wins ghi đè toàn bộ tài liệu, chuyển đổi sang thư viện CRDT giữ trọn vẹn thao tác và bổ sung logic app tự đánh dấu các đoạn chỉnh sửa chồng lấn để người dùng rà soát.

## Vì sao 200Lab tạo ra khóa học này

Các công cụ lập trình AI hiện nay có thể dựng hoàn chỉnh một gateway WebSocket, bảng lưu tin nhắn hay khung soạn thảo ghi chú chỉ trong vài phút. Khi bạn kiểm thử cục bộ trên máy cá nhân hoặc qua mạng văn phòng ổn định, mọi thứ hoạt động rất mượt mà. Tuy nhiên, khi hệ thống bước vào môi trường thực tế với hàng nghìn người dùng thật, các sự cố kỹ thuật bắt đầu xuất hiện: người dùng đi qua vùng sóng yếu thấy tin nhắn bị mất, tin gửi đi nhảy lên hai lần, bình luận livestream tắc nghẽn cả chục giây, và phần ghi chú soạn thảo suốt chuyến bay biến mất không dấu vết sau lần đồng bộ đầu tiên.

Khi đối mặt với sự cố, phản xạ phổ biến của AI agent là đưa ra các giải pháp chung chung mang tính chắp vá: tải lại toàn bộ lịch sử sau mỗi lần kết nối, dựng cụm pub/sub có lưu trữ phức tạp, hoặc vội vã bật thêm server mới. Những đề xuất này thường làm tăng chi phí vận hành và dồn thêm tải nặng nề lên database, trong khi điểm nghẽn thực sự nằm rải rác trên từng chặng mạng cụ thể lại không được xử lý. Bạn chính là người phải trực tiếp trực ca, trả lời khiếu nại của khách hàng và chịu trách nhiệm khi hệ thống gặp sự cố mất mát dữ liệu.

Các nền tảng nhắn tin quy mô lớn như Slack hay Discord đều từng trải qua và ghi nhận chi tiết những bài toán này. Năm 2017, đội ngũ kỹ thuật của Slack từng phân tích hiện tượng reconnect storm khi cả văn phòng đột ngột mất mạng rồi đồng loạt kết nối lại khiến toàn bộ hệ thống bị quá tải vì các yêu cầu nạp lại trạng thái. Trong sự cố năm 2022, Slack tiếp tục chứng minh rằng dù client có cơ chế retry với backoff và jitter, lượng request dồn dập vẫn làm tê liệt tầng database đang suy yếu. Tương tự, Discord buộc phải tối ưu hóa fan-out bằng cách không gửi dữ liệu đầy đủ cho các session thụ động, bởi hơn 90% kết nối trong các nhóm chat cộng đồng lớn không trực tiếp nhìn vào màn hình kênh.

200Lab tạo ra khóa học này nhằm giúp bạn nắm vững bản chất kỹ thuật bên dưới, tự tin lần ngược từng triệu chứng đo được trên dashboard về đúng chặng kiến trúc gây ra lỗi. Thay vì áp dụng máy móc các sơ đồ phân tán đồ sộ, bạn sẽ biết rõ khi nào một database Postgres duy nhất với kỹ thuật polling là đủ tốt, khi nào cần mở rộng cụm gateway, và cách đưa ra các quyết định kỹ thuật chuẩn xác đi kèm số liệu đo lường cụ thể cho đội ngũ của mình.

## Những vấn đề thường gặp khi app có tính năng realtime

Khi app gặp hiện tượng mất tin, lặp tin hay phản hồi chậm chạp, phản xạ tự nhiên của lập trình viên là vá lỗi tức thời trên giao diện hoặc tăng cấu hình server. Các triệu chứng đo được dưới đây cho thấy những cách xử lý vội vã đó thường đi sai hướng, bởi nguyên nhân gốc rễ bắt nguồn từ những chặng mạng cụ thể trên đường đi của dữ liệu:

- Gateway giữ 31.000 connection dù chỉ có 18.000 người online và ngốn 2,9 GB bộ nhớ — Client mất mạng không gửi được frame close khiến connection ma tích tụ liên tục trong RAM khi gateway thiếu cơ chế heartbeat định kỳ.
- Reconnect thành công nhưng vẫn thiếu 3.300 trong 410.000 tin nhắn mỗi ngày — Client không gửi kèm cursor khi kết nối lại, còn gateway chỉ đẩy những tin mới phát sinh sau thời điểm mở socket.
- Tin nhắn gửi từ điện thoại bị lặp lại hai lần liên tiếp khi mạng chập chờn — Server đã lưu tin an toàn vào database nhưng phản hồi ack bị thất lạc khi dữ liệu dạng byte gửi qua mạng, client gửi lại mà database không có constraint khử trùng lặp theo ID.
- Cụm Redis restart 8 giây khiến 1.240 tin nhắn đã lưu trong database không tới người nhận online — Pub/sub không lưu dữ liệu làm lỡ đợt phát tin tức thời, trong khi client ở các kênh im lặng không có tin nhắn kế tiếp để nhận biết khoảng trống sequence.
- Người dùng đang chat trên laptop mà điện thoại vẫn nhận push notification cho từng tin — Gateway nhận tin chỉ kiểm tra danh sách socket trong bộ nhớ cục bộ thay vì tra cứu registry dùng chung giữa các gateway.
- Database nhận 3.800 lệnh ghi mỗi giây với 70% là cập nhật số tin chưa đọc dù app chỉ có 40 tin nhắn mới — Ứng dụng cộng dồn bộ đếm cho từng thành viên của kênh thay vì tính số tin chưa đọc bằng hiệu giữa số tin của kênh và mốc đọc của người dùng.
- Bình luận livestream trễ 9 giây dù phòng 30.000 người đã chia đều cho ba gateway — Mỗi người xem phải nhận hơn 740 frame rời rạc mỗi giây khiến bình luận bị nghẽn sau hàng trăm frame thả tim và frame thông báo vào phòng.
- Ghi chú soạn thảo suốt 3 tiếng lúc offline bị ghi đè hoàn toàn sau khi có mạng — Cơ chế đồng bộ so sánh mốc thời gian cập nhật của toàn bộ tài liệu và giữ lại bản sửa đổi muộn hơn từ điện thoại.

Mỗi vấn đề trên đều tương ứng với một bài học chuyên sâu trong khóa, giúp bạn lần ngược từ số liệu metric về đúng chặng kiến trúc bị hở và áp dụng giải pháp bền vững.

## Bạn sẽ học theo cách nào

- **Xuất phát từ triệu chứng kỹ thuật có thật** — Mỗi bài học đều mở đầu bằng các dữ liệu đo đạc thực tế mà bạn thường gặp khi vận hành: dòng log lỗi, cảnh báo trần RAM, biểu đồ CPU database, tỉ lệ phản hồi rỗng hay ticket phản ánh lỗi từ người dùng.
- **Thu nhỏ mô hình trước khi vào hệ thống lớn** — Mọi cơ chế phức tạp đều được phân tích trước trên các kịch bản thu nhỏ gồm hai client và vài tin nhắn, kết hợp sơ đồ luồng dữ liệu và bảng theo dõi sequence từng giây để bạn thấy rõ biến động trạng thái ở từng chặng.
- **Dự đoán và kiểm chứng qua bài tập** — Các câu hỏi tương tác yêu cầu bạn tự tính toán và dự đoán kết quả trước khi đối chiếu với giải pháp chuẩn, giúp bạn rèn luyện phản xạ phát hiện điểm nghẽn kiến trúc.
- **Thực hành kiểm chứng với demo kit Docker** — Các bài tình huống trọng tâm đi kèm demo kit chạy trên Docker để bạn cùng AI agent tái hiện chính xác lỗi mất mạng, đo đạc chỉ số trước và sau khi tối ưu hóa mã nguồn.

## Khóa học dành cho ai

1. **Junior developer và vibe coder** — Bạn đang phát triển app có tính năng chat, trạng thái online hay tài liệu cộng tác cùng AI agent trên nền Postgres, cần nắm vững nguyên lý vận hành để chẩn đoán chính xác lỗi mất tin, lặp tin hay xung đột dữ liệu.
2. **Kỹ sư backend thiết kế kiến trúc realtime** — Bạn cần bộ tiêu chí kỹ thuật và số liệu đo đạc cụ thể để thẩm định các đề xuất chuyển đổi sang WebSocket, mở rộng cụm gateway với pub/sub hoặc tích hợp CRDT từ đồng đội và AI agent.
3. **Lập trình viên phát triển app offline-first** — Bạn xây dựng các tính năng cho phép đọc và sửa dữ liệu khi mất kết nối mạng, cần thiết kế hàng đợi thao tác bền bỉ tại client và chọn giải thuật gộp bản sửa phù hợp cho từng loại dữ liệu.

## Những điều cần lưu ý

- **Yêu cầu kiến thức nền tảng** — Khóa học không đòi hỏi bạn phải có kinh nghiệm vận hành cụm Kubernetes hay cấu hình load balancer phức tạp; bạn chỉ cần từng làm app nhận request và ghi Postgres trong transaction, từng gọi API bằng fetch, đọc được TypeScript, SQL và log, kể cả khi code do agent viết.
- **Mối liên hệ với các khóa System Design liên quan** — Năm bài nền tảng được trích chọn từ các khóa học về kiến trúc event-driven, hệ thống chịu tải cao và dữ liệu phân tán; các cơ chế như idempotency key, outbox pattern hay retry storm được giải thích trực tiếp theo ngữ cảnh realtime mà không bắt buộc bạn phải học khóa nền trước.
- **Không hướng dẫn cấu hình nền tảng realtime thương mại** — Khóa học không đi vào chi tiết cấu hình của các dịch vụ đám mây cụ thể; thay vào đó, bạn tự tay thiết kế gateway, sequence theo kênh và hàng đợi thao tác trên nền Postgres và Redis để hiểu rõ bản chất bên dưới mọi thư viện.
- **Số liệu minh họa phục vụ tính toán kỹ thuật** — Các thông số về lượng người online, số lượng connection hay tần suất frame trong bài học được thiết kế nhất quán để làm rõ công thức tính tải; khi triển khai thực tế, bạn sẽ dùng đúng các công thức này với số liệu đo được từ hệ thống của chính mình.

## Bắt đầu từ đâu

Bài học đầu tiên mở đầu bằng tình huống app chat nhóm chạm mốc 8.000 người online cùng lúc khiến database quá tải và đề xuất quen thuộc từ agent: chuyển toàn bộ sang WebSocket. Khi lần theo trọn vẹn đường đi của một tin nhắn từ người gửi đến người nhận, bạn sẽ thấy WebSocket chỉ thay đổi chặng truyền dữ liệu cuối cùng xuống trình duyệt, trong khi các sự cố mất tin, trùng tin hay trễ tin lại phát sinh ở bốn chặng mạng hoàn toàn khác nhau. Bài học đặt ở vị trí khởi đầu để trang bị cho bạn ba câu hỏi kỹ thuật cốt lõi giúp thẩm định mọi đề xuất kiến trúc trước khi bắt tay vào chỉnh sửa mã nguồn.

## Chương trình

- Chuyển app chat sang WebSocket là xong, hay cần phải làm thêm gì nữa? (miễn phí)
- Từ 100 tới 100.000 người online, app chat cần thêm gì ở mỗi nấc? (miễn phí)

### Từ polling sang một gateway: tin nhắn không mất, không trùng

- 95% request polling trả về rỗng, nên dùng SSE hay WebSocket? (miễn phí) · kit cho agent
- Gateway giữ 31.000 connection dù chỉ có 18.000 người online · quiz
- Chấm online vẫn sáng dù người dùng đã tắt app từ hôm qua · quiz
- Đọc bảng event theo id khiến consumer bỏ sót event commit muộn · quiz · kit cho agent
- Vì sao reconnect thành công mà vẫn thiếu tin nhắn? · quiz
- Client gửi lại khi network chập chờn nên tin nhắn hiện hai lần · quiz
- Tình huống: mất network 5 giây giữa lúc cả nhóm đang nhắn tin · kit cho agent

### Chạy nhiều gateway mà tin nhắn vẫn tới mọi thiết bị

- Hai service đọc chung một queue thì mỗi service chỉ nhận một phần message (miễn phí) · quiz · kit cho agent
- Thêm gateway thứ hai thì một nửa tin nhắn không tới người nhận · quiz
- Đang đọc trên laptop mà điện thoại vẫn nhận push cho từng tin · quiz
- Vì sao đếm tin chưa đọc lại tốn lệnh ghi hơn cả lưu tin nhắn? · quiz
- Tình huống: pub/sub restart 8 giây làm 1.240 tin nhắn không tới · kit cho agent

### Gateway phải làm gì khi kênh hay phòng có hàng nghìn người?

- Hàng chờ trong RAM phình to khi service nhận việc nhanh hơn tốc độ xử lý
- Vì sao vài trăm client đọc chậm chiếm hết bộ nhớ của gateway? · quiz
- Tin gửi vào kênh 12.000 người mất hơn 2 giây mới tới người cuối · quiz
- Tình huống: bình luận livestream trễ 9 giây khi phòng quá đông · kit cho agent

### Sửa dữ liệu khi offline rồi gộp bản sửa từ nhiều thiết bị

- Ghi chú tạo lúc offline hiện thành hai bản trên server · quiz
- Last-write-wins âm thầm ghi đè bản sửa địa chỉ giao hàng · quiz
- Mã giảm giá vượt giới hạn dù counter CRDT không đếm sót lượt nào · quiz
- Hai người cùng sửa một đoạn thì mỗi thiết bị hiện một nội dung · quiz
- Ghi chú chỉ dài ba trang nhưng dữ liệu đồng bộ nặng gần 5 MB · quiz
- Tình huống: sửa ghi chú 3 tiếng lúc offline, đồng bộ xong mất hết · kit cho agent
