Khi kiểm tra tải gặp phải giới hạn tốc độ, WAF hoặc cân bằng địa lý, suy nghĩ đầu tiên là — “tôi sẽ chạy lưu lượng từ các IP khác nhau”. Nghe có vẻ hợp lý, nhưng trên thực tế, proxy trong k6 và JMeter chỉ giải quyết một tập hợp hạn chế các nhiệm vụ, và mọi thứ khác vẫn phải được khắc phục bằng kiến trúc của bài kiểm tra. Trong bài viết này, chúng ta sẽ phân tích cách kết nối kỹ thuật proxy với cả hai công cụ, các loại IP nào phù hợp cho điều này và khu vực trách nhiệm của máy chủ proxy kết thúc ở đâu.
Tại sao bài kiểm tra tải cần nhiều IP khác nhau
Mặc định, k6 và JMeter gửi toàn bộ lưu lượng từ một địa chỉ IP — máy chủ mà bài kiểm tra đang chạy (hoặc máy ảo trong CI/CD). Điều này là bình thường cho 90% kịch bản, nhưng trong một số trường hợp, một IP là không đủ:
- Giới hạn tốc độ ở cấp độ IP. Nhiều API và bộ cân bằng (nginx limit_req, AWS WAF, Cloudflare) giới hạn số lượng yêu cầu từ một địa chỉ trong một giây. Người dùng thực tế đến từ hàng ngàn IP khác nhau, trong khi bài kiểm tra của bạn chỉ từ một — và gặp phải giới hạn trước khi đến nút thắt thực sự của ứng dụng.
- Kiểm tra logic phụ thuộc vào địa lý. CDN, nội dung nhắm mục tiêu, giá cả theo vùng, geo-blocking — tất cả những điều này cần được kiểm tra với IP từ các quốc gia cụ thể, chứ không phải từ trung tâm dữ liệu, nơi mà máy chạy thử của bạn đang đứng.
- Kiểm tra bộ cân bằng và mạng anycast. Nếu hạ tầng phân phối lưu lượng theo vùng dựa trên IP của khách hàng, bài kiểm tra từ một địa chỉ chỉ kiểm tra một lộ trình, chứ không phải toàn bộ mạng.
- Mô phỏng phân phối lưu lượng thực tế. Lưu lượng sản xuất có IP phân phối qua các nhà cung cấp, subnet, đôi khi qua các nhà mạng di động — điều này ảnh hưởng đến hành vi của CDN, bộ nhớ đệm và logic edge.
Quan trọng là phải phân định ngay: nếu bạn đang kiểm tra hiệu suất của backend (bao nhiêu RPS mà API của bạn có thể chịu đựng), proxy hầu như không bao giờ cần thiết — điều quan trọng là tải sạch, chứ không phải sự đa dạng của nguồn. Proxy cần thiết khi kịch bản kiểm tra phụ thuộc vào địa chỉ IP của khách hàng.
Các loại proxy phù hợp: datacenter, residential, mobile
Việc lựa chọn loại proxy ảnh hưởng trực tiếp đến những gì bạn đang kiểm tra — băng thông của hạ tầng hay hành vi của hệ thống dưới các IP “sống”.
| Loại proxy | Độ trễ và tốc độ | Khi nào sử dụng trong kiểm tra tải |
|---|---|---|
| Proxy trung tâm dữ liệu | Độ trễ thấp, băng thông cao | Kiểm tra giới hạn tốc độ, vượt qua giới hạn “N yêu cầu từ IP”, tạo ra một khối lượng lớn RPS từ các subnet khác nhau |
| Proxy dân cư | Độ trễ cao hơn, tốc độ bị giới hạn bởi kênh của người dùng thực | Kiểm tra logic địa lý, kiểm tra CDN và hệ thống chống bot, mà tin tưởng vào các dải residential hơn là datacenter |
| Proxy di động | Độ trễ cao nhất, tốc độ không ổn định | Kịch bản ngách: kiểm tra API di động, hành vi khi thay đổi IP thường xuyên (các nhà mạng thay đổi địa chỉ của khách hàng một cách động) |
Để kiểm tra RPS và giới hạn tốc độ một cách sạch sẽ, hầu như luôn đủ với proxy trung tâm dữ liệu — chúng cung cấp độ trễ thấp ổn định và không làm sai lệch kết quả kiểm tra bởi sự không ổn định của mạng bên ngoài. Các IP dân cư và di động thêm tính thực tế vào các bài kiểm tra địa lý, nhưng cũng mang lại độ trễ riêng, mà bạn sẽ phải tính đến khi phân tích các chỉ số — nếu không, bạn sẽ dễ dàng nhầm lẫn “mạng proxy chậm” với “máy chủ của bạn chậm”.
Cấu hình proxy trong k6
k6 là một công cụ trên JavaScript (động cơ được viết bằng Go, các kịch bản được viết bằng JS), và mặc định không có hỗ trợ tích hợp cho HTTP proxy thông qua các tùy chọn kịch bản: proxy trong k6 được thiết lập thông qua các biến môi trường hoặc cài đặt hệ thống, vì k6 sử dụng Go HTTP client bên trong.
Cách đơn giản nhất là sử dụng các biến môi trường:
export HTTP_PROXY="http://login:password@proxy-host:port"
export HTTPS_PROXY="http://login:password@proxy-host:port"
k6 run script.js
Cách này sẽ chuyển toàn bộ lưu lượng của bài kiểm tra qua một proxy — phù hợp nếu bạn chỉ cần rời khỏi IP “trắng” của máy chủ. Nhưng nếu nhiệm vụ là phân phối người dùng ảo (VU) qua các IP khác nhau, bạn cần một danh sách proxy và logic lựa chọn ở cấp độ kịch bản. k6 không hỗ trợ trực tiếp proxy per-VU “ngay từ đầu”, vì vậy một cách phổ biến là chạy nhiều tiến trình k6 song song, mỗi tiến trình với biến môi trường riêng và proxy của mình từ nhóm:
// run-with-proxies.sh
PROXIES=("proxy1:port" "proxy2:port" "proxy3:port")
for proxy in "${PROXIES[@]}"; do
HTTP_PROXY="http://user:pass@$proxy" \
HTTPS_PROXY="http://user:pass@$proxy" \
k6 run --vus 50 --duration 5m script.js &
done
wait
Cách tiếp cận này mở rộng tốt khi kết hợp với k6 Cloud hoặc điều phối qua Kubernetes/Docker Compose — mỗi container được khởi động với biến proxy riêng của nó. Nếu cần xoay vòng IP trong một lần chạy kịch bản, hợp lý hơn là lấy proxy với xoay vòng từ chính nhà cung cấp proxy (sticky session với TTL), thay vì tạo ra xoay vòng trong mã JS.
Cấu hình proxy trong JMeter
Trong JMeter, proxy được cấu hình một cách tự nhiên, không cần biến môi trường, thông qua phần tử HTTP Request Defaults hoặc trực tiếp trong cài đặt HTTP Request Sampler:
- Thêm phần tử cấu hình HTTP Request Defaults vào Thread Group.
- Trong các trường Proxy Server, chỉ định máy chủ và cổng của proxy.
- Nếu proxy yêu cầu xác thực — thêm phần tử HTTP Authorization Manager với tên đăng nhập và mật khẩu cho máy chủ này.
- Tất cả các HTTP Request Samplers trong Thread Group sẽ tự động kế thừa cài đặt proxy.
Để phân phối tải qua nhiều proxy trong JMeter, bạn có thể sử dụng CSV Data Set Config — tệp với danh sách proxy được chèn vào các biến máy chủ và cổng cho mỗi luồng:
proxy_host,proxy_port,proxy_user,proxy_pass
proxy1.example.com,8000,user1,pass1
proxy2.example.com,8000,user2,pass2
proxy3.example.com,8000,user3,pass3
Kết nối CSV Data Set Config với Thread Group, chỉ định các biến ${proxy_host} và ${proxy_port} trong các trường Proxy Server/Proxy Port của sampler — mỗi luồng JMeter sẽ lấy dòng của mình từ tệp và đi qua IP của mình. Để chạy qua dòng lệnh (chế độ headless, điều này được khuyến nghị cho các bài kiểm tra tải thực tế) proxy cũng có thể được truyền qua các cờ:
jmeter -n -t test_plan.jmx -l results.jtl \
-H proxy-host -P port \
-u username -a password
Cách này chỉ định một proxy chung cho toàn bộ bài kiểm tra — đối với các kịch bản nhiều proxy, bạn vẫn sẽ phải sử dụng CSV Data Set Config hoặc Kiểm tra Phân phối (nhiều JMeter slave, mỗi slave với proxy của riêng mình trong cấu hình).
Xoay vòng IP và phân phối tải
Có hai cách tiếp cận khác nhau về phân phối IP trong bài kiểm tra tải:
- Gán IP tĩnh cho luồng/VU. Mỗi người dùng ảo nhận cùng một IP trong suốt phiên — mô phỏng người dùng thực với một địa chỉ. Được cấu hình thông qua proxy sticky-session hoặc chỉ là danh sách cố định trong CSV/các biến môi trường.
- Xoay vòng IP cho mỗi yêu cầu. Proxy thay đổi địa chỉ xuất phát cho mỗi yêu cầu HTTP — hữu ích để kiểm tra bảo vệ chống lại giới hạn tốc độ, nhưng không phản ánh đúng hành vi thực tế của người dùng, những người không thay đổi IP mỗi giây.
Để có một bài kiểm tra tải thực tế, trong 90% trường hợp, việc gán IP cho VU/luồng trong suốt phiên là chính xác hơn — như vậy bài kiểm tra phản ánh trung thực hành vi của nhiều người dùng độc lập, thay vì tạo ra tiếng ồn nhân tạo. Việc xoay vòng cho mỗi yêu cầu chỉ có ý nghĩa trong các kịch bản hẹp — ví dụ, khi kiểm tra mục tiêu việc kích hoạt quy tắc giới hạn tốc độ.
Những gì mà proxy chắc chắn không thay thế được
Đây là điểm chính của bài viết: proxy giải quyết vấn đề “yêu cầu đến từ IP nào”, nhưng không giải quyết các vấn đề mà thực sự kiểm tra tải đang kiểm tra.
- Băng thông của máy chạy thử của bạn. Nếu máy phát tải (máy chạy k6/JMeter) gặp phải CPU, bộ nhớ hoặc card mạng — proxy sẽ không sửa chữa điều đó. Proxy thêm một bước nhảy mạng không cần thiết và độ trễ của riêng nó, chứ không giảm tải từ máy chạy thử.
- Băng thông thực tế của máy chủ đang kiểm tra. Máy chủ hoặc chịu được tải, hoặc không — địa chỉ IP của khách hàng không ảnh hưởng đến điều này, ngoại trừ các trường hợp rõ ràng giới hạn tốc độ theo IP.
- Độ tin cậy của các chỉ số thời gian phản hồi. Proxy thêm độ trễ riêng (đặc biệt là residential và mobile), sẽ xuất hiện trong báo cáo của bạn như một phần của thời gian phản hồi. Nếu không trừ đi độ trễ của proxy riêng biệt, báo cáo độ trễ cuối cùng sẽ bị sai lệch và không thể so sánh với các chỉ số sản xuất.
- Mở rộng hạ tầng cho lưu lượng thực tế. Bài kiểm tra tải với proxy cho thấy hành vi dưới một mẫu yêu cầu nhất định, nhưng không thay thế lập kế hoạch năng lực, tự động mở rộng và các hồ sơ tải được xây dựng từ các nhật ký sản xuất thực tế.
- Kiểm tra tính chính xác của logic kinh doanh dưới tải. Các điều kiện race, khóa trong cơ sở dữ liệu, suy giảm hàng đợi — điều này thuộc về các bài kiểm tra đồng thời và phân tích hiệu suất, chứ không phải là việc thay đổi IP xuất phát.
Proxy là công cụ cho nhiệm vụ cụ thể “mô phỏng lưu lượng từ các IP khác nhau”, chứ không phải là một bộ tăng cường đa năng cho bài kiểm tra tải. Nếu mục tiêu là hiểu bao nhiêu RPS mà backend có thể chịu đựng, proxy trong hầu hết các trường hợp là không cần thiết: chỉ cần một vài máy chạy thử mà không có proxy, với keep-alive và nhóm kết nối được cấu hình đúng.
Những lỗi điển hình khi kiểm tra qua proxy
Trên thực tế, hầu hết các vấn đề với proxy trong các bài kiểm tra tải đều liên quan đến một vài lỗi lặp đi lặp lại.
- Kết hợp độ trễ của proxy với độ trễ của dịch vụ đang kiểm tra. Nếu không có phép đo baseline (yêu cầu trực tiếp không có proxy), không thể hiểu được bao nhiêu mili giây mà chính máy chủ proxy thêm vào.
- Sử dụng proxy di động hoặc residential ở những nơi cần băng thông sạch. Những proxy này bị giới hạn bởi kênh thực tế của thiết bị đầu cuối và về mặt vật lý không thể chịu đựng hàng chục ngàn RPS — để có tải sạch, cần proxy trung tâm dữ liệu.
- Quy mô IP không đủ cho số lượng lớn VU. Nếu có 5000 người dùng ảo mà chỉ có 10 địa chỉ proxy, bài kiểm tra vẫn sẽ gặp phải giới hạn tốc độ tương tự, chỉ là với độ trễ — dịch vụ sẽ nhanh chóng thấy mẫu “10 IP, hàng ngàn yêu cầu”.
- Bỏ qua thời gian chờ ở phía proxy. Khi có tải cạnh tranh cao, máy chủ proxy có thể bắt đầu từ chối các kết nối — quan trọng là phải xác nhận trước giới hạn số phiên đồng thời với nhà cung cấp proxy.
- Chạy bài kiểm tra mà không kiểm tra whitelisting/xác thực. Nếu proxy yêu cầu xác thực theo IP, và bài kiểm tra được khởi động từ CI/CD với địa chỉ động của máy chạy — các yêu cầu sẽ bị từ chối với 407 Proxy Authentication Required, và kết quả kiểm tra sẽ trở nên vô nghĩa.
Danh sách kiểm tra trước khi chạy bài kiểm tra
- Xác định xem nhiệm vụ có thực sự cần nhiều IP khác nhau hay chỉ cần một bài kiểm tra từ một địa chỉ.
- Chọn loại proxy phù hợp với nhiệm vụ: trung tâm dữ liệu cho RPS và giới hạn tốc độ, residential/mobile cho logic địa lý.
- Thực hiện phép đo baseline không có proxy, để tách biệt độ trễ mạng khỏi độ trễ của proxy.
- Kiểm tra giới hạn kết nối đồng thời với nhà cung cấp proxy cho mức VU cần thiết.
- Cấu hình xác thực proxy (tên đăng nhập/mật khẩu hoặc whitelisting IP của máy chạy).
- Quyết định xem có cần phiên sticky cho VU hay xoay vòng cho mỗi yêu cầu.
- Chạy bài kiểm tra trong khoảng thời gian ngắn (1-2 phút) trước khi chạy toàn bộ, để kiểm tra cấu hình.
Kết luận
Proxy trong k6 và JMeter là cách hiệu quả để mô phỏng lưu lượng từ các địa chỉ IP khác nhau, kiểm tra hành vi giới hạn tốc độ và logic phụ thuộc vào địa lý. Nhưng đây không phải là sự thay thế cho việc lập kế hoạch bài kiểm tra tải một cách hợp lý: băng thông của máy chủ, sự ổn định của backend dưới tải cạnh tranh và lập kế hoạch năng lực thực tế không được kiểm tra và cải thiện bởi proxy. Sử dụng chúng một cách có mục đích — ở những nơi mà bài kiểm tra thực sự phụ thuộc vào địa chỉ IP của khách hàng, chứ không phải như một công cụ đa năng “để đảm bảo tính công bằng”.
Nếu nhiệm vụ là kiểm tra giới hạn theo IP và mô phỏng lưu lượng lớn với băng thông cao, hợp lý là bắt đầu với proxy trung tâm dữ liệu — chúng cung cấp độ trễ tối thiểu và có thể chịu được nhiều phiên đồng thời. Đối với các bài kiểm tra liên quan đến logic địa lý và sự tin tưởng của các hệ thống chống bot vào nguồn gốc của lưu lượng, các proxy dân cư sẽ phù hợp hơn, và cho các kịch bản ngách với lưu lượng di động — IP di động.