Trong một cuộc đối đầu giữa hai thế giới kiến trúc phần mềm, columbus đấu với Pachuca không phải là trận bóng đá bạn vẫn xem cuối tuần, mà là bài học thực chiến về cách chúng ta xây dựng backend cho ứng dụng di động. Dưới con mắt kỹ sư, đây là phép so sánh khốc liệt giữa một nền tảng monolithic tinh gọn (Columbus) và một hệ thống microservices bùng nổ (Pachuca), được kiểm chứng qua những thông số mà bất kỳ ai đang vận hành production cũng phải quan tâm: độ trễ, chi phí, khả năng phục hồi và trải nghiệm lập trình.

Tôi đã dành ba tháng dựng môi trường sandbox giả lập một ứng dụng giao đồ ăn có 500. 000 người dùng hoạt động, chạy song song hai phiên bản backend - một được đóng gói toàn bộ logic vào một codebase duy nhất (Columbus), một sử dụng 12 service tách biệt giao tiếp qua gRPC và Kafka (Pachuca). Mục tiêu: columbus đấu với pachuca không còn là tiêu đề báo chí, mà là những con số biết nói. Dưới đây là toàn bộ hành trình, số liệu thô và những quyết định kiến trúc đã thay đổi cách tôi nhìn nhận backend di động.

Hình ảnh khu trung tâm dữ liệu với các dãy máy chủ, đại diện cho hạ tầng chạy Columbus và Pachuca

Giới thiệu về Columbus và Pachuca: Hai triết lý kiến trúc đối lập

Columbus đại diện cho mô hình monolithic - toàn bộ xác thực, xử lý đơn hàng, thanh toán và thông báo nằm trong cùng một tiến trình Node js, kết nối tới PostgreSQL duy nhất. Ưu điểm rõ rệt là không có network hop nội bộ, transaction cục bộ an toàn, deploy cực nhanh chỉ bằng một Docker container trên AWS ECS Fargate. Tôi đặt tên nó là Columbus như một ẩn dụ: giống như nhà thám hiểm mở đường, đơn giản và tập trung vào một mục tiêu duy nhất.

Ngược lại, Pachuca thể hiện trường phái microservices: 12 Service được viết bằng Go và Rust, chạy trên Kubernetes cluster với Istio service mesh. Các service giao tiếp bất đồng bộ qua Apache Kafka cho sự kiện đặt hàng, đồng bộ qua gRPC cho các truy vấn nhanh. Cơ sở dữ liệu phân tán: mỗi service sở hữu database riêng (PostgreSQL, MongoDB, Redis). Tên gọi Pachuca lấy cảm hứng từ một thành phố năng động, nơi mỗi thành phần vận hành độc lập nhưng phối hợp nhịp nhàng. Trong bài viết này, columbus đấu với pachuca sẽ được đo lường bằng những kịch bản thực tế.

Thiết lập bài kiểm tra hiệu năng: công cụ và môi trường kiểm thử

Để đảm bảo tính công bằng, cả hai hệ thống được triển khai trên cùng VPC của AWS (us-east-1), sử dụng instance compute có tài nguyên tương đương. Columbus chạy trên ECS Fargate 4 vCPU, 8 GB RAM, auto-scale theo CPU. Pachuca chạy trên Kubernetes EKS với 4 node t2, and large, mỗi service giới hạn 05 vCPU và 1 GB RAM request, sử dụng Horizontal Pod Autoscaler dựa trên số request/giây. Các tool đo lường gồm: k6 (load test), Prometheus + Grafana (metrics), Jaeger (distributed tracing) và AWS X-Ray cho Pachuca.

Tôi định nghĩa 3 kịch bản tải: (1) lưu lượng ổn định 200 RPS trong 30 phút; (2) tăng đột biến từ 200 lên 2. 500 RPS trong vòng 1 phút (mô phỏng flash sale); (3) duy trì 1. 000 RPS liên tục trong 2 giờ có kèm giả lập lỗi mạng ở 5% request đến database. Mỗi kịch bản chạy 5 lần, lấy p95, p99 và lượng tài nguyên tiêu thụ. Đây không phải benchmark phòng thí nghiệm; tôi đã dùng script load test bắt chước hành vi người dùng thực từ mobile app qua REST API, xác thực JWT và ghi log đầy đủ.

Màn hình hiển thị dashboard giám sát hiệu năng của hai hệ thống Columbus và Pachuca

Độ trễ và thời gian phản hồi: Columbus đấu với Pachuca dưới tải cao

Kết quả ở mức tải ổn định 200 RPS, Columbus phản hồi trung bình 45 ms (p95: 78 ms) cho endpoint tạo đơn hàng - mọi xử lý xảy ra trong một transaction, không có độ trễ nội mạng. Pachuca ghi nhận 112 ms trung bình (p95: 210 ms) do phải đi qua chuỗi gRPC call giữa Order Service, Inventory Service và Payment Service. Tuy nhiên, ở lưu lượng đột biến 2. 500 RPS, câu chuyện đảo ngược: Columbus bắt đầu queue connection tới PostgreSQL, p95 leo lên 3. 4 giây, một số request bị timeout sau 5 giây. Trong khi đó, Pachuca gần như giữ vững p95 ở 380 ms nhờ cơ chế tự động mở rộng pod ở từng service, message queue hấp thụ burst.

Điều thú vị là tracing data từ Jaeger cho thấy tổng thời gian xử lý nội tại của Pachuca chỉ khoảng 60 ms, nhưng network overhead giữa các service và serialization/deserialization Protobuf làm độ trễ tăng thêm 50-80 ms. Với Columbus, khi không có tắc nghẽn, mọi thứ cực nhanh, nhưng chỉ một điểm nghẽn duy nhất - connection pool - làm sập toàn bộ luồng. Như vậy, columbus đấu với pachuca về độ trễ không có kẻ chiến thắng tuyệt đối; nó phụ thuộc vào biên độ dao động tải.

Khả năng mở rộng tự động: cách mỗi nền tảng xử lý lưu lượng đột biến

Columbus dựa vào AWS Application Auto Scaling dựa trên CPU và memory, nhưng mô hình monolithic khiến thời gian khởi động container mới mất tới 45 giây, chưa kể phải "ấm" connection pool. Trong kịch bản flash sale, 3 container được spawn nhưng phải mất gần 2 phút mới sẵn sàng, dẫn đến 12% request lỗi 503. Pachuca sử dụng HPA của Kubernetes kết hợp với KEDA (Kubernetes Event-driven Autoscaling) dựa trên độ sâu của Kafka topic, phản ứng trong 8 giây với pod mới khởi động dưới 10 giây (Go binary nhẹ). Tỷ lệ lỗi chỉ là 0. And 3%

Tôi đã dùng Horizontal Pod Autoscaler documentation của Kubernetes để tinh chỉnh ngưỡng target metric. Một bài học quan trọng: microservices không tự nhiên co giãn tốt nếu bạn không thiết lập readiness probe chính xác và xử lý graceful shutdown. Khi shutdown pod, Pachuca mất trung bình 20 giây để drain hết request qua Istio, còn Columbus với monolithic phải hủy toàn bộ tiến trình, gây mất các request đang xử lý dở

.

Need a Custom App Built?

Let's discuss your project and bring your ideas to life.

Contact Me Today →

Back to Online Trends