5-year Evolution of Ele.me's Transaction System - Part 6
Ele.me · 2020 · 4. Điều chỉnh · Độ khó: Trung bình — bài gốc
Phần cuối của series. Trước: Ele.me 2020; phần 1: Ele.me 2020.
Thay đổi chính
-
Tách giao dịch thuận và nghịch (giữa 2016): giao dịch nghịch (hoàn, huỷ, khiếu nại) chỉ chiếm khoảng 1% đơn nhưng logic phân nhánh phức tạp hơn nhiều. Giao dịch thuận cần hiệu năng, đồng thời, ổn định. Hai bên khác nhau về miền vấn đề và mức yêu cầu, nên chia cả team làm hai.
- Thêm trạng thái "đơn hoàn tất". Mất gần 3 tháng để các team trên dưới thích ứng.
- Dựng hệ hoàn trả nhận phần sau trạng thái đó; đối soát nhận tiền tách khỏi hoàn tiền.
- Chuyển logic dịch vụ hậu mãi sang hệ riêng.
Sai lầm tự nhận: chưa tách hẳn trạng thái khỏi sự kiện nghiệp vụ phía trên, gây nhiều vấn đề ở ranh giới và distributed transaction.
-
ToB/ToD, một thiết kế sai: đầu 2016, khi tách mô hình tự giao hàng (BOD), giao dịch bị cắt thành các đoạn đơn ToB (gói dịch vụ cho merchant) và ToD (giao hàng). Kết quả:
- user và merchant vẫn phải thấy mọi đoạn;
- kênh ToD thành đường duy nhất giữa nền tảng và hệ logistics nên chịu tải nặng;
- dữ liệu đồng bộ offline.
Tác giả từng phản đối nhưng bị bác. Sau đó họ gộp ToB/ToD thành dữ liệu mở rộng của đơn hàng, chỉ đẩy dữ liệu giao hàng cần thiết qua kênh realtime, đổi từ message sang RPC có token idempotent + consumer kéo bù. Lý do: hai data center (nền tảng và logistics) ở hai thành phố, gọi xuyên DC nhiều lần làm xấu trải nghiệm.
-
Kiến trúc phía merchant chia theo tầng kỹ thuật (tầng hạ tầng chung bọc DB/Redis) khiến dữ liệu cùng domain nằm rải ở nhiều service. Họ gom lại theo domain.
-
Thói quen tốt cuối 2016:
- thu hồi quyền repo, quyền release, chuỗi kết nối DB/MQ;
- mỗi 1–2 tháng dọn API không dùng, theo dõi API tăng traffic bất thường, dọn config thừa;
- kiên trì tự động hoá, performance test, diễn tập lỗi;
- "tấn công vấn đề, không tấn công người".
Tổng kết của tác giả
Kiến trúc nên tiến hoá theo nghiệp vụ và có tầm nhìn, không phải theo sự cố. Nhìn lại thì một nửa quá trình tiến hoá của họ đến từ sự cố.
Bài học cho SWE
- Tách service theo khác biệt của miền vấn đề và mức yêu cầu (thuận và nghịch), kèm tách team theo Conway. Không tách theo tầng kỹ thuật (Monolith và microservices — đi và quay lại).
- Cắt một giao dịch thành nhiều "đơn" theo cách tổ chức nội bộ làm phân mảnh trải nghiệm; ranh giới phải theo cái người dùng thấy.
- Thêm một trạng thái vào mô hình lõi (đơn hoàn tất) tốn hàng tháng phối hợp: thiết kế mô hình trạng thái sớm là đáng.