Service Architecture at SoundCloud — Part 2: Value-Added Services

Bài tóm tắt SoundCloud 2021 3. Quy mô lớn Độ khó: Trung bình

SoundCloud · 2021 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc

Phần 2 của series 3 phần. Phần 1: SoundCloud 2021; phần 3: SoundCloud 2021.

Bối cảnh

  • Sau nhiều năm dùng BFF, logic nghiệp vụ và phân quyền bị nhân bản ở từng BFF và lệch nhau (SoundCloud 2021). Với SoundCloud, lộ track riêng tư hoặc chưa phát hành là kịch bản tệ nhất.
  • Kiến trúc có ba tầng:
    • Edge: các BFF;
    • Value Added: ghép dữ liệu từ service khác thành trải nghiệm;
    • Foundation: khối xây dựng mức thấp cho một domain.

Thay đổi chính

  • Value-Added Service (VAS): service nghiệp vụ trả về một aggregate (entity + value object, theo DDD), ví dụ track kèm metadata, transcoding, chính sách hiển thị. VAS không tự ghép metadata của entity khác: track chỉ giữ user ID của chủ sở hữu.
  • BFF chỉ còn việc ánh xạ aggregate nội bộ sang representation cho client.
  • 2019: Tracks VAS là bản đầu tiên, dùng để kiểm chứng mô hình.
  • 2020: refactor Public API. Endpoint nằm rải giữa Mothership (monolith gốc, cửa chính vào DB) và Public API BFF. Track thì dễ vì đã có Tracks VAS. Playlist thì phải chọn: chép logic phân quyền sang thêm một BFF, hay dựng Playlists VAS. Họ chọn dựng VAS.
  • Các bước:
    1. gom và ghi lại mọi biến thể logic playlist đang có ở các BFF, xin góp ý rồi mới viết service;
    2. unit test cho mọi kịch bản fetch/phân quyền, integration test cho format response;
    3. chuyển hơn 50 endpoint playlist của các BFF chính sang VAS, từng endpoint một, so sánh response giữa hai bản cài đặt. Bước này mất thời gian hơn cả viết service.
  • VAS gọi VAS được (thêm track vào playlist thì Playlists VAS hỏi Tracks VAS xem track có được thấy không), nhưng phải tách để không có phụ thuộc vòng.

Vì sao (theo SoundCloud)

  • Hết code trùng lặp ở các BFF; tối ưu và refactor ở một chỗ.
  • Logic phân quyền nằm trong một codebase nên audit được.
  • Đánh đổi:
    • thêm một service thì thêm chi phí node, monitoring, on-call;
    • thêm một round-trip mạng.
  • Họ cân nhắc làm VAS thành thư viện link vào lúc build (như JVMKit trước đây) nhưng bỏ, vì mỗi service có thể dùng một phiên bản khác nhau và dẫn tới diamond dependency.
  • Contract bằng IDL qua Twinagle (Twirp trên Finagle) giúp đổi VAS an toàn hơn.

Bài học cho SWE

  • Khi entity lõi bị tách thành nhiều microservice, cần một điểm vào chuẩn cho mỗi aggregate, nhất là cho phân quyền. Nếu không, mỗi client sẽ tự ghép và tự phân quyền.
  • Service dùng chung thay vì thư viện dùng chung: đổi version skew lấy một hop mạng.
  • Migrate endpoint từng cái, so response cũ/mới: cùng tinh thần shadow/parallel run như Grab 2016 và Zalando 2021.
  • Phần 3 kể chuyện VAS phình to và tách thành gateway theo domain: SoundCloud 2021.

Liên quan