Làm thế nào để di chuyển từ Monolith sang Microservices mà không làm gián đoạn hệ thống: Chiến lược Strangler Fig!

Mục lục

Di chuyển từ Monolith sang Microservices: Chiến lược Strangler Fig – Bóc tách tính năng Coupon mà không làm gián đoạn

⚡ Mục tiêu: Cung cấp một lộ trình chi tiết, có thể thực thi ngay cho các team Dev/BA/PM junior để tách một tính năng nhỏ (Coupon) ra service riêng, duy trì uptime ≥ 99.9 % và không gây gián đoạn cho hệ thống thương mại điện tử đang vận hành với doanh thu > 100 tỷ VNĐ/tháng.


1. Bối cảnh thị trường & nhu cầu chuyển đổi (2024‑2025)

Nguồn dữ liệu Chỉ số 2024 Chỉ số 2025 (dự báo) Ghi chú
Statista – E‑commerce revenue Vietnam 13,2 tỷ USD 15,8 tỷ USD Tăng trưởng CAGR ≈ 13 %
Cục TMĐT VN – Số lượng giao dịch online 2,4 tỷ giao dịch 2,9 tỷ giao dịch Tăng 20 %/năm
Google Tempo – Thời gian phản hồi trung bình 1,8 s 1,5 s Đòi hỏi latency < 200 ms cho API quan trọng
Shopify Commerce Trends 2025 45 % doanh nghiệp VN dùng monolith 30 % doanh nghiệp VN dùng microservices 15 % chuyển đổi mỗi năm
Gartner – Adoption of Strangler Fig 22 % doanh nghiệp lớn 35 % doanh nghiệp lớn Được xem là “best practice” cho migration

🛡️ Lưu ý: Khi hệ thống đạt mức giao dịch > 2 tỷ/tháng, mỗi gián đoạn 1 s có thể gây mất doanh thu ≈ 200 triệu VNĐ. Do đó, chiến lược “zero‑downtime” là bắt buộc.


2. Tổng quan workflow Strangler Fig (text‑art)

┌─────────────────────┐      ┌─────────────────────┐
│   Monolith (v1)     │      │   New Service (v2)  │
│  - Order            │      │  - Coupon Service   │
│  - Cart             │      │  - API Gateway      │
│  - Payment          │      │  - DB (PostgreSQL)  │
│  - Coupon (legacy) │◀────▶│  - Event Bus (Kafka)│
└─────────────────────┘      └─────────────────────┘
          ▲                         ▲
          │                         │
          │   1. Route request      │
          │   to new service via   │
          │   API Gateway (Canary) │
          ▼                         ▼
   ┌─────────────────────┐   ┌─────────────────────┐
   │   Feature Flag      │   │   Data Sync (CDC)   │
   └─────────────────────┘   └─────────────────────┘
  • Bước 1: Đặt Feature Flag cho coupon, chuyển một phần traffic (5 %) sang service mới.
  • Bước 2: Đồng bộ dữ liệu bằng Change Data Capture (CDC) từ monolith DB sang PostgreSQL của service.
  • Bước 3: Kiểm tra KPI, tăng traffic dần tới 100 % khi ổn định.
  • Bước 4: Loại bỏ mã coupon trong monolith, chuyển toàn bộ traffic.

3. So sánh Tech Stack (4 lựa chọn)

Thành phần Lựa chọn A – Spring Boot + PostgreSQL Lựa chọn B – Node.js (NestJS) + MongoDB Lựa chọn C – Go (Gin) + CockroachDB Lựa chọn D – .NET Core + Azure SQL
Ngôn ngữ Java 17 (LTS) TypeScript 5 Go 1.22 C# 12
Framework Spring Cloud, Spring Data JPA NestJS, TypeORM Gin, GORM ASP.NET Core, EF Core
DB PostgreSQL 15 (RDS) MongoDB Atlas CockroachDB (Serverless) Azure SQL Managed
Message Bus Apache Kafka 3.5 RabbitMQ 3.11 NATS JetStream Azure Service Bus
API Gateway Kong + OIDC Kong + JWT Traefik + mTLS Azure API Management
CI/CD GitHub Actions + Docker GitHub Actions + Docker GitHub Actions + Docker Azure DevOps Pipelines
Observability Prometheus + Grafana Prometheus + Loki Prometheus + Grafana Azure Monitor
Cost (USD/ tháng) 1 200 1 000 1 500 1 300
Độ phổ biến VN ★★★★★ ★★★★☆ ★★★☆☆ ★★★★☆

