Kabootar — Swiggy's Communication Platform
Bài tóm tắt Swiggy 2017 2. Tăng trưởng Độ khó: Trung bình
Swiggy · 2017 · 2. Tăng trưởng · Độ khó: Trung bình — bài gốc
Blog Medium custom domain; đọc bản
medium.com/swiggy-bytes/...qua trình duyệt,raw/chỉ là placeholder.
Bối cảnh
- Swiggy (giao đồ ăn, Ấn Độ) cần liên lạc với khách hàng, shipper, nhà hàng và nhân viên chăm sóc khách hàng qua push, SMS, email.
- Trước đây logic gửi nằm rải rác trong microservice của từng team. Theo Swiggy, cách đó ổn khi team nhỏ và các ca dùng tách biệt; khi scale nhanh thì cần một nền tảng chung.
Thay đổi chính
- Yêu cầu: một chỗ cho cả tin giao dịch lẫn marketing với độ ưu tiên khác nhau; fallback và retry; template có ngữ cảnh; lịch gửi; gom template vào campaign để đo open rate, CTA và lọc/làm giàu dữ liệu.
- Đối tượng MESSAGE tự đủ: mọi thông tin cần để gửi nằm trong một object không phụ thuộc trạng thái bên ngoài, nên bất kỳ node nào cũng xử lý được. Message đi qua chuỗi service: Event (nhận event, làm giàu ngữ cảnh) → Campaign → Templating (render, nhúng tracking) → Router (chọn kênh, đẩy tới gateway).
- Mọi domain là state machine (event, message, campaign, tracker) được lưu liên tục; message kẹt ở trạng thái chưa kết thúc thì bị nhặt lại giao cho đúng bộ xử lý.
- Pull thay vì push giữa các service: 8 microservice nối nhau qua RabbitMQ, vì theo Swiggy gọi HTTP/RPC dạng push với thông lượng cao có thể kéo sập cả hệ. Mỗi service có lớp tích hợp (HTTP hoặc queue, nhận RabbitMQ gửi Kafka được), lớp logic lõi, lớp gửi ra; mô hình theo Enterprise Integration Patterns.
- Nền tảng không biết nghiệp vụ: service khác gửi event vào; ai cần biết tin đã đi thì đăng ký webhook hoặc queue. Thông tin user lấy qua một dịch vụ tổng hợp riêng (Grand Maester) nơi các team đăng ký API, để không team nào tự thu thập dữ liệu user mình không sở hữu.
- Retry/fallback nằm trong message: ví dụ "T1, thử lại 2 lần, rồi T2, thử lại 2 lần" lưu thành deque
[T1,T1,T1,T2,T2]; mỗi lần gửi lấy một phần tử; lỗi render thì có thể nhảy thẳng tới template dự phòng. Họ bỏ cách dựng lại trạng thái từ kho lưu trữ vì chậm và đòi DB chịu truy vấn tuỳ ý trên bảng append-only. - Scheduler Samay tách riêng, dựa trên Quartz: đăng ký cron hoặc trigger một lần, báo qua queue/topic/webhook, có chế độ cần ack hoặc không. Đóng gói thành jar nhúng vào mọi microservice: còn một service sống là scheduler còn sống, không tốn tài nguyên riêng.
- Java 8 + Spring Boot (lớp
swiggy-commons), MySQL làm kho giao dịch, Elasticsearch cho báo cáo và truy vấn tuỳ ý; báo cáo theo giờ/ngày/tuần/tháng bằng cron mỗi giờ.
Vì sao (số liệu 2017)
- Thử trên 4 máy m4.xlarge, mỗi service một instance: 1 triệu message trong 15 phút; theo bài thêm instance sẽ rút ngắn đáng kể.
Bài học cho SWE
- Message tự chứa trạng thái tiến trình (kể cả kế hoạch retry/fallback) làm worker không trạng thái và dễ scale; cái giá là message to hơn và đổi kế hoạch giữa chừng khó hơn.
- State machine được lưu là cách đơn giản để phục hồi việc dở dang sau khi node chết, tương tự ý tưởng của workflow engine về sau (Netflix 2021).
- Tách bên "biết user" (dịch vụ tổng hợp) khỏi bên "gửi tin" giữ nền tảng chung không dính nghiệp vụ.
Liên quan
- Slack 2026 · Disney Hotstar 2019 · Segment 2018 (hàng đợi giao tin tới đích ngoài)
- Event-driven, message queue và Kafka · Nền tảng nội bộ cho service (đường ray chung)
#Notification platform#Push#SMS#Email#RabbitMQ#State machine#Retry#Fallback#Quartz#Scheduler#Microservices#Pull-based
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (1)