Files
2026-09-08 12:35:40 +07:00

20 KiB

section, title, status, version, reviewer_notes
section title status version reviewer_notes
03 Thiết kế kiến trúc approved 1

3. Thiết kế kiến trúc (System Architecture Design)

3.1 Mô hình kiến trúc

Lựa chọn: Kiến trúc hướng dịch vụ theo bounded-context (Coarse-grained Service-Oriented / "modular microservices"), kết hợp Event-Driven cho các luồng bất đồng bộ

Hệ thống được chia thành khoảng 10 service nghiệp vụ độc lập (mỗi service sở hữu dữ liệu riêng — database-per-service), giao tiếp đồng bộ qua REST cho các thao tác request/response và bất đồng bộ qua message broker (Kafka/Amazon MSK, hoặc SQS/SNS cho các luồng đơn giản hơn) cho các quy trình chuỗi nhiều bước (đặt hàng → thanh toán → trừ tồn kho → tính hoa hồng → payout → thông báo).

Đây không phải microservices chi tiết theo từng entity (tránh over-engineering), mà là mô hình "modular monolith được service hoá theo domain lớn" — mỗi service tương ứng một bounded context nghiệp vụ rõ ràng, đủ nhỏ để một nhóm 3-6 kỹ sư sở hữu, đủ lớn để tránh chi phí vận hành/network overhead của hàng chục nano-service.

Danh sách service và đối chiếu với FR/NFR

Service Trách nhiệm chính FR phục vụ NFR/ràng buộc liên quan
Identity & Access Service Đăng ký/đăng nhập email-password, OAuth Google/Facebook, MFA cho Admin/Seller, phát hành JWT/session FR-01, FR-02, FR-27 NFR-04 (bảo mật), tách riêng để cô lập rủi ro credential/PII
Catalog & Inventory Service Quản lý Product/SKU/Category, tồn kho do seller cập nhật, wishlist, quản trị catalog toàn sàn (admin ẩn/gỡ sản phẩm vi phạm) FR-04 (dữ liệu gốc), FR-10, FR-18, FR-24 NFR-01, NFR-06 (đa ngôn ngữ nội dung sản phẩm), NFR-07
Search subsystem (thành phần đọc, không phải service độc lập có team riêng) Chỉ mục tìm kiếm/filter sản phẩm (OpenSearch), đồng bộ qua event từ Catalog FR-04 (tìm kiếm) NFR-01 (<2s), NFR-02 (cache/CDN, chịu tải đỉnh flash sale)
Cart & Order Service Giỏ hàng đa seller, checkout, tách đơn theo seller, vòng đời đơn hàng, tiếp nhận yêu cầu đổi trả/khiếu nại, xem đơn theo seller FR-05, FR-06, FR-08, FR-09, FR-19 NFR-01 (checkout <3s), NFR-02 (queue hấp thụ đột biến đặt hàng flash sale)
Payment Service Tích hợp VNPay/Momo, xử lý luồng COD, đối soát giao dịch, không lưu dữ liệu thẻ FR-07 NFR-04, NFR-05 (giảm phạm vi PCI-DSS bằng cách cô lập service này và không lưu card data)
Seller Management Service Onboarding & KYC (upload/duyệt giấy tờ), quản trị seller (khoá/duyệt), dashboard báo cáo doanh thu FR-17, FR-20, FR-23 NFR-04 (PII giấy tờ KYC lưu S3 mã hoá riêng biệt), NFR-05
Commission & Payout Service Cấu hình bảng hoa hồng theo ngành hàng, tính hoa hồng, lịch payout hàng tuần, kỳ giữ tiền (hold), tạo lệnh chuyển khoản ngân hàng FR-21, FR-22 NFR-05 (tuân thủ tài chính), tách riêng khỏi Seller Management vì đây là luồng tài chính nhạy cảm cần audit trail riêng
Promotion & Loyalty Service Cấu hình mã giảm giá/khuyến mãi, tích/đổi điểm thưởng, xếp hạng thành viên FR-13, FR-14 NFR-07
Review Service Đánh giá/nhận xét sản phẩm sau khi mua FR-11 NFR-01
Notification Service Gửi email/SMS xác nhận đơn hàng, cập nhật trạng thái giao hàng, là consumer của các domain event FR-12 NFR-02 (qua queue, không chặn luồng chính), NFR-06 (nội dung đa ngôn ngữ)
Shipping & Fulfillment Service Điều phối đóng gói/tồn kho vận hành, tích hợp GHN/GHTK, cập nhật trạng thái giao hàng, hỗ trợ Ops/Warehouse FR-26 NFR-01, NFR-08
Dispute/CSR handling Xử lý tranh chấp — triển khai như module trong Cart & Order Service với quyền truy cập mở rộng cho CSR/Admin (không tách service riêng vì khối lượng nghiệp vụ chưa đủ lớn để cần đội riêng) FR-25 NFR-04 (kiểm soát quyền truy cập CSR ở mức đọc + ghi có giới hạn)