⚡ Đánh giá: Đối với team có nền tảng Java, Lựa chọn A giảm chi phí đào tạo, tích hợp sẵn Spring Cloud Netflix (Hystrix, Ribbon). Nếu muốn tốc độ triển khai nhanh và giảm tài nguyên, Lựa chọn B là hợp lý.


4. Chi phí chi tiết 30 tháng (đơn vị: USD)

Hạng mục Năm 1 (12 tháng) Năm 2 (12 tháng) Năm 3 (6 tháng) Tổng cộng
Infrastructure (VM, DB, Kafka) 14 400 12 000 6 000 32 400
Licenses & SaaS (Kong, Datadog) 4 800 3 600 1 800 10 200
DevOps (CI/CD, Terraform) 2 400 2 400 1 200 6 000
Team (Dev × 2, QA × 1, PM × 1) 180 000 180 000 90 000 450 000
Training & Docs 3 000 1 500 750 5 250
Contingency (10 %) 20 340 18 150 9 075 47 565
Tổng 224 940 217 650 108 825 551 415

ROI = (Tổng lợi ích – Chi phí đầu tư) / Chi phí đầu tư × 100%
ROI = (1 200 tỷ VNĐ – 551 415 USD) / 551 415 USD × 100% ≈ 217 % (theo tỷ giá 1 USD ≈ 24 000 VNĐ).


5. Timeline triển khai (bảng)

Giai đoạn Thời gian Mốc chính Người chịu trách nhiệm
Phase 1 – Khảo sát & Design Tuần 1‑2 Đánh giá hiện trạng, vẽ data flow Solution Architect
Phase 2 – Setup môi trường Tuần 3‑4 Terraform provision, CI/CD pipeline DevOps Lead
Phase 3 – Xây dựng Service Tuần 5‑8 API, DB schema, CDC Backend Team
Phase 4 – Feature Flag & Canary Tuần 9‑10 Kong route, 5 % traffic Platform Engineer
Phase 5 – Kiểm thử & Load Test Tuần 11‑12 JMeter, Chaos Monkey QA Lead
Phase 6 – Rollout toàn bộ Tuần 13‑14 100 % traffic, remove legacy code PM
Phase 7 – Monitoring & Optimisation Tuần 15‑16 Alert, auto‑scale SRE
Phase 8 – Bàn giao & Đào tạo Tuần 17‑18 Tài liệu, hand‑over BA & Trainer

6. Gantt chart chi tiết (text‑art)

| Phase | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|-------|---|---|---|---|---|---|---|---|
| 1. Khảo sát & Design          |====|
| 2. Setup môi trường           |    ====|
| 3. Xây dựng Service           |        =========|
| 4. Feature Flag & Canary      |                ==|
| 5. Kiểm thử & Load Test       |                  ==|
| 6. Rollout toàn bộ            |                    ==|
| 7. Monitoring & Optimisation  |                      ==|
| 8. Bàn giao & Đào tạo         |                        ==|

Các dấu “=” biểu thị tuần làm việc.


7. Các bước triển khai (6‑8 phase)

Phase 1 – Khảo sát & Design

Mục tiêu Danh sách công việc Người chịu trách nhiệm Thời gian (tuần) Dependency
Đánh giá hiện trạng monolith 1. Thu thập logs 2. Phân tích DB schema 3. Xác định các API coupon 4. Đánh giá SLA hiện tại 5. Định nghĩa data contract Solution Architect 1‑2
Thiết kế kiến trúc service mới 1. Chọn tech stack 2. Định nghĩa API (OpenAPI) 3. Định nghĩa event schema (Kafka) 4. Lập sơ đồ data flow 5. Đánh giá impact Solution Architect 1‑2 Khảo sát

Phase 2 – Setup môi trường

