Kiến Trúc Hệ Thống Lớn: Blueprint Toàn Diện Cho Ứng Dụng Hàng Triệu Người Dùng
1. Kiến trúc hệ thống tối ưu
Phần 1) Cổng vào và Phân phối (Entrypoint & Distribution)
Route 53 sẽ là dịch vụ DNS, định tuyến người dùng đến CloudFront.
CloudFront (CDN) sẽ chịu trách nhiệm chính trong việc tăng tốc độ tải trang bằng cách phục vụ nội dung tĩnh từ các Edge Location gần người dùng nhất và chuyển tiếp các yêu cầu động về Origin. Toàn bộ kết nối sẽ được bảo mật bằng HTTPS thông qua AWS Certificate Manager.
Phần 2) Lớp Ứng dụng (Application Tier)
Load Balancer: Origin của CloudFront sẽ là một Application Load Balancer (ALB). ALB sẽ phân phối lưu lượng đến lớp compute.
API Gateway: Một Amazon API Gateway sẽ được triển khai sau ALB, đóng vai trò là cửa ngõ duy nhất vào hệ thống microservices. Gateway sẽ xử lý tập trung các tác vụ phi chức năng, bao gồm:
- Authentication & Authorization: Sử dụng AWS Lambda Authorizers để xác thực token (ví dụ: JWT) và thực thi các logic phân quyền phức tạp dựa trên mô hình RBAC/ABAC. Các microservice phía sau sẽ nhận các request đã được xác thực và ủy quyền.
- Caching: Kích hoạt tính năng cache của API Gateway để lưu trữ các response của các endpoint ít thay đổi, giảm tải trực tiếp cho backend.
- Rate Limiting & Throttling: Cấu hình các giới hạn truy cập để bảo vệ hệ thống khỏi các hành vi lạm dụng.
Compute & Orchestration: Lớp compute sẽ được container hóa và vận hành bởi Amazon ECS (hoặc EKS cho các nhu cầu tùy biến nâng cao). Mỗi microservice sẽ là một ECS Service riêng biệt, được cấu hình Auto Scaling để tự động giãn theo các chỉ số như CPU/Memory Utilization hoặc số lượng request.
Giao tiếp Nội bộ (Inter-Service Communication): Trong mô hình Microservices, Client sẽ gọi đến Microservices thông qua API Gateway, còn giữa các Microservice sẽ gọi nhau qua các DNS nội bộ (local DNS) của các Application Load Balancer (ALB) VD: order-service.internal.
- Đồng bộ (Synchronous) - gRPC
- Bất đồng bộ (Asynchronous): Sử dụng Amazon SQS (Simple Queue Service) để tách biệt các tác vụ và tăng khả năng chịu lỗi.
Kết nối Mạng & Bảo mật: Toàn bộ lớp ứng dụng sẽ được triển khai trong các private subnet của một VPC. Kết nối ra internet (để gọi API bên ngoài) sẽ được thực hiện thông qua NAT Gateway. Security Groups và Network ACLs sẽ được cấu hình chặt chẽ để kiểm soát luồng traffic.
Phần 3) Lớp Dữ liệu (Data Tier)
Tùy vào nhu cầu, em sẽ chọn Amazon RDS (MySQL/PostgreSQL) cho dữ liệu có cấu trúc hoặc DynamoDB cho dữ liệu NoSQL.
Để tối ưu cho các ứng dụng đọc nhiều, em sẽ áp dụng mô hình Read Replica. Toàn bộ các tác vụ Ghi (Write) sẽ vào instance Master, còn các tác vụ Đọc (Read) sẽ được phân phối qua các instance Slave.
Data Synchronization: khi CSDL quan hệ không đáp ứng tốt cho việc READ, áp dụng CQRS Pattern (Command Query Responsibility Segregation) tức là sẽ pipeline đồng bộ dữ liệu sang MongoDB hoặc Firebase để phục vụ các truy vấn cần dữ liệu dạng document phức tạp. đồng bộ sang Elasticsearch để phục vụ cho nhu cầu tìm kiếm toàn văn (full-text search).
CSDL phân tán: Khi hệ thống đạt đến quy mô cực lớn, các giải pháp nâng cao hơn như Database Sharding (phân mảnh theo chiều ngang hoặc dọc) sẽ được xem xét để đảm bảo khả năng mở rộng không giới hạn.
Cơ sở dữ liệu phân tán có thể áp dụng thêm phân tán theo chiều ngang: cùng 1 table nhưng dữ liệu mỗi châu lục lưu ở một database khác nhau. Cơ sở dữ liệu phân tán phân tán theo chiều dọc: tách 1 table thành nhiều table khác nhau rồi tách 1 số table ra database khác, nhưng cai này phải liên quan mật thiết đến cấu trúc và chức năng.
Transaction: Chỉ dùng transaction cho những nghiệp vụ 'tới hạn' (critical operations) nơi tính nguyên tử là bắt buộc, ví dụ như quy trình thanh toán hoặc trừ kho, để tránh các rủi ro về deadlock và ảnh hưởng đến hiệu năng.
Phần 4) Khả năng quan sát (Observability)
Thay vì chỉ dựa vào CloudWatch Logs, em đề xuất xây dựng một pipeline quản lý log tập trung. Log từ ECS sẽ được xuất ra S3, và chúng em sẽ dùng Amazon Athena để thực hiện các truy vấn phân tích sâu trên toàn bộ lịch sử log.
Phần 5) Caching
Edge Caching: Sử dụng CloudFront để cache nội dung tĩnh và các API response ít thay đổi tại các điểm gần người dùng nhất.
Application-level Caching: Sử dụng Amazon ElastiCache for Redis làm lớp cache trung tâm. Cụ thể, em sẽ hiện thực hóa Cache-Aside Pattern trong lớp Repository để cache lại các kết quả truy vấn database tốn kém. Đồng thời, Redis cũng được dùng để lưu trữ session người dùng và các dữ liệu đã qua xử lý khác, giúp giảm tải đáng kể cho cả lớp ứng dụng (ECS) và lớp dữ liệu (RDS).
6) Tác vụ real-time (Socket.IO)
Sử dụng Firebase Realtime Database/Firestore hoặc Amazon API Gateway với WebSocket API.
7) Tự động hóa Hạ tầng (Infrastructure Automation)
Bắt buộc phải có cho hệ thống Microservices và quy trình Agile CICD. Sử dụng Terraform hoặc CloudFormation (Infrastructure as Code).
8.) Storage
Sử dụng Amazon S3 để lưu trữ toàn bộ các tài sản như file người dùng upload, hình ảnh, video, tài liệu... Sau đó sử dụng CloudFront để phân phối các file này, giúp tăng tốc độ truy cập cho người dùng và giảm tải hoàn toàn cho backend.
9) Module chuyên dụng
- File template & E-Signature: Document/ Pandadocs
- Marketing & Email: Mautic/Mailchimp
- Workflow: N8N/ Activepieces/ Zapier
10) Transaction cho Microservices
Local transaction ACID: Chỉ dùng transaction cho những nghiệp vụ 'tới hạn' (critical operations) nơi tính nguyên tử là bắt buộc, ví dụ như quy trình thanh toán hoặc trừ kho, để tránh các rủi ro về deadlock và ảnh hưởng đến hiệu năng.
System transaction: sử dụng Saga Pattern, là compensating action cho transaction của Microservices. Sử dụng Orchestrator và Durable State Machine - AWS Step Functions. Step Functions sẽ quản lý trạng thái, gọi đến các Lambda function hoặc các service khác, và xử lý các logic retry/bù trừ. Nó là một Saga Orchestrator được quản lý hoàn toàn (fully managed).
Ví dụ: Phân Tích Saga Pattern với AWS Step Functions
Orchestrator: AWS Step Functions State Machine. Mỗi lần đặt hàng sẽ khởi tạo một "execution" mới của State Machine này.
Các Service: ProcessService: Vai trò của nó giờ đây được chuyển giao cho Step Functions. Logic của nó là định nghĩa của State Machine. OrderService: Xử lý tạo/cập nhật đơn hàng. InventoryService: Xử lý kho (có local transaction). PaymentService: Xử lý thanh toán (có local transaction). ShippingService: Xử lý giao hàng.
Giao tiếp: Step Functions sẽ gọi đến các service này (thông qua API Gateway hoặc gọi trực tiếp Lambda/ECS Task).
Kịch bản 1: PaymentService bị treo/lỗi
Luồng sự kiện:
- Bắt đầu: Một execution của Step Functions được khởi tạo.
- CreateOrder: Step Functions gọi Lambda, OrderService tạo đơn hàng thành công. State Machine chuyển sang bước ReserveInventory.
- ReserveInventory: Step Functions gọi Lambda, InventoryService thực hiện local transaction để trừ kho thành công. State Machine chuyển sang bước ProcessPayment.
- ProcessPayment (Sự cố xảy ra): Step Functions gọi Lambda để thực thi PaymentService.process(). PaymentService bắt đầu local transaction của nó. Tuy nhiên, trong quá trình xử lý, nó gặp lỗi (ví dụ: cổng thanh toán của bên thứ ba trả về lỗi 500, thẻ hết tiền, hoặc chính service bị treo và timeout). Vì có lỗi, local transaction bên trong PaymentService sẽ tự động rollback. Database của PaymentService vẫn ở trạng thái nhất quán (chưa ghi nhận thanh toán). Quan trọng nhất: Lambda function hoặc service sẽ trả về một lỗi (error) cho Step Functions.
- Step Functions Bắt lỗi và Bù trừ (Compensation): Step Functions nhận được tín hiệu lỗi từ bước ProcessPayment. Nó sẽ kiểm tra block Catch của state ProcessPayment. "Catch": [ { "ErrorEquals": ["States.ALL"], "Next": "ReleaseInventory" } ] -> Regel này khớp! Step Functions sẽ không đi tiếp đến ShipOrder, mà sẽ nhảy đến state ReleaseInventory.
- ReleaseInventory (Hành động Bù trừ 1): Step Functions gọi Lambda để thực thi InventoryService.release(). InventoryService thực hiện local transaction để cộng trả lại hàng vào kho. Sau khi thành công, State Machine chuyển sang bước CancelOrder.
- CancelOrder (Hành động Bù trừ 2): Step Functions gọi Lambda để thực thi OrderService.cancel(). OrderService cập nhật trạng thái của đơn hàng thành CANCELLED.
- State Machine kết thúc.
Kết quả: Hệ thống đã trở về trạng thái nhất quán. Đơn hàng bị hủy, kho đã được hoàn trả. Vai trò của Orchestrator (Step Functions) là phát hiện lỗi và điều phối các hành động bù trừ.
Kịch bản 2: ProcessService (Orchestrator - Step Functions) bị treo
Đây là lúc sức mạnh của một dịch vụ bền bỉ (durable) như Step Functions được thể hiện. "Bị treo" trong trường hợp của Step Functions có nghĩa là dịch vụ AWS gặp sự cố nội bộ (cực kỳ hiếm) hoặc một execution bị kẹt.
Luồng sự kiện: Bắt đầu, CreateOrder, ReserveInventory: Diễn ra bình thường. Chuyển sang ProcessPayment: Step Functions đã lưu trạng thái: Trước khi gọi đến PaymentService, Step Functions đã lưu lại một cách bền bỉ trạng thái hiện tại của execution này là "đang thực thi bước ProcessPayment". Trạng thái này được lưu trữ trên hạ tầng nội bộ, có độ bền cao của AWS. Step Functions gửi command PROCESS_PAYMENT đến PaymentService. Sự cố xảy ra: Giả sử ngay sau khi gửi command, toàn bộ dịch vụ Step Functions trong một Availability Zone bị sập (một sự cố rất lớn, nhưng về mặt lý thuyết là có thể). Trong lúc đó, PaymentService vẫn đang xử lý. Giả sử nó xử lý thành công và phát ra event PAYMENT_COMPLETED. Vấn đề: Event này được gửi đi, nhưng không có Orchestrator nào đang "lắng nghe" nó cả. Quá trình Phục hồi của Step Functions (Tự động): AWS sẽ tự động phát hiện sự cố và chuyển các execution sang một Availability Zone khác hoặc khởi động lại dịch vụ. Khi execution của anh "tỉnh dậy", nó sẽ đọc lại trạng thái cuối cùng mà nó đã lưu: "đang thực thi bước ProcessPayment". Nó sẽ kiểm tra xem bước này đã có kết quả chưa. Tùy vào cách tích hợp (ví dụ: dùng callback token), nó có thể đã nhận được event PAYMENT_COMPLETED (nếu event được lưu trong một queue) hoặc nó sẽ thấy bước này đã chạy quá thời gian timeout. Trường hợp Timeout: Nếu nó thấy bước ProcessPayment đã quá timeout mà chưa nhận được phản hồi, nó sẽ coi đó là một lỗi. Và nó sẽ bắt đầu kích hoạt chuỗi bù trừ như trong Kịch bản 1 (nhảy đến ReleaseInventory). Trường hợp nhận được event thành công: Nó sẽ tiếp tục đi đến bước tiếp theo là ShipOrder.
Bản thiết kế kiến trúc hệ thống này được chia sẻ bởi TVD Media. Một hệ thống mạnh mẽ cần một nền tảng vững chắc, bắt đầu từ việc Thiết kế và phát triển website chuyên nghiệp.