Trong giới phát triển phần mềm, câu chuyện về việc chuyển đổi từ kiến trúc monolith
sang microservices
không còn mới, nhưng không phải lúc nào chúng ta cũng có cơ hội nhìn vào GitHub thực hiện điều đó. Bắt đầu là một khối monolith
vững chắc bằng Ruby on Rails, GitHub đã phục vụ hàng chục triệu developer. Tuy nhiên, khi quy mô công ty và đội ngũ kỹ sư tăng vọt, khối monolith
từng là niềm tự hào bắt đầu bộc lộ những hạn chế.

Khi Monolith không còn là lựa chọn tối ưu
GitHub ra đời năm 2008 và nhanh chóng trở thành một phần không thể thiếu của cộng đồng mã nguồn mở. Được xây dựng trên Ruby on Rails, kiến trúc monolith
của họ đã chứng tỏ sự hiệu quả đáng kinh ngạc, có khả năng scale để phục vụ 50 triệu developer, hơn 100 triệu repository và xử lý hơn 1 tỷ API call mỗi ngày.
Tuy nhiên, vấn đề bắt đầu nảy sinh khi chính GitHub phát triển. Trong vòng 18 tháng, số lượng kỹ sư đã tăng gấp đôi và hơn 70% trong số họ làm việc remote trên khắp các múi giờ. Việc yêu cầu mọi kỹ sư mới, dù chuyên về mảng nào, cũng phải học Ruby và làm quen với một codebase khổng lồ đã trở thành một nút thắt cổ chai, làm chậm quá trình phát triển và onboard nhân sự. Đây chính là lúc đội ngũ kỹ thuật của GitHub nghiêm túc xem xét kiến trúc microservices
.
Cân nhắc giữa Monolith và Microservices
Trước khi đưa ra quyết định, GitHub đã phân tích kỹ lưỡng ưu và nhược điểm của cả hai kiến trúc trong bối cảnh của chính họ.
Ưu điểm của kiến trúc Monolith:
- Infrastructure Simplicity: Một kỹ sư mới có thể thiết lập và chạy toàn bộ hệ thống GitHub trên máy local chỉ trong vài giờ.
- Code Simplicity: Việc phát triển trong một codebase duy nhất giúp loại bỏ các logic phức tạp để xử lý
timeout
,network latency
hay các sự cố mạng giữa các service. - Tổ chức đơn giản: Mọi người đều quen thuộc với cùng một codebase, giúp việc điều chuyển nhân sự giữa các team, các tính năng trở nên dễ dàng hơn.
Ưu điểm của kiến trúc Microservices:
- System Ownership: Các team có ranh giới chức năng rõ ràng thông qua các
API contract
. Điều này trao cho họ quyền tự chủ cao hơn, được tự do lựa chọn stack công nghệ phù hợp nhất cho service của mình miễn là tuân thủAPI contract
. - Separation of Concerns: Kỹ sư mới không cần phải hiểu toàn bộ hệ thống đồ sộ mà chỉ cần tập trung vào service của team mình, giúp rút ngắn đáng kể thời gian onboarding.
- Scaling độc lập: Các service có thể được scale riêng lẻ tùy theo nhu cầu sử dụng thực tế, giúp tối ưu hóa tài nguyên và chi phí.
Sau khi cân nhắc, GitHub quyết định chuyển đổi sang một kiến trúc hướng microservices
. Tuy nhiên, đây không phải là đập đi xây lại. Họ xác định sẽ duy trì một môi trường hybrid, nơi monolith
và microservices
cùng tồn tại trong tương lai gần. Vì vậy, việc tiếp tục cải tiến và bảo trì codebase monolith
vẫn là một ưu tiên.
Chiến lược phân rã Monolith một cách bài bản
Đây là phần quan trọng nhất trong chiến lược của GitHub. Họ không vội vàng tách code thành các service riêng biệt mà tiếp cận một cách có phương pháp.
Bước 1: Bắt đầu từ Data, không phải từ Code
Sai lầm phổ biến nhất khi chuyển sang microservices
là tạo ra một distributed monolith
, một hệ thống vừa mang sự phức tạp của microservices
, vừa có sự thiếu linh hoạt của monolith
. Để tránh cái bẫy này, GitHub khẳng định rằng mỗi service phải sở hữu và kiểm soát hoàn toàn dữ liệu của nó. Mọi truy cập dữ liệu từ bên ngoài đều phải thông qua API.
Họ đã thực hiện điều này bằng cách:
- Xác định ranh giới chức năng: Phân tích database schema của
monolith
để tìm ra các cụm dữ liệu có liên quan đến nhau theo chức năng. Ví dụ: nhóm tất cả các table liên quan đến repository (pull requests, issues, comments) vào một nhóm, các table liên quan đến user vào một nhóm khác. Họ gọi các nhóm này là schema domains. - Giám sát và thực thi: GitHub đã triển khai một công cụ gọi là
query watcher
bên trongmonolith
. Công cụ này sẽ phát hiện và cảnh báo mỗi khi có một query truy vấn dữ liệu từ nhiềuschema domain
khác nhau. - Refactor query: Khi một query vi phạm bị phát hiện, đội ngũ kỹ sư sẽ viết lại nó thành nhiều query nhỏ hơn, mỗi query chỉ truy cập vào một
schema domain
duy nhất. Sau đó, họ sẽ thực hiện các thao tácjoin
cần thiết ở tầng application.
Bước 2: Tách Service
Khi tách các service ra khỏi monolith
, GitHub tuân thủ một nguyên tắc cốt lõi: Dependency direction phải luôn đi từ trong monolith ra ngoài microservice, không bao giờ được theo chiều ngược lại. Nếu một microservice gọi ngược vào trong monolith, nó sẽ lại rơi vào anti-pattern distributed monolith
.
- Ví dụ thực tế: Service cốt lõi đầu tiên mà GitHub tách ra là Authentication và Authorization. Khối
monolith
(Rails) giao tiếp với service này thông qua Twirp, một framework giao tiếp service-to-service tương tựgRPC
. Luồng phụ thuộc rất rõ ràng: monolith (bên trong) gọi đến service xác thực (bên ngoài).
Bước 3: Chú trọng trải nghiệm Developer và dọn dẹp hệ thống
Để khuyến khích các kỹ sư phát triển trên kiến trúc mới, GitHub nhận ra rằng họ cần cung cấp các công cụ hỗ trợ tương đương với những gì có sẵn trong monolith
.
- Shared Tooling: Một ví dụ điển hình là hệ thống
feature flags
, giúp developer trongmonolith
dễ dàng kiểm soát việc ra mắt tính năng mới. Hệ thống này cần được cung cấp cho cả các developer làm việc vớimicroservices
. - Loại bỏ code cũ: Sau khi một service mới đã ổn định và 100% traffic đã được chuyển qua, việc lên kế hoạch xóa bỏ code path cũ trong
monolith
là bắt buộc. Nếu không, đội ngũ sẽ phải gánh chịu chi phí bảo trì cả hai hệ thống song song.
Hành trình chuyển đổi của GitHub cung cấp một case study giá trị cho bất kỳ tổ chức nào đang đứng trước ngưỡng cửa tương tự. Họ đã chọn một chiến lược phân rã có phương pháp, thận trọng và tập trung vào nền tảng.