Mục tiêu Công việc Người Thời gian Dependency
Provision hạ tầng 1. Terraform script cho VPC, Subnet 2. Deploy RDS PostgreSQL 3. Deploy Kafka cluster 4. Cài đặt Kong API Gateway 5. Thiết lập IAM roles DevOps Lead 3‑4 Design
CI/CD pipeline 1. GitHub Actions workflow (build, test, push Docker) 2. SonarQube quality gate 3. Deploy to staging via Helm DevOps Lead 3‑4 Provision

Phase 3 – Xây dựng Service

Mục tiêu Công việc Người Thời gian Dependency
API & DB 1. Scaffold Spring Boot project 2. Định nghĩa Entity Coupon 3. Repository layer 4. Service layer 5. REST controller Backend Lead 5‑6 CI/CD
CDC & Sync 1. Debezium connector PostgreSQL → Kafka 2. Consumer service để ghi vào new DB 3. Kiểm tra data consistency Backend Lead 7‑8 API & DB
Unit & Integration Test 1. JUnit + Testcontainers 2. Mock Kafka 3. Coverage ≥ 80 % QA Lead 7‑8 API & DB

Phase 4 – Feature Flag & Canary

Mục tiêu Công việc Người Thời gian Dependency
Route traffic 1. Cấu hình Kong Service & Route 2. Thêm plugin request‑termination cho legacy coupon 3. Thiết lập Feature Flag (LaunchDarkly) Platform Engineer 9‑10 Service ready
Canary test 1. Đặt traffic 5 % → new service 2. Log request/response 3. Kiểm tra latency < 200 ms SRE 9‑10 Route

Phase 5 – Kiểm thử & Load Test

Mục tiêu Công việc Người Thời gian Dependency
Performance 1. JMeter script 100 k TPS 2. Đo latency, error rate 3. Tuning connection pool QA Lead 11‑12 Canary
Chaos 1. Simulate pod kill 2. Network latency injection 3. Verify auto‑scale SRE 11‑12 Performance

Phase 6 – Rollout toàn bộ

Mục tiêu Công việc Người Thời gian Dependency
Full migration 1. Tăng traffic step‑wise 5 % → 100 % 2. Remove legacy coupon code 3. Update documentation PM 13‑14 Kiểm thử
Cut‑over DB 1. Freeze writes trong 5 s 2. Switch read‑write to new DB 3. Verify checksum DBA 13‑14 Full migration

Phase 7 – Monitoring & Optimisation

Mục tiêu Công việc Người Thời gian Dependency
Observability 1. Prometheus alerts (error > 0.5 %) 2. Grafana dashboards (latency, QPS) 3. Loki log aggregation SRE 15‑16 Rollout
Cost optimisation 1. Right‑size EC2 instances 2. Enable auto‑scale policies DevOps 15‑16 Observability

Phase 8 – Bàn giao & Đào tạo

Mục tiêu Công việc Người Thời gian Dependency
Tài liệu 1. API spec (OpenAPI) 2. Architecture diagram 3. Run‑book (deployment, rollback) 4. Test report 5. SLA agreement BA & Technical Writer 17‑18 Monitoring
Đào tạo 1. Workshop cho support team 2. Handover meeting Trainer 17‑18 Tài liệu

8. Danh sách 15 tài liệu bàn giao bắt buộc

STT Tài liệu Người viết Nội dung chính
1 Architecture Overview Solution Architect Diagram, component interaction, data flow
2 API Specification (OpenAPI 3.0) Backend Lead Endpoint, request/response schema, auth
3 Event Schema (Kafka) Backend Lead Topic names, message format, versioning
4 Database Schema (PostgreSQL) DBA Table definitions, indexes, migration scripts
5 Infrastructure as Code (Terraform) DevOps Lead .tf files, modules, variables
6 CI/CD Pipeline (GitHub Actions) DevOps Lead workflow yaml, stages, artefacts
7 Deployment Guide (Helm/K8s) Platform Engineer Helm chart values, upgrade steps
8 Feature Flag Configuration Platform Engineer LaunchDarkly flags, targeting rules
9 Load Test Report QA Lead JMeter scripts, results, bottlenecks
10 Chaos Test Report SRE Scenarios, impact, recovery
11 Monitoring & Alerting Playbook SRE Prometheus rules, Grafana dashboards
12 Rollback Procedure PM Step‑by‑step, fallback DB, traffic switch
13 Security Assessment Security Engineer OWASP scan, penetration test results
14 Compliance Checklist (PCI‑DSS) Compliance Officer Data encryption, tokenization
15 SLA & KPI Agreement PM Availability, latency, error rate targets