Ghi chú: FR-15 (đa ngôn ngữ) và FR-16 (đa tiền tệ hiển thị) không phải là service riêng mà là năng lực xuyên suốt (cross-cutting) được triển khai qua i18n framework ở tầng frontend/BFF và trường ngôn ngữ/tỷ giá lưu ở Catalog & Pricing config — phục vụ NFR-06.

Đối chiếu quyết định kiến trúc với NFR/ràng buộc

  • NFR-02 (scale-out, cache, CDN, MQ ngay từ đầu) + quy mô "large" → đây là lý do chính không chọn Monolith đơn khối: cần scale độc lập Catalog/Search (đọc nhiều) và Cart/Checkout (ghi nhiều, đột biến flash sale) mà không kéo theo toàn bộ hệ thống. Message broker (Kafka/MSK) tách rời các bước xử lý sau khi đặt hàng thành công (tính hoa hồng, payout, notification, loyalty) để không làm chậm phản hồi checkout.
  • NFR-01 (checkout <3s, catalog/search <2s ngay cả tải đỉnh) → Search tách thành subsystem riêng dùng OpenSearch + cache Redis, không query trực tiếp DB giao dịch; Cart & Order Service dùng cache cho giỏ hàng (Redis) và queue để đệm đơn hàng khi tải đỉnh thay vì xử lý đồng bộ toàn bộ chuỗi nghiệp vụ.
  • NFR-05/PCI-DSS scope giảm → Payment Service là biên cô lập duy nhất giao tiếp với VNPay/Momo; không service nào khác lưu trữ thông tin thẻ; giảm phạm vi kiểm toán PCI-DSS xuống 1 service thay vì toàn hệ thống.
  • NFR-04 (PII, giấy tờ KYC) → Seller Management Service lưu file KYC trong S3 bucket riêng có mã hoá + access policy giới hạn (chỉ Seller Management Service và Admin), tách khỏi Identity Service để giảm bề mặt tấn công.
  • FR-06 checkout tách đơn theo seller + FR-21/22 commission/payout → tách Commission & Payout thành service riêng để có audit trail tài chính độc lập, tránh commission logic bị lẫn với logic vận hành seller (onboarding/KYC) vốn thay đổi thường xuyên hơn.
  • NFR-07 (maintainability, module hoá theo nhóm) → ranh giới service theo domain cho phép các đội catalog/order/seller/payment phát triển và release độc lập, khớp với ghi chú NFR-07 trong mục 2.
  • NFR-08 (vận hành, escalation 24/7 cho sự cố nghiêm trọng) → các service giao dịch cốt lõi (Cart & Order, Payment, Identity) được ưu tiên chạy multi-AZ với auto-scaling và health check chặt hơn các service ít quan trọng hơn (Review, Promotion).

Trade-off và phương án bị loại

