Skip to content

Load Balancer Debugging: Health Checks and Traffic Distribution

Tại sao Load Balancer Debugging Khó

Load Balancer đóng vai trò là tầng quan trọng (critical layer) trong hạ tầng production. Khi xảy ra sự cố:

  • Một số request thành công, số khác thất bại (backend ở status unhealthy).
  • Traffic không được phân phối đều (cơ chế load balancing bị lỗi).
  • Độ trễ (latency) cao mặc dù các backend vẫn healthy (lỗi cấu hình traffic policy).
  • Các kết nối bị mất chập chờn (hiện tượng health check chập chờn - flapping).

Phần lớn các sự cố về load balancer đều có nguyên nhân gốc rễ từ health check hoặc cấu hình sai firewall.

Cơ chế bên trong: Hoạt động của Health Check

Cách thức hoạt động

Health check là các đợt kiểm tra định kỳ (periodic probes) gửi từ các prober do Google quản lý tới các backend endpoint:

Quy trình:

1. LB gửi packet probe
   Source: Dải IP của Google prober (35.191.0.0/16 hoặc 130.211.0.0/22)
   Destination: Backend instance (port được cấu hình)
   
2. Backend nhận probe
   Ứng dụng phải phản hồi với mã thành công (successful response)
   
3. LB ghi nhận phản hồi
   Thành công → cộng dồn số lần thành công liên tiếp (consecutive success)
   Thất bại → cộng dồn số lần thất bại liên tiếp (consecutive failure)
   
4. Áp dụng ngưỡng (threshold)
   Đạt ngưỡng success threshold → Đánh dấu HEALTHY
   Đạt ngưỡng failure threshold → Đánh dấu UNHEALTHY
   
5. Phân phối traffic
   Các backend HEALTHY: Tiếp tục nhận traffic
   Các backend UNHEALTHY: Không nhận traffic

Các giao thức Health Check

GCP hỗ trợ nhiều giao thức kiểm tra:

ProtocolSuccess CriteriaUse Case
HTTP/HTTPSTrả về 200 OKỨng dụng Web
TCPThiết lập kết nối thành côngCác dịch vụ chung
SSLBắt tay TLS thành côngCác dịch vụ mã hóa
gRPCStatus gRPC HEALTHYCác dịch vụ gRPC
UDPNhận được phản hồiDNS, game servers

Lựa chọn:

  • Sử dụng giao thức phù hợp với dịch vụ chạy ở backend.
  • Sử dụng HTTP cho web, TCP cho các dịch vụ chung, và gRPC cho các dịch vụ sử dụng Protobuf.

Ngưỡng đánh giá Health Check (Health Check Thresholds)

Cấu hình mẫu:
  healthy_threshold: 2  (mặc định)
    → Backend được đánh dấu healthy sau 2 lần probe thành công liên tiếp
  
  unhealthy_threshold: 3  (mặc định)
    → Backend được đánh dấu unhealthy sau 3 lần probe thất bại liên tiếp
  
  check_interval_sec: 5  (mặc định)
    → Gửi probe sau mỗi 5 giây

Dòng thời gian (Timeline):
T=0s:   Probe 1 → THẤT BẠI
T=5s:   Probe 2 → THẤT BẠI
T=10s:  Probe 3 → THẤT BẠI
        → đạt unhealthy_threshold → Đánh dấu UNHEALTHY
T=15s:  Probe 4 → THÀNH CÔNG
T=20s:  Probe 5 → THÀNH CÔNG
        → đạt healthy_threshold → Đánh dấu HEALTHY

Hệ quả: Backend chuyển sang status unhealthy sau khoảng ~15 giây (3 lần thất bại × 5 giây interval), và cần khoảng ~10 giây để phục hồi sang healthy.

Yêu cầu cấu hình Firewall

Quan trọng: Các LB prober gửi gói tin từ các dải IP Google xác định. Nếu firewall chặn các dải IP này, health check sẽ thất bại.

Các quy tắc Allow cần thiết:

bash
# Đối với global external load balancers
ALLOW từ: 35.191.0.0/16
ALLOW từ: 130.211.0.0/22

# Đối với regional load balancers
ALLOW từ: 35.191.0.0/16 (tương tự)

# Đối với internal load balancers
ALLOW từ: 35.191.0.0/16
ALLOW từ: 130.211.0.0/22

# Tạo firewall rule:
gcloud compute firewall-rules create allow-health-checks \
  --allow=tcp \
  --source-ranges=35.191.0.0/16,130.211.0.0/22 \
  --target-tags=backend

Debug cấu hình Firewall:

bash
# Nếu health check thất bại, hãy kiểm tra firewall rules
gcloud compute firewall-rules list \
  --filter="sourceRanges:35.191.0.0/16 OR sourceRanges:130.211.0.0/22"

# Nếu thiếu rule allow, health check sẽ bị chặn
# Chạy lệnh trên để tạo rule cho phép kết nối

Sơ đồ chuyển đổi status (Health Check State Machine)