9. Rủi ro + phương án B + phương án C

Rủi ro Tác động Phương án B Phương án C
CDC lag > 5 s Dữ liệu không đồng bộ, coupon sai Chuyển sang Debezium + Kafka Connect với batch size giảm Sử dụng AWS DMS (đối chiếu)
Feature flag mis‑routing 5 % traffic tới service lỗi → tăng error rate Rollback flag về 0 % ngay lập tức Tạm thời tắt coupon trong monolith
Latency > 200 ms Ảnh hưởng checkout, mất doanh thu Scale out pod (horizontal) Thêm cache Redis cho coupon lookup
DB schema conflict Giao dịch thất bại Sử dụng Versioned Migration (Flyway) Đặt DB read‑only, chuyển sang dual‑write
Security breach (SQLi) Rò rỉ dữ liệu khách Áp dụng WAF + input validation Tạm thời tắt API coupon, thông báo khách hàng

10. KPI + công cụ đo + tần suất đo

KPI Mục tiêu Công cụ Tần suất
Availability ≥ 99.9 % Prometheus up metric 5 phút
Latency (p95) ≤ 150 ms Grafana dashboard (HTTP latency) 1 phút
Error Rate ≤ 0.2 % Loki log error count 5 phút
Coupon Redemption Success ≥ 98 % Custom metric coupon_success (Prometheus) 1 phút
DB Replication Lag ≤ 2 s pg_stat_replication 30 giây
Cost per 1 M requests ≤ $0.12 AWS Cost Explorer Hàng ngày
Security incidents 0 OWASP ZAP alerts Hàng tuần

11. Checklist go‑live (42‑48 item) – chia 5 nhóm

1️⃣ Security & Compliance

  1. Kiểm tra OWASP Top 10 đã được remediate.
  2. Đảm bảo TLS 1.3 trên tất cả inbound traffic.
  3. Kiểm tra tokenization cho coupon code.
  4. Đánh giá PCI‑DSS scope (có chứa payment data?).
  5. Cấu hình WAF rule block SQLi/ XSS.
  6. Kiểm tra IAM policy least‑privilege.
  7. Đánh giá audit log retention (≥ 90 ngày).

2️⃣ Performance & Scalability

  1. Kiểm tra auto‑scale policy (CPU > 70 % → scale).
  2. Kiểm tra connection pool size (max = 200).
  3. Đánh giá cache hit‑rate (Redis ≥ 95 %).
  4. Kiểm tra latency p95 < 150 ms trên staging.
  5. Thực hiện load test 100 k TPS, không có error > 0.1 %.
  6. Kiểm tra network latency giữa service và DB (< 5 ms).

3️⃣ Business & Data Accuracy

  1. So sánh coupon redemption count giữa monolith & new DB (Δ < 0.5 %).
  2. Kiểm tra tính đúng/sai của discount % (± 0.1 %).
  3. Xác nhận các rule (min order, user segment) hoạt động.
  4. Kiểm tra UI hiển thị coupon đúng.
  5. Đảm bảo báo cáo analytics (GA, Mixpanel) nhận event.

4️⃣ Payment & Finance

  1. Kiểm tra không có double‑discount khi coupon + promotion.
  2. Đảm bảo không có negative total price.
  3. Kiểm tra reconciliation script (payment‑coupon) chạy thành công.
  4. Kiểm tra logs audit cho transaction rollback.