Phương án Lý do cân nhắc Lý do loại/không chọn hoàn toàn
Monolith truyền thống (1 codebase, 1 DB) Đơn giản triển khai, phù hợp đội nhỏ, chi phí vận hành thấp Loại — không đáp ứng NFR-02 (yêu cầu scale-out ngang từ đầu) và không cho phép scale độc lập Catalog/Search khỏi Checkout khi tải đỉnh flash sale; rủi ro một lỗi nhỏ ở module ít quan trọng (VD Review) có thể ảnh hưởng uptime toàn hệ thống (mâu thuẫn NFR-03 99.9%)
Microservices chi tiết (chia theo từng entity, 20-30+ service) Scale/độc lập tối đa theo lý thuyết Loại — độ phức tạp vận hành (distributed tracing, service mesh, quản lý hàng chục pipeline CI/CD) vượt quá nhu cầu thực tế của MVP; ngân sách/timeline chưa xác định (giả định #7, mục 5 brief) → rủi ro chậm tiến độ; chọn mức "coarse-grained" cân bằng hơn
Modular Monolith (module hoá trong 1 process, chưa tách service) Giữ đơn giản vận hành, vẫn module hoá code theo domain Cân nhắc làm bước đệm hợp lý cho giai đoạn đầu, nhưng không chọn làm kiến trúc mục tiêu vì NFR-02 yêu cầu rõ scale-out ngang và MQ ngay từ đầu — nếu chọn modular monolith sẽ cần re-architect sớm khi traffic tăng, tốn kém hơn là tách service hợp lý từ đầu cho các domain đã biết rõ tải cao (Catalog/Search, Checkout)
Event-Driven thuần tuý (toàn bộ giao tiếp qua event, không REST) Độ tách rời (decoupling) cao nhất Loại một phần — các luồng cần phản hồi tức thời cho người dùng (đăng nhập, xem catalog, checkout, thanh toán) phù hợp hơn với REST đồng bộ; event chỉ dùng cho luồng nghiệp vụ chuỗi phía sau (post-order processing) để tránh độ trễ cảm nhận (perceived latency) không cần thiết

3.2 Sơ đồ thành phần & triển khai (Component & Deployment Diagram)

flowchart TB
    subgraph Clients
        WebCustomer["Web Storefront (Customer/Guest)\nResponsive SPA"]
        SellerPortal["Seller Portal"]
        AdminPortal["Admin/Ops/CSR Backoffice"]
    end

    CDN["CloudFront CDN\n(static assets, ảnh sản phẩm)"]
    WAF["AWS WAF"]
    ALB["Application Load Balancer"]
    APIGW["API Gateway / BFF layer\n(routing, auth check, rate limit)"]

    subgraph CoreServices["Core Services (ECS Fargate / EKS, auto-scaling)"]
        IDSvc["Identity & Access Service"]
        CatalogSvc["Catalog & Inventory Service"]
        SearchSvc["Search subsystem\n(OpenSearch)"]
        CartOrderSvc["Cart & Order Service\n(+ Dispute handling)"]
        PaymentSvc["Payment Service"]
        SellerSvc["Seller Management Service\n(KYC/onboarding)"]
        CommissionSvc["Commission & Payout Service"]
        PromoLoyaltySvc["Promotion & Loyalty Service"]
        ReviewSvc["Review Service"]
        NotifySvc["Notification Service"]
        ShippingSvc["Shipping & Fulfillment Service"]
    end

    Redis[("ElastiCache Redis\ncache, session, giỏ hàng")]
    RDS[("RDS PostgreSQL Multi-AZ\ndatabase-per-service")]
    S3[("S3\nảnh sản phẩm, KYC docs, invoice")]
    MQ["Message Broker\n(Amazon MSK/Kafka hoặc SQS/SNS)"]

    subgraph External["Dịch vụ bên ngoài"]
        VNPay["VNPay"]
        Momo["Momo"]
        GHN["GHN"]
        GHTK["GHTK"]
        EmailSMS["Email/SMS Provider\n(SES/SNS hoặc SendGrid/Twilio)"]
        Bank["Ngân hàng\n(chuyển khoản payout)"]
        OAuth["Google/Facebook OAuth"]
    end

    WebCustomer --> CDN
    WebCustomer --> WAF
    SellerPortal --> WAF
    AdminPortal --> WAF
    WAF --> ALB --> APIGW

    APIGW --> IDSvc
    APIGW --> CatalogSvc
    APIGW --> SearchSvc
    APIGW --> CartOrderSvc
    APIGW --> PaymentSvc
    APIGW --> SellerSvc
    APIGW --> CommissionSvc
    APIGW --> PromoLoyaltySvc
    APIGW --> ReviewSvc
    APIGW --> ShippingSvc

    IDSvc --> RDS
    IDSvc --> OAuth
    CatalogSvc --> RDS
    CatalogSvc --> S3
    CatalogSvc -.event.-> MQ
    MQ -.sync index.-> SearchSvc
    SearchSvc --> Redis

    CartOrderSvc --> RDS
    CartOrderSvc --> Redis
    CartOrderSvc -.event.-> MQ
    PaymentSvc --> RDS
    PaymentSvc --> VNPay
    PaymentSvc --> Momo
    PaymentSvc -.event.-> MQ

    SellerSvc --> RDS
    SellerSvc --> S3

    MQ -.consume.-> CommissionSvc
    CommissionSvc --> RDS
    CommissionSvc --> Bank

    MQ -.consume.-> PromoLoyaltySvc
    PromoLoyaltySvc --> RDS

    ReviewSvc --> RDS

    MQ -.consume.-> NotifySvc
    NotifySvc --> EmailSMS

    ShippingSvc --> RDS
    ShippingSvc --> GHN
    ShippingSvc --> GHTK
    MQ -.consume.-> ShippingSvc

Ghi chú kiến trúc triển khai:

  • Mỗi service chạy container hoá trên ECS Fargate (hoặc EKS nếu cần kiểm soát sâu hơn), auto-scaling group riêng theo tải thực tế của từng domain (Catalog/Search và Cart/Order được cấp cấu hình auto-scale nhanh hơn cho mùa flash sale).
  • Database theo mô hình "database-per-service" trên RDS PostgreSQL Multi-AZ; không service nào truy cập trực tiếp DB của service khác — chỉ qua API hoặc event.
  • Redis (ElastiCache) dùng chung cho cache catalog/search, lưu session, và giỏ hàng (giỏ hàng cần độ trễ thấp, có thể chấp nhận mất dữ liệu tạm thời thấp).
  • Message broker là xương sống cho các luồng bất đồng bộ: OrderPlaced, PaymentConfirmed, OrderDelivered (khởi động đếm hold), CommissionCalculated, PayoutScheduled, InventoryReserved, ReviewEligible, LoyaltyPointsEarned, NotificationRequested.
  • API Gateway/BFF đảm nhiệm xác thực token (JWT), rate limiting, và có thể tách thành 3 BFF nhỏ (Customer BFF, Seller BFF, Admin BFF) để tối ưu payload riêng cho từng loại client — chi tiết endpoint sẽ do api-designer đặc tả ở mục 4.
  • Thiết kế chi tiết bảo mật (mã hoá at-rest/in-transit, KMS, WAF rule cụ thể) thuộc mục 8; ở đây chỉ thể hiện vị trí kiến trúc của các control đó (WAF, S3 mã hoá, cô lập Payment Service).

3.3 Môi trường triển khai (Environments)

Môi trường Kích cỡ hạ tầng Dữ liệu Feature flag Quyền truy cập
Dev 1 instance/service, cấu hình nhỏ nhất (VD Fargate 0.25-0.5 vCPU), RDS single-AZ, không cần OpenSearch cluster nhiều node Dữ liệu giả lập (seed/synthetic), không chứa PII/KYC thật Tất cả feature flag mặc định bật để dev/test tính năng mới Đội kỹ sư phát triển; không giới hạn IP
Staging Cấu hình gần giống Production nhưng scale nhỏ hơn (1-2 instance/service), RDS Multi-AZ nhỏ, OpenSearch cluster nhỏ Dữ liệu đã ẩn danh hoá (anonymized) từ Production hoặc dữ liệu giả lập quy mô lớn hơn Dev để test hiệu năng; không đưa PII/KYC thật vào Staging (tuân thủ NĐ13/2023) Feature flag phản ánh trạng thái sắp release (dùng để UAT/regression trước khi lên Production) Đội QA, Product Owner, stakeholder UAT; giới hạn qua VPN/IP allowlist
Production Auto-scaling theo tải thực tế, RDS Multi-AZ + read replica cho các bảng đọc nhiều (Catalog), OpenSearch cluster đa node, CDN toàn cầu qua CloudFront Dữ liệu thật (PII khách hàng/seller, giao dịch thanh toán, KYC) — mã hoá at-rest, phân quyền truy cập nghiêm ngặt Feature flag kiểm soát rollout dần (canary/phần trăm người dùng) cho tính năng rủi ro cao (VD thay đổi luồng thanh toán/commission) Chỉ đội vận hành (Ops) và Admin được cấp quyền truy cập hạ tầng qua IAM role có audit log; không truy cập DB Production trực tiếp trừ trường hợp khẩn cấp có phê duyệt

Ghi chú: cả 3 môi trường đều nằm trên AWS theo giả định #7/#10 (mục 1.4 — 01-tong-quan.md). Production yêu cầu hỗ trợ vận hành giờ hành chính kèm escalation 24/7 cho sự cố nghiêm trọng (NFR-08) — chi tiết on-call/runbook thuộc mục 9 (Kế hoạch vận hành & Kiểm thử).

3.4 Tích hợp bên thứ ba

Dịch vụ Giao thức Timeout/Retry Fallback khi lỗi Trách nhiệm
VNPay REST/HTTPS (redirect + callback/IPN xác nhận giao dịch) Timeout gọi API: 10s; retry callback xử lý idempotent tối đa 3 lần với backoff (do VNPay có thể gọi lại IPN) Nếu callback không nhận được sau ngưỡng thời gian, đơn hàng chuyển trạng thái "chờ xác nhận thanh toán" và có job đối soát định kỳ (reconciliation) gọi API tra cứu giao dịch; khách hàng được thông báo trạng thái tạm thời Payment Service
Momo REST/HTTPS (tương tự VNPay: redirect + IPN) Timeout 10s; retry callback idempotent tối đa 3 lần Tương tự VNPay — job đối soát định kỳ tra cứu trạng thái giao dịch qua API Momo Payment Service
COD (thu tiền mặt khi giao) Không phải tích hợp API bên ngoài — là luồng nghiệp vụ nội bộ, xác nhận thu tiền do đơn vị vận chuyển/Ops cập nhật thủ công hoặc qua webhook GHN/GHTK Không áp dụng timeout API; SLA xác nhận thu tiền phụ thuộc đơn vị vận chuyển Nếu đơn vị vận chuyển không cập nhật trạng thái thu tiền đúng hạn, CSR có quy trình đối soát thủ công định kỳ Cart & Order Service (trạng thái đơn) + Shipping & Fulfillment Service
GHN REST/HTTPS (tạo vận đơn, tra cứu trạng thái, webhook cập nhật) Timeout 8s; retry tạo vận đơn tối đa 3 lần với backoff; webhook xử lý idempotent Nếu GHN không phản hồi, hệ thống chuyển sang thử tạo vận đơn qua GHTK (nếu seller/khu vực hỗ trợ) hoặc đưa vào hàng đợi retry thủ công cho Ops xử lý Shipping & Fulfillment Service
GHTK REST/HTTPS (tương tự GHN) Timeout 8s; retry tối đa 3 lần Tương tự GHN — fallback chéo hoặc hàng đợi retry thủ công Shipping & Fulfillment Service
Email/SMS Provider (đề xuất: AWS SES cho email + AWS SNS/hoặc nhà cung cấp nội địa cho SMS — nhà cung cấp cụ thể chưa chốt, xem giả định) REST/HTTPS hoặc SDK, gửi bất đồng bộ qua queue Timeout 5s; retry tối đa 5 lần với exponential backoff (do đây là thông báo không chặn luồng chính) Nếu gửi thất bại sau tất cả lần retry, ghi log lỗi và đưa vào dead-letter queue để CSR/Ops xử lý thủ công (gọi lại/gửi lại); không chặn hoặc rollback đơn hàng Notification Service
Chuyển khoản ngân hàng (payout) Batch file (theo chuẩn ngân hàng, VD NAPAS) hoặc API ngân hàng đối tác — chưa chốt ngân hàng cụ thể, xem giả định Không áp dụng timeout theo nghĩa API tức thời; SLA xử lý batch theo chu kỳ hàng tuần; retry submit file nếu bị từ chối do lỗi định dạng Nếu batch payout bị từ chối/thất bại, Commission & Payout Service giữ trạng thái "payout thất bại", cảnh báo Admin, và seller được thông báo chậm trễ; không tự động thử lại chuyển tiền để tránh double-payout — cần xác nhận thủ công Commission & Payout Service + Admin (giám sát)
Google/Facebook OAuth OAuth 2.0 / OpenID Connect (redirect flow) Timeout xác thực 10s Nếu OAuth provider lỗi, Customer vẫn có thể đăng nhập bằng email/password (không phụ thuộc hoàn toàn vào OAuth) Identity & Access Service

3.5 Tóm tắt truy vết

Bảng dưới bổ sung cho Ma trận truy vết ở mục 2.4 (cột "Mục thiết kế liên quan" — phần kiến trúc):

Requirement ID Service/thành phần chịu trách nhiệm chính
FR-01, FR-02, FR-27 Identity & Access Service
FR-03 Identity & Access Service (hồ sơ) + Catalog & Inventory Service (địa chỉ giao hàng liên kết Order)
FR-04, FR-10, FR-18, FR-24 Catalog & Inventory Service + Search subsystem
FR-05, FR-06, FR-08, FR-09, FR-19, FR-25 Cart & Order Service
FR-07 Payment Service
FR-11 Review Service
FR-12 Notification Service
FR-13, FR-14 Promotion & Loyalty Service
FR-15, FR-16 Cross-cutting i18n/currency (BFF/frontend + Catalog config)
FR-17, FR-20, FR-23 Seller Management Service
FR-21, FR-22 Commission & Payout Service
FR-26 Shipping & Fulfillment Service

api-designer sẽ dùng bảng này làm cơ sở để nhóm endpoint theo service; data-modeler dùng ranh giới service ở mục 3.1 làm cơ sở database-per-service khi thiết kế ERD (mục 5).