Một bước quan trọng của bất kỳ chuỗi công cụ DevOps nào là bao gồm kiểm tra hiệu suất của ứng dụng web trước khi phiên bản mới được triển khai trong môi trường sản xuất. HTTP benchmarking là một chủ để phức tạp vì có rất nhiều thông số can thiệp vào hiệu suất nhận thức của ứng dụng.
Ví dụ:
- Một ứng dụng web nặng mã javascript dường như có vẻ chậm chạp với user;
- Một ứng dụng web đòi hỏi nhiều request (yêu cầu) để tải ảnh và file tĩnh sẽ chậm trong việc hiển thị trang đầu tiên;
- Và nếu các thành phần ấy không được cache đúng trong trình duyệt, nó sẽ chậm khi di chuyển tới trang tiếp theo;
- Cuối cùng, ngay cả khi đã tối ưu hóa mã javascript và cache mạnh nội dung tĩnh, ứng dụng web có thể vẫn chậm nếu máy chủ không có khả năng xử lý request của tất cả người dùng truy cập trang vào cùng thời điểm.
Trong bài đăng blog này, chúng ta tập trung vào tình huống cuối cùng, bằng cách sử dụng wrk2. Giống như ApacheBench (ab) hoặc phiên bản gốc wrk, thì wrk2 sẽ gửi các yêu cầu tới một URL duy nhất và đo thời gian phản hồi từ máy chủ. Vì thế nó sẽ không tải toàn bộ trang, và nó sẽ không thực thi mã javascript.
Không giống các công cụ khác, wrk2 cố gắng đo lường hành vi của máy chủ ở tốc độ yêu cầu cố định (fixed request rate). Điều này cung cấp một phép đo công bằng về thời gian phản hồi từ máy chủ khi nhiều người dùng cùng truy cập URL cụ thể (nào đó) cùng lúc…
Docker
Cách đơn giản nhất để chạy wrk2 là sử dụng Docker image:
docker run --rm cylab/wk2
wrk chấp nhận một số tham số đầu vào. Dưới đây là một số cái chính:
-R<tốc độ> : số lượng yêu cầu mỗi giây-L: hiển thị số liệu thống kê độ trễ-d<khoảng thời gian> : khoảng thời gian của kiểm tra (phải tối thiểu 30 giây mới cho các kết quả chính xác)-t<luồng> : số luồng được sử dụng để khởi tạo workload-c<các kết nối> : tổng số lượng các kết nối TCP đồng thời
Vì vậy một thử nghiệm thực tế trông sẽ giống thế này:
docker run --rm cylab/wrk2 -R 1000 -L -d 30s -t 4 -c 100 https://172.17.0.1:8000
GitLab
Bạn cũng có thể sử dụng wrk2 như một job trong .gitlab-ci.yaml, để kiểm tra hiệu suất của phiên bản mới sau khi bạn triển khai mã vào môi trường thử nghiệm. Có một mẹo ở đây, bạn cần phải ghi đè định nghĩa “entrypoint” của container:
stages:
- test
- build
- deploy-staging
- test-staging
functional:wrk2:
# test-staging takes place after the application has been deployed
# to the staging environment
stage: test-staging
environment:
name: staging
url: https://my.stating.com
image:
name: cylab/wrk2
entrypoint: [""]
script:
- wrk -R 200 -L -d 30s -t 10 -c 100 https://my.stating.com
Chọn các tham số
Việc chọn lựa các tham số kiểm tra có thể khá khó khăn. Dưới đây là một vài quy tắc ngón tay cái dùng để xác định điểm khởi đầu:
- Hãy tưởng tượng bạn muốn kiểm tra xem máy chủ của bạn có thể phục vụ được số lượng U người dùng hay không;
- Nếu những người dùng lướt web, họ sẽ click vào các link mỗi 2 hoặc 3 giây, vì thế U người dùng sẽ tạo ra U/2 click mỗi giây;
- Nếu mã của bạn được tối ưu hóa chính xác, tất cả nội dung tĩnh (ảnh, file js, file css) sẽ được cache trên trình duyệt, hoặc phục vụ từ CDN, vì thế một click sẽ chỉ yêu cầu chỉ một request từ máy chủ, điều đó sẽ dẫn đến tốc độ yêu cầu sẽ là R = U/2 request mỗi giây;
Bây giờ chúng ta cần bao nhiêu kết nối và luồng để tạo ra khối lượng công việc (workload) này?
Dựa trên kinh nghiệm của tôi, không phải là hiếm khi thấy một trang web cần 200ms để được ‘đã xử lý’ bởi một máy chủ web (trong PHP, nếu opcache bị vô hiệu hóa, bạn sẽ cần khoảng 500ms cho mỗi yêu cầu/request). Trong một kết nối, yêu cầu tiếp theo chỉ được gửi khi yêu cầu trước đó đã hoàn tất. Vì thế để giữ được ‘biên’ chúng ta cần cài đặt c = R/2 = U/4.
Cuối cùng, và đây hoàn toàn là kinh nghiệm cá nhân, tôi thường sử dụng 10 kết nối cho mỗi luồng, vì thế t = c/10 = R/20
Đặt ngưỡng
Docker image cylab/wrk2 cũng bao gồm một tiện ích nhỏ gọi là wrk-threshold cho phép xác định bản dựng thất bại nếu độ trễ đo bởi wrk2 vượt một ngưỡng cho trước. Nó lấy 3 tham số: đường dẫn tới báo cáo văn bản được tạo bởi wrk2, phần trăm, và ngưỡng độ trễ tính bằng mili giây. Vì thế job .gitlab-ci.yaml cần phải trông giống thế này:
stages:
- test
- build
- deploy-staging
- test-staging
staging:wrk2:
# test-staging takes place after the application has been deployed
# to the staging environment
stage: test-staging
environment:
name: staging
url: https://my.stating.com
image:
name: cylab/wrk2
entrypoint: [""]
script:
- wrk -R 200 -L -d 30s -t 10 -c 100 https://my.stating.com > wrk-200.txt
- wrk-threshold wrk-200.txt 99.9 200
Trong ví dụ này, chúng tôi gửi 200 request mỗi giây tới máy chủ staging của chúng tôi và đo độ trễ phản hồi. Sau đó chúng tôi coi thử nghiệm là thành công chỉ khi có ít nhất 99,9 phần trăm yêu cầu được phục vụ trong vòng 200ms.
(Dịch từ bài blog HTTP benchmarking with wrk2 của tác giả Thibault Debatt | CC BY-SA 4.0)