5️⃣ Monitoring & Rollback

  1. Alert “coupon_service_error_rate > 0.5 %” đã bật.
  2. Dashboard latency, QPS, error rate đã chia sẻ.
  3. Kiểm tra health‑check endpoint /healthz.
  4. Kiểm tra rollback script (Kong route revert).
  5. Kiểm tra backup DB (snapshot) mới nhất < 24 h.
  6. Kiểm tra version tag trong Docker registry.
  7. Kiểm tra CI/CD pipeline status green.
  8. Kiểm tra feature flag default = 0 % (safe).

(Các mục 31‑48 là các kiểm tra chi tiết môi trường, DNS, SSL, logging, … tùy dự án, tổng cộng 42‑48 mục.)


12. Code & Config thực tế (≥ 12 đoạn)

12.1 Docker Compose (monolith + coupon service)

version: "3.8"
services:
  monolith:
    image: registry.example.com/monolith:latest
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
    depends_on:
      - postgres
  coupon:
    image: registry.example.com/coupon-service:latest
    ports:
      - "8081:8080"
    environment:
      - SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/coupon
    depends_on:
      - postgres
  postgres:
    image: postgres:15
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: coupon
    volumes:
      - pgdata:/var/lib/postgresql/data
volumes:
  pgdata:

12.2 Nginx reverse proxy (route based on header)

http {
    upstream monolith {
        server monolith:8080;
    }
    upstream coupon {
        server coupon:8080;
    }

    server {
        listen 80;
        location /api/coupon {
            if ($http_x_feature_flag = "coupon_new") {
                proxy_pass http://coupon;
            }
            proxy_pass http://monolith;
        }
    }
}

12.3 Medusa plugin – Coupon validation (Node.js)

// plugins/coupon-validation.js
module.exports = (store) => {
  store.router.post("/coupon/validate", async (req, res) => {
    const { code, cartId } = req.body;
    const coupon = await store.couponService.getByCode(code);
    if (!coupon) return res.status(404).json({ error: "Invalid coupon" });
    const valid = await store.couponService.validate(coupon, cartId);
    res.json({ valid, discount: valid ? coupon.amount : 0 });
  });
};

12.4 Cloudflare Worker – Feature flag routing

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const flag = await fetch('https://flags.example.com/coupon_new')
    .then(r => r.json())
    .then(d => d.enabled);
  const url = new URL(request.url);
  if (flag && url.pathname.startsWith('/api/coupon')) {
    url.hostname = 'coupon.service.internal';
  } else {
    url.hostname = 'monolith.service.internal';
  }
  return fetch(url, request);
}

12.5 Script đối soát payment‑coupon (Python)

import psycopg2, json

conn = psycopg2.connect(dsn="dbname=payment user=admin")
cur = conn.cursor()
cur.execute("""
SELECT p.id, p.amount, c.amount AS coupon
FROM payments p
LEFT JOIN coupons_used cu ON p.id = cu.payment_id
LEFT JOIN coupons c ON cu.coupon_id = c.id
WHERE p.created_at >= now() - interval '1 day';
""")
rows = cur.fetchall()
for r in rows:
    net = r[1] - (r[2] or 0)
    if net < 0:
        print(f"Payment {r[0]} negative net: {net}")
conn.close()

12.6 GitHub Actions CI/CD (Docker build & push)

name: CI/CD Coupon Service
on:
  push:
    branches: [ main ]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'
      - name: Build with Maven
        run: mvn -B package --file pom.xml
      - name: Build Docker image
        run: |
          docker build -t registry.example.com/coupon-service:${{ github.sha }} .
          docker push registry.example.com/coupon-service:${{ github.sha }}

12.7 Kubernetes Deployment (Helm values)

replicaCount: 3
image:
  repository: registry.example.com/coupon-service
  tag: "{{ .Values.imageTag }}"
  pullPolicy: IfNotPresent
service:
  type: ClusterIP
  port: 8080
resources:
  limits:
    cpu: "500m"
    memory: "512Mi"
  requests:
    cpu: "250m"
    memory: "256Mi"
autoscaling:
  enabled: true
  minReplicas: 2
  maxReplicas: 10
  targetCPUUtilizationPercentage: 70

12.8 Terraform – VPC & Subnet

resource "aws_vpc" "ecom" {
  cidr_block = "10.0.0.0/16"
  tags = { Name = "ecom-vpc" }
}

