Using an event-driven architecture to improve Jira Software responsiveness

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

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

Bối cảnh

Board của Next-Gen Jira Software poll mỗi phút để lấy dữ liệu mới. Hậu quả: người khác sửa issue thì phải chờ khoảng một phút mới thấy, và phần lớn request là thừa vì không có gì đổi.

Thay đổi chính

  • JiRT (Jira realtime service): một service nhỏ nối luồng event backend sẵn có với frontend.

  • Nguồn event: đọc từ StreamHub, event bus nội bộ: Kinesis bên trong, at-least-once, mỗi consumer có một SQS queue riêng. Jira vốn đã đẩy event lên đó cho mục đích khác, nên Jira và StreamHub không phải sửa gì.

  • Đẩy tới client: qua FPS (Frontend PubSub), một lớp trừu tượng trên PubNub, có client lib cho web và mobile nên đổi nhà cung cấp được. FPS kiểm tra quyền lúc client subscribe bằng Permissions service.

  • Event chỉ mang định danh, không mang nội dung: quyền có thể đổi giữa lúc subscribe và lúc nhận, nên client phải gọi lại backend để lấy dữ liệu, và lời gọi đó kiểm tra quyền như thường.

  • Định danh chuẩn hoá:

    • ARI cho tài nguyên, ví dụ ari:cloud:jira:<cloud_id>:project/<id>;
    • AVI cho loại event, ví dụ avi:jira:updated:issue.

    Frontend tự chọn event theo ARI/AVI nên không cần sửa backend; team issue view và roadmap đã dùng lại.

  • Chống bão request ở client:

    • bỏ event do chính user gây ra;
    • đệm event khi có request đang chạy hoặc đang kéo thả;
    • xử lý từng event một, event đến trong lúc đó thì bỏ.

Vì sao (theo Atlassian)

Cộng tác cần độ trễ vài giây chứ không phải vài phút. Event-driven tách producer và consumer, nên chỉ cần ghép các khối nền tảng đã có (StreamHub, FPS, Permissions) với một service rất mỏng, và không ảnh hưởng team nào khác.

Bài học cho SWE

  • Chuyển từ polling sang push thường rẻ nếu backend đã phát event; việc chính là định tuyến event tới đúng client.
  • Gửi ID, không gửi dữ liệu qua kênh realtime để không phải lo phân quyền trên kênh đó.
  • Push dễ biến thành bão refetch: cần đệm và giới hạn ở phía client.
  • Khối nền tảng dùng chung (event bus, pub/sub frontend, ID chuẩn) giúp tính năng mới chỉ còn là việc ghép nối (Nền tảng nội bộ cho service (đường ray chung)).

Liên quan