Quá trình chuyển đổi status của Backend:

UNHEALTHY

    [Số lần probe thành công liên tiếp = healthy_threshold]

HEALTHY

    [Số lần probe thất bại liên tiếp = unhealthy_threshold]

UNHEALTHY

Lưu ý: Quá trình chuyển đổi status không xảy ra ngay lập tức, mà cần trải qua nhiều chu kỳ probe.

Các lỗi Load Balancer thường gặp khi Debug

Trường hợp 1: Toàn bộ Backend đều Unhealthy

Triệu chứng: Load Balancer hiển thị toàn bộ backend ở status UNHEALTHY, hoặc trả về lỗi 502/503.

Nguyên nhân gốc rễ:

  1. Firewall chặn kết nối health check

    bash
    # Kiểm tra firewall rules
    gcloud compute firewall-rules list \
      --filter="direction=INGRESS"
    
    # Xác minh dải allow từ 35.191.0.0/16 đã tồn tại
    # Nếu chưa, tiến hành tạo mới rule
  2. Cấu hình sai port ở backend

    bash
    # So sánh port cấu hình health check với port ứng dụng lắng nghe
    gcloud compute backend-services describe my-service \
      --region=us-central1 | grep healthChecks
    
    # Xem chi tiết cấu hình health check
    gcloud compute health-checks describe my-health-check
    # Xem field: port
    
    # Kiểm tra xem port có đang hoạt động trên backend không
    gcloud compute ssh backend-vm
    sudo netstat -tlnp | grep :8080
    # Nếu ứng dụng chưa lắng nghe port, hãy khởi động lại ứng dụng
  3. Ứng dụng backend bị crash

    bash
    gcloud compute ssh backend-vm
    sudo systemctl status app
    # Nếu ứng dụng dừng hoạt động, restart lại hoặc kiểm tra logs
  4. Định dạng phản hồi health check không hợp lệ

    bash
    # Nếu dùng HTTP với đường dẫn tùy chỉnh, kiểm tra xem endpoint có tồn tại không
    curl http://backend-vm:8080/health
    # Phải trả về mã 200 OK
    
    # Nếu không, kiểm tra log ứng dụng để sửa lỗi ở endpoint

Trường hợp 2: Status Health Check chập chờn (Flapping)

Triệu chứng: Backend liên tục đổi status từ healthy sang unhealthy rồi quay lại healthy một cách nhanh chóng.

Nguyên nhân gốc rễ:

  1. Ứng dụng khởi động quá chậm

    bash
    # Nếu thời gian khởi động > (unhealthy_threshold × check_interval),
    # backend sẽ bị đánh dấu unhealthy trước khi kịp sẵn sàng
    
    # Khắc phục: Tăng thông số healthy_threshold hoặc check_interval
    gcloud compute health-checks update my-health-check \
      --check-interval=10  # Tăng lên 10 giây thay vì 5 giây
  2. Backend quá tải dẫn đến timeout health check

    bash
    # Ứng dụng thỉnh thoảng phản hồi health check quá chậm
    
    # Giám sát latency của backend
    # Nếu CPU/memory quá cao, hãy scale out thêm instance
  3. Mạng chập chờn

    bash
    # Kiểm tra VPC Flow Logs của traffic health check
    # Tìm kiếm các packet bị drop hoặc timeout

Trường hợp 3: Traffic phân phối không đều

Triệu chứng: Một số backend nhận được lượng request lớn trong khi số khác lại nhận được rất ít.

Nguyên nhân gốc rễ:

  1. Cấu hình sai chế độ cân bằng tải (Balancing mode)

    bash
    # Kiểm tra cấu hình balancing mode
    gcloud compute backend-services describe my-service \
      --region=us-central1 \
      --format="value(balancingMode)"
    # Phải ở chế độ RATE, CONNECTION, hoặc CPU
    
    # Kiểm tra max rate của từng backend
    gcloud compute backend-services get-health my-service
    # Xem thông số: max-rate-per-instance
  2. Session affinity giữ kết nối vào backend unhealthy

    bash
    # Nếu bật session affinity, kết nối sẽ được giữ cố định
    # Nếu backend bị quá tải hoặc lỗi, kết nối sẽ bị timeout liên tục
    
    gcloud compute backend-services describe my-service \
      --region=us-central1 \
      --format="value(sessionAffinity)"
    
    # Tắt nếu không cần thiết:
    gcloud compute backend-services update my-service \
      --session-affinity=NONE \
      --region=us-central1
  3. Khác biệt về tài nguyên của backend (ví dụ khi thêm instance mới)

    bash
    # Nếu thêm instance mới có cấu hình tài nguyên thấp hơn,
    # LB sẽ không tự động phân phối lại
    
    # Cấu hình rõ ràng thông số max-rate-per-instance
    gcloud compute backend-services update-backend my-service \
      --instance-group=my-ig \
      --instance-group-zone=us-central1-a \
      --max-rate-per-instance=100 \
      --region=us-central1

