Service-Oriented Architecture: Scaling the Uber Engineering Codebase As We Grow
Bài tóm tắt Uber 2015 2. Tăng trưởng Độ khó: Dễ
Uber · 2015 · 2. Tăng trưởng · Độ khó: Dễ — bài gốc
Bối cảnh
- Uber bắt đầu bằng một monolith cho một sản phẩm (UberBLACK) ở một thành phố (San Francisco). Lúc đầu để mọi logic một chỗ là hợp lý.
- Khi mở thêm thành phố và sản phẩm:
- Component dính chặt vào nhau; continuous integration thành gánh nặng vì deploy là deploy tất cả.
- Số developer tăng nhanh: thêm tính năng, sửa bug, trả nợ kỹ thuật trên một repo cực khó; muốn sửa gì cũng cần "kiến thức truyền miệng".
Thay đổi chính
- Tách monolith thành microservices, theo Amazon, Netflix, SoundCloud, Twitter. Mỗi service một domain hẹp, tự chọn ngôn ngữ và DB. Tháng 9/2015 đã có hơn 500 service; mục tiêu là bỏ hẳn repo monolith trong năm 2015.
- Vấn đề mới, gói trong ba chữ:
- Obviousness: khó tìm service phù hợp; mỗi service một kiểu; contract REST/RPC lỏng lẻo và khác nhau. Một kỹ sư tóm lại: họ đã "biến API monolith thành API monolith phân tán".
- Safety: không có contract chặt thì không deploy độc lập được.
- Resilience: không có cách chuẩn xử lý timeout/sự cố phía client, dễ gây sự cố dây chuyền.
- Giải pháp đang triển khai:
- Apache Thrift làm IDL: định nghĩa kiểu và interface một chỗ, sinh code cho Python, Node, Go.
- Công cụ phát hành client lên pip/npm.
- Thư viện chịu lỗi lấy cảm hứng từ Hystrix (Netflix) và Finagle (Twitter).
Vì sao
Theo Uber: lý do chính là quy mô tổ chức (nhiều developer, deploy chung), cùng với quy mô traffic. Mục tiêu nêu rõ: quyền sở hữu rõ ràng, tổ chức scale được, chịu lỗi tốt hơn.
Bài học cho SWE
- Tách service mà không có contract chặt và thư viện RPC chung thì chỉ thu được một monolith phân tán.
- Đánh đổi chính Uber nêu: công cụ Thrift cho Python/Node còn non; không có header cấp cao nên xác thực và tracing xuyên service khó.
- Đây là điểm khởi đầu. 5 năm sau, với ~2.200 service, Uber phải gom lại theo domain: Uber 2020.
Liên quan
Được nhắc tới trong
Công ty (1)