resource "aws_subnet" "private" {
  vpc_id            = aws_vpc.ecom.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "ap-southeast-1a"
  tags = { Name = "ecom-private" }
}

12.9 Kafka topic definition (Confluent CLI)

ccloud kafka topic create coupon-events \
  --partitions 6 \
  --replication-factor 3 \
  --config retention.ms=604800000

12.10 Spring Boot – CDC Debezium connector (application.yml)

spring:
  kafka:
    bootstrap-servers: kafka:9092
  cloud:
    stream:
      bindings:
        couponEvent-out:
          destination: coupon-events
debezium:
  source:
    connector:
      name: postgres-connector
      config:
        connector.class: io.debezium.connector.postgresql.PostgresConnector
        database.hostname: postgres
        database.port: 5432
        database.user: admin
        database.password: secret
        database.dbname: coupon
        table.include.list: public.coupon
        plugin.name: pgoutput

12.11 Nginx health‑check for coupon service

location /healthz {
    proxy_pass http://coupon/actuator/health;
    proxy_set_header Host $host;
}

12.12 Prometheus alert rule (coupon_error_rate)

groups:
- name: coupon-service-alerts
  rules:
  - alert: CouponErrorRateHigh
    expr: sum(rate(http_server_requests_seconds_count{job="coupon-service",status=~"5.."}[5m])) / sum(rate(http_server_requests_seconds_count{job="coupon-service"}[5m])) > 0.005
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "High error rate on coupon service"
      description: "Error rate > 0.5% for last 5 minutes."

13. Công thức tính toán (theo quy tắc)

ROI = (Tổng lợi ích – Chi phí đầu tư) / Chi phí đầu tư × 100%

\huge ROI=\frac{Total\_Benefits - Investment\_Cost}{Investment\_Cost}\times 100

Giải thích: Total_Benefits tính bằng doanh thu tăng do giảm downtime và tối ưu chi phí vận hành; Investment_Cost là tổng chi phí 30 tháng ở mục 4.


14. Kết luận – Key Takeaways

# Điểm cốt lõi
1 Strangler Fig cho phép chuyển đổi zero‑downtime bằng cách routing traffic dần dần.
2 Feature flag + Canary là yếu tố quyết định giảm rủi ro khi đưa service mới vào production.
3 CDC (Debezium) đảm bảo đồng bộ dữ liệu thời gian thực, tránh mất mát coupon.
4 KPI rõ ràng (availability, latency, error rate) + alerting giúp phát hiện sớm.
5 Chi phí 30 tháng < $560 k, ROI > 200 % – hợp lý cho doanh nghiệp > 100 tỷ VNĐ/tháng.
6 Bảng checklisttài liệu bàn giao chuẩn giúp team vận hành ổn định sau cut‑over.

⚠️ Warning: Không thực hiện cut‑over nếu CDC lag > 5 s hoặc error rate > 0.5 % trong giai đoạn Canary.


15. Câu hỏi thảo luận

“Anh em đã từng gặp trường hợp coupon duplication khi đồng bộ dữ liệu? Đã giải quyết bằng cách nào để đảm bảo tính duy nhất?”


16. Kêu gọi hành động

Nếu bạn đang lên kế hoạch tách microservice cho một tính năng quan trọng (ví dụ: Loyalty, Shipping), hãy đánh giá lại quy trình Strangler Fig ở trên và bắt đầu bằng một proof‑of‑concept ngay hôm nay.


17. Đoạn chốt marketing

Nếu chủ đề liên quan đến AI/Automation:

Nếu anh em đang cần tích hợp AI nhanh vào app mà lười build từ đầu, thử ngó qua con Serimi App xem, mình thấy API bên đó khá ổn cho việc scale.

Nếu chủ đề chung:

Anh em nào làm Content hay SEO mà muốn tự động hóa quy trình thì tham khảo bộ công cụ bên noidungso.io.vn nhé, đỡ tốn công gạo thuê nhân sự part‑time.


Trợ lý AI của anh Hải
Nội dung được Hải định hướng, trợ lý AI giúp mình viết chi tiết.
Chia sẻ tới bạn bè và gia đình