負荷テストがレート制限、WAF、または地理的負荷分散に直面したとき、最初に思いつくのは「異なるIPからトラフィックを送信する」ということです。理にかなっていますが、実際にはk6とJMeterにおけるプロキシは限られたタスクを解決するだけで、残りはテストアーキテクチャで修正する必要があります。この記事では、両方のツールにプロキシを技術的に接続する方法、どのIPタイプが適しているか、プロキシサーバーの責任範囲がどこで終わるかを解説します。
負荷テストに異なるIPが必要な理由
デフォルトでは、k6とJMeterはすべてのトラフィックをテストが実行されているサーバー(またはCI/CDのクラウドマシン)からの1つのIPアドレスで送信します。これは90%のシナリオでは問題ありませんが、いくつかのケースでは1つのIPでは不十分です:
- IPレベルでのレート制限。 多くのAPIやロードバランサー(nginx limit_req、AWS WAF、Cloudflare)は、1秒あたりのリクエスト数を1つのアドレスから制限します。実際のユーザーは数千の異なるIPからアクセスしますが、あなたのテストは1つのIPから行われ、アプリケーションの実際のボトルネックに達する前に制限にぶつかります。
- 地理依存ロジックのテスト。 CDN、ターゲットコンテンツ、地域価格、地理的ブロックなどは、特定の国からのIPで確認する必要があります。テストランナーが物理的に存在するデータセンターからではなく。
- ロードバランサーとAnycastネットワークの確認。 インフラストラクチャがクライアントのIPに基づいてトラフィックを地域ごとに分配する場合、1つのアドレスからのテストは1つのルートのみを確認し、ネットワーク全体を確認しません。
- 実際のトラフィック分配のシミュレーション。 プロダクショントラフィックのIPは、プロバイダー、サブネット、時にはモバイルオペレーターによって分散されています。これはCDN、キャッシュ、エッジロジックの動作に影響を与えます。
重要なのは、バックエンドのパフォーマンスをテストしている場合(あなたのAPIがどれだけのRPSに耐えられるか)、プロキシはほとんど必要ないということです。そこでは、ソースの多様性ではなく、純粋な負荷が重要です。プロキシは、テストシナリオがクライアントのIPアドレスに依存している場合に必要です。
適切なプロキシの種類:データセンター、レジデンシャル、モバイル
プロキシの種類の選択は、あなたがテストしているものに直接影響します — インフラストラクチャの帯域幅か、「生の」IPの下でのシステムの動作か。
| プロキシの種類 | 遅延と速度 | 負荷テストで使用するタイミング |
|---|---|---|
| データセンターのプロキシ | 低遅延、高帯域幅 | レート制限の確認、「NリクエストをIPから」の制限の回避、異なるサブネットからの大量のRPSの生成 |
| レジデンシャルプロキシ | 遅延が高く、速度は実際のユーザーの回線に制限される | 地理ロジックのテスト、CDNおよびアンチボットシステムの確認、これらはデータセンターよりもレジデンシャルレンジを信頼する |
| モバイルプロキシ | 最も高い遅延、不安定な速度 | ニッチなシナリオ:モバイルAPIのテスト、IPの頻繁な変更時の動作(オペレーターがクライアントのアドレスを動的に変更する) |
RPSとレート制限の純粋な確認には、ほとんどの場合データセンターのプロキシが十分です — それらは安定した低遅延を提供し、外部のネットワークの不安定性によってテスト結果を歪めません。レジデンシャルおよびモバイルIPは地理テストにリアリズムを追加しますが、分析メトリクスに考慮する必要がある独自の遅延をもたらします — さもなければ「プロキシネットワークが遅い」と「あなたのサーバーが遅い」を混同しやすくなります。
k6におけるプロキシの設定
k6はJavaScriptで書かれたツール(エンジンはGoで書かれ、スクリプトはJSで書かれます)で、デフォルトではスクリプトオプションを介したHTTPプロキシの組み込みサポートはありません:k6のプロキシは環境変数またはシステム設定を介して指定されます。なぜなら、k6は内部でGoのHTTPクライアントを使用しているからです。
最も簡単な方法は環境変数です:
export HTTP_PROXY="http://login:password@proxy-host:port"
export HTTPS_PROXY="http://login:password@proxy-host:port"
k6 run script.js
この方法では、テストのすべてのトラフィックが1つのプロキシを介して送信されます — 「ホワイト」IPサーバーから単に離れる必要がある場合に適しています。しかし、仮想ユーザー(VU)を異なるIPに分散させる必要がある場合は、プロキシのリストとスクリプトレベルでの選択ロジックが必要です。k6は「箱から出して」per-VUプロキシを直接サポートしていないため、一般的な回避策は、各プロセスが独自の環境変数とプールからのプロキシを持つように、複数のk6プロセスを並行して実行することです:
// 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
このアプローチは、k6 CloudやKubernetes/Docker Composeを介したオーケストレーションと組み合わせると、非常にスケーラブルです — 各コンテナは独自のプロキシ変数で起動されます。スクリプトの1回の実行内でIPのローテーションが必要な場合は、プロキシプロバイダー側でローテーションを持つプロキシを取得する方が理にかなっています(TTL付きのスティッキーセッション)、JSコード内でローテーションを構築するのではなく。
JMeterにおけるプロキシの設定
JMeterでは、環境変数なしで、HTTP Request Defaults要素またはHTTP Request Samplerの設定で直接プロキシを設定できます:
- Thread GroupにHTTP Request Defaults設定要素を追加します。
- Proxy Serverフィールドにプロキシのホストとポートを指定します。
- プロキシが認証を必要とする場合は、そのホストのログインとパスワードを持つHTTP Authorization Manager要素を追加します。
- Thread Group内のすべてのHTTP Request Samplerは、自動的にプロキシ設定を継承します。
JMeterで複数のプロキシに負荷を分散させるには、CSV Data Set Configを使用するのが便利です — プロキシのリストを含むファイルが、各スレッドのホストとポートの変数に置き換えられます:
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
CSV Data Set ConfigをThread Groupに接続し、プロキシサーバー/プロキシポートサンプラーのフィールドに${proxy_host}と${proxy_port}変数を指定します — 各JMeterスレッドはファイルから独自の行を取得し、独自のIPを介して進みます。コマンドラインから実行する場合(ヘッドレスモード、実際の負荷テストに推奨される)でも、プロキシをフラグとして渡すことができます:
jmeter -n -t test_plan.jmx -l results.jtl \
-H proxy-host -P port \
-u username -a password
この方法では、テスト全体に対して1つの共通プロキシが設定されます — 複数のプロキシを使用するシナリオでは、CSV Data Set ConfigまたはDistributed Testing(各JMeterスレーブが独自のプロキシを持つ)を使用する必要があります。
IPのローテーションと負荷分散
負荷テストにおけるIPの分配には、2つの根本的に異なるアプローチがあります:
- スレッド/VUに対する静的IPの固定。 各仮想ユーザーはセッション全体で同じIPを受け取ります — 1つのアドレスを持つ実際のユーザーを模倣します。これはスティッキーセッションプロキシまたは単にCSV/環境変数内の固定リストを介して設定されます。
- 各リクエストごとのIPのローテーション。 プロキシは各HTTPリクエストごとに送信元アドレスを変更します — レート制限からの保護を確認するのに役立ちますが、IPが毎秒変わらないユーザーの実際の動作を反映するものではありません。
現実的な負荷テストでは、90%のケースでセッション全体でVU/スレッドにIPを固定する方が正しいです — これにより、テストは多くの独立したユーザーの動作を正確に反映し、人工的なノイズを生み出しません。各リクエストごとのローテーションは、特定のシナリオでのみ有効です — たとえば、レート制限ルールの発動をターゲットにした確認時などです。
プロキシが絶対に代替できないもの
ここがこの記事の重要なポイントです:プロキシは「どのIPからリクエストが来るか」という問題を解決しますが、実際に負荷テストが確認する問題を解決するわけではありません。
- テストランナーの帯域幅。 負荷生成器(k6/JMeterを実行しているマシン)がCPU、メモリ、またはネットワークカードに制限されている場合、プロキシでは修正できません。プロキシは余分なネットワークホップと独自の遅延を追加し、ランナーの負荷を軽減するわけではありません。
- テスト対象サーバーの実際の帯域幅。 サーバーは負荷に耐えるか、耐えないかのどちらかです — クライアントのIPアドレスはこれに影響を与えません。明示的なIPによるレート制限のケースを除いて。
- 応答時間のメトリクスの信頼性。 プロキシは独自の遅延を追加します(特にレジデンシャルおよびモバイル)、これが応答時間の一部としてレポートに含まれます。プロキシの遅延を別に引き算しないと、最終的なレイテンシーレポートは歪み、プロダクションメトリクスとの比較には適さなくなります。
- 実際のトラフィックに基づくインフラストラクチャのスケーリング。 プロキシを使用した負荷テストは、特定のリクエストパターンの下での動作を示しますが、実際のプロダクションログに基づいたキャパシティプランニング、自動スケーリング、負荷プロファイルを代替するものではありません。
- 負荷下でのビジネスロジックの正確性の確認。 レースコンディション、データベースのロック、キューの劣化 — これは競合テストやプロファイリングで確認されるものであり、送信元IPの変更ではありません。
プロキシは「異なるIPからのトラフィックをエミュレートする」という特定のタスクのためのツールであり、負荷テストの普遍的な強化ツールではありません。もし目的がバックエンドがどれだけのRPSに耐えられるかを理解することであれば、ほとんどの場合、プロキシは全く必要ありません:適切に設定されたkeep-aliveと接続プールを持ついくつかのテストランナーがあれば十分です。
プロキシを使用したテストでの典型的なミス
実際には、負荷テストにおけるプロキシに関するほとんどの問題は、いくつかの繰り返し発生するミスに起因しています。
- プロキシの遅延とテスト対象サービスの遅延を混同する。 ベースライン測定(プロキシなしの直接リクエスト)がないと、プロキシサーバーがどれだけのミリ秒を追加しているかを理解することはできません。
- 純粋な帯域幅が必要な場合にモバイルまたはレジデンシャルプロキシを使用する。 これらのプロキシは、最終デバイスの実際の回線に制限されており、数万のRPSを物理的に処理できません — 純粋な負荷にはデータセンターのプロキシが必要です。
- 多くのVUに対してIPプールが不足している。 5000の仮想ユーザーに対して10のプロキシアドレスがある場合、テストは同じレート制限にぶつかります。ただし、遅延が発生します — サービスはすぐに「10のIP、数千のリクエスト」というパターンを認識します。
- プロキシ側でのタイムアウトを無視する。 高い競合負荷がかかると、プロキシサーバーが接続を拒否し始めることがあります — プロキシプロバイダーに同時セッションの制限を事前に確認することが重要です。
- ホワイトリスト/認証の確認なしにテストを実行する。 プロキシがIPによる認証を必要とし、テストが動的なランナーアドレスからCI/CDで実行される場合、リクエストは407 Proxy Authentication Requiredで失敗し、テスト結果は無意味になります。
テスト開始前のチェックリスト
- 本当に異なるIPが必要か、1つのアドレスからのテストで十分かを確認しました。
- タスクに応じてプロキシの種類を選択しました:RPSとレート制限にはデータセンター、地理ロジックにはレジデンシャル/モバイル。
- プロキシなしのベースライン測定を行い、ネットワークの遅延とプロキシの遅延を分離しました。
- 必要なVUレベルに対してプロキシプロバイダーの同時接続制限を確認しました。
- プロキシの認証を設定しました(ログイン/パスワードまたはランナーのIPのホワイトリスト)。
- VUにスティッキーセッションが必要か、各リクエストごとのローテーションが必要かを決定しました。
- 構成を確認するために、完全な実行の前に短い間隔(1-2分)でテストを実行しました。
結論
k6とJMeterにおけるプロキシは、異なるIPアドレスからのトラフィックをエミュレートし、レート制限や地理依存ロジックの動作を確認するための効果的な方法です。しかし、これは負荷テストの適切な計画の代替にはなりません:サーバーの帯域幅、競合負荷下でのバックエンドの安定性、実際のキャパシティプランニングをプロキシは確認せず、改善もしません。プロキシは、テストが本当にクライアントのIPアドレスに依存している場合にのみ、特定の目的で使用してください。
もし目的がIPによる制限を確認し、高帯域幅の大量トラフィックをシミュレートすることであれば、データセンターのプロキシから始めるのが理にかなっています — それらは最小限の遅延を提供し、大量の同時セッションに耐えます。地理ロジックに依存し、トラフィックの出所に対するアンチボットシステムの信頼を必要とするテストには、レジデンシャルプロキシが適しており、モバイルトラフィックを伴うニッチなシナリオにはモバイルIPが最適です。