Trường hợp 4: Latency cao trên một vài Backend

Triệu chứng: Một số request xử lý nhanh nhưng số khác lại rất chậm. Latency ở P99 tăng cao.

Nguyên nhân gốc rễ:

  1. Phân phối traffic không đều (như trên), dẫn đến một số backend bị quá tải.
  2. Định tuyến ECMP bị bất đối xứng.
  3. Tài nguyên VM ở backend bị cạn kiệt (CPU, memory quá tải).

Sử dụng Load Balancer Logs

Bật tính năng logging trên load balancer để hỗ trợ debug:

bash
gcloud compute backend-services update my-service \
  --enable-logging \
  --logging-sample-rate=1.0 \  # Lấy mẫu 100%
  --region=us-central1

Cấu trúc Log:

json
{
  "httpRequest": {
    "requestUrl": "http://example.com/api",
    "requestMethod": "POST",
    "status": 200,
    "latency": "0.123456s",
    "userAgent": "..."
  },
  "sourceIp": "10.0.1.2",
  "destinationIp": "10.1.1.5",
  "backendService": "projects/my-project/global/backendServices/my-service",
  "forwardingRule": "projects/my-project/global/forwardingRules/my-rule"
}

Phân tích logs:

bash
# Truy vấn các request bị chậm
gcloud logging read \
  'resource.type="http_load_balancer" AND severity >= "WARNING"' \
  --limit=100

# Hoặc kiểm tra qua Log Explorer:
# resource.type="http_load_balancer"
# httpRequest.latency > "1.0s"  # Tìm các request xử lý lâu hơn 1 giây

Health Check Best Practices

1. Sử dụng Endpoint kiểm tra thực tế

bash
# TỐT: Sử dụng endpoint phản ánh đúng status sẵn sàng của ứng dụng
gcloud compute health-checks create http my-health-check \
  --port=8080 \
  --request-path=/health \
  --check-interval=5 \
  --timeout=3 \
  --healthy-threshold=2 \
  --unhealthy-threshold=3

Endpoint /health cần đảm bảo:

  • Phản hồi nhanh chóng (< 1 giây).
  • Kiểm tra các thành phần phụ thuộc quan trọng (kết nối DB, cache, v.v.).
  • Chỉ trả về mã 200 khi toàn bộ hệ thống sẵn sàng.

2. Cấu hình Ngưỡng đánh giá phù hợp

bash
# Đối với các backend ổn định:
# Giữ healthy_threshold: 2, unhealthy_threshold: 3 (mặc định OK)

# Đối với các backend chập chờn:
# Tăng healthy_threshold: 3-5 (để bỏ qua các đợt lỗi ngắn hạn)
# Tăng unhealthy_threshold: 3-5

# Đối với cơ chế failover nhanh:
# Đặt healthy_threshold: 1, unhealthy_threshold: 1
# (chuyển đổi nhanh, nhưng dễ bị nhận diện sai lỗi)

gcloud compute health-checks update my-health-check \
  --healthy-threshold=3 \
  --unhealthy-threshold=3

3. Giám sát Latency của Health Check

bash
# Tạo alert nếu latency của health check > 500ms:
gcloud monitoring policies create \
  --metric-type=loadbalancing.googleapis.com/https/request_count \
  --condition-threshold=500  # ms

4. Kiểm tra thủ công phản hồi từ Backend

bash
# SSH vào VM để kiểm thử phản hồi health check
gcloud compute ssh backend-vm

# Giả lập request health check
curl -v http://127.0.0.1:8080/health
# Phải trả về mã 200 OK ngay lập tức

Quy trình Debug sự cố Load Balancer trên Production

Khi nhận báo cáo sự cố về Load Balancer:

1. Kiểm tra status health của backend
   gcloud compute backend-services get-health my-service
   → Nếu có backend báo UNHEALTHY, tiếp tục quy trình.

2. Kiểm tra firewall đã cho phép IP của Google chưa
   gcloud compute firewall-rules describe allow-health-checks
   → Nếu thiếu rule allow, tiến hành tạo mới.

3. SSH vào backend, kiểm tra ứng dụng có hoạt động không
   gcloud compute ssh backend-vm
   sudo netstat -tlnp | grep 8080
   sudo systemctl status app
   → Nếu ứng dụng bị dừng, tiến hành restart.

4. Test thủ công endpoint health
   curl http://127.0.0.1:8080/health
   → Nếu mã trả về khác 200, kiểm tra log ứng dụng để sửa lỗi endpoint.

5. Theo dõi log của health check
   gcloud logging read 'resource.type="http_load_balancer"' --limit=50
   → Tìm kiếm các lỗi timeout hoặc lỗi probe.

6. Bật log trên load balancer nếu chưa bật
   gcloud compute backend-services update my-service \
     --enable-logging
      
7. Kiểm tra phân phối traffic
   gcloud compute backend-services get-health my-service
   → Tất cả backend đã healthy chưa?
   → Xem log để đánh giá luồng đi của traffic.

References