Reliable load testing with regards to unexpected nuances

Bài tóm tắt Miro 2020 2. Tăng trưởng Độ khó: Trung bình

Miro · 2020 · 2. Tăng trưởng · Độ khó: Trung bình — bài gốc

Bài 1 của cặp bài do Head of QA viết; bài 2 (quản lý hàng trăm server sinh tải, monitoring, IaC): Miro 2020.

Bối cảnh

  • Khoảng đầu 2019, ở mốc 12.000 user online đồng thời, Miro bắt đầu dựng hạ tầng load test; ba tháng sau bản test đầu tiên ra đời, và đúng lúc đó production chạm giới hạn, sập hai giờ. Sự cố đẩy họ từ test thỉnh thoảng sang hạ tầng load test thường trực.
  • Trong 12 tháng tiếp theo, user đồng thời tăng từ 12.000 lên 100.000 (2020); không biết khối nào sẽ thành nút thắt, khối nào scale tuyến tính.

Thay đổi chính

  • Một test lớn, thực tế, thay vì test từng khối: vẽ sơ đồ mọi server và viết test cho từng tương tác sẽ mất nhiều tháng. Thay vào đó dựng một cụm có cấu trúc giống production nhưng mạnh hơn, chạy virtual user mô phỏng hoạt động thật. Nhược điểm duy nhất: đắt.
  • Kịch bản dựng từ số liệu production: số board và phân bố nội dung trên board, tỉ lệ người sửa so với người xem (từ thống kê DB), số lần gọi DB qua từng "model" của backend để biết phần logic nào tạo tải nặng nhất. Mỗi khối test không cần đúng về chức năng mà phải tạo tải giống thật theo metric server; phần lớn virtual user làm việc trên board trung bình, vài user tạo tải "phá hoại" như account lớn ở production.
  • Dữ liệu là một phần của test: DB test phải lớn và không làm méo kết quả, nên dữ liệu được tạo qua REST API như user thật (khôi phục board từ backup), chạy nhiều luồng nên nhanh ngang sinh dữ liệu rác.
  • Bộ sinh tải: JMeter + Taurus; công việc trong WebSocket của board phải tự viết, nên họ nhúng chính client thật (chỉ giữ phần giao tiếp client-server, ít đổi) vào JMeter. Cái giá: script lớn làm mỗi máy m5.large chỉ chạy khoảng 730 luồng; 50.000 user cần 69 instance, khoảng 3.000 USD/tháng; dùng Spot tiết kiệm ít nhất 60%. Không dùng dịch vụ load test trên cloud vì muốn tái dùng 90% công sức ở môi trường local.
  • Tái dùng cho test nhỏ:
    • Test DB: ghi log mọi query trong lúc chạy test lớn trên môi trường test, rồi dùng pgreplay phát lại nhiều luồng trên một bản dump (công cụ Marucy tự dựng instance, deploy dump, replay, đo bằng Prometheus/Grafana) để tinh chỉnh cấu hình PostgreSQL (VACUUM không chạy, CHECKPOINT kích hoạt ngoài lịch) bằng vòng lặp ngắn thay cho test ba giờ. Không ghi log ở production để tránh dùng dữ liệu thật và chi phí syslog. Tải phải không đều, nếu không DB sẽ cư xử khác production.
    • Test thoái hoá sau release: so thời gian phản hồi với giá trị tham chiếu; chạy song song hàng nghìn functional test trong lúc có tải, báo cáo bằng Allure.

Vì sao

  • Theo Miro, test hướng từ logic nghiệp vụ (lặp lại đúng việc user làm) phủ được cả những tương tác không ai lường trước, điều mà test tổng hợp theo từng khối không làm được.

Bài học cho SWE

  • Hiệu chỉnh kịch bản tải theo metric server, không theo analytics sử dụng: cái cần giống là tải lên hệ thống.
  • Code tuỳ biến trong công cụ sinh tải có thể thành nút thắt: khi đó bạn đang test JMeter chứ không phải sản phẩm.
  • Một test lớn và thực tế là tài sản tái dùng: từ nó sinh ra test DB bằng replay và test thoái hoá cho mỗi release.

Liên quan