1. はじめに:負荷テストにおける「同時性」への疑問
- 既存SOAPサービスの限界性能を正確に測定するため、高頻度でリクエストを送信する負荷ツールをPythonで自作した。
- 負荷テストの鍵は、「個々のリクエストがサーバーの応答待ちに引きずられず、独立して同時的に発行されるか」 にある。
- この同時性を高め、CPUコアを効率的に活用できるPython標準ライブラリ
multiprocessingをツールの設計に採用した。
1.1 コードサンプル
2. 負荷テストツールの実装(pyApiAtac_mp.pyの解説)
2.1. multiprocessingによるリクエスト並列化
リクエストの生成から送信までを独立したプロセスで実行するため、multiprocessing.Processを使用。
プロセスはそれぞれが独自のメモリ空間とGIL(Global Interpreter Lock)を持つようなので、リクエスト処理が並列(完全に同時)に実行されるように考慮した。
# pyApiAtac_mp.py の主要部分 (抜粋)
# Processを起動してリクエストを送信
process = mp.Process(target=send_soap_request, args=(request_count,))
processes.append(process)
process.start()
2.2. ログ追跡のための識別子埋め込み
リクエストがどのプロセスから送られたかをネットワークキャプチャとサーバーログの両方で識別できるように、SOAPペイロード内にプロセスID(PID)と連番を組み合わせた識別子(例: P12345-R10)を埋め込んだ。
3. Wiresharkによる動作確認:POSTアクセスは本当に同時発行されているか?
3.1. 検証方法
負荷ツール実行中にネットワークパケットをキャプチャし、サーバーへ向かうPOSTリクエストのタイムスタンプを、マイクロ秒単位で比較した。
リクエストが同時的に発行されていれば、タイムスタンプが極めて近接するはずである。
3.2. 検証で確認したパケットキャプチャ例
実際にキャプチャされたログデータの一部を以下に示す。
| パケット# | Time (秒.マイクロ秒) | Source Port | Protocol | Info(アクション) |
|---|---|---|---|---|
| 12601 | 19:54:56.338274 | 61266 | HTTP/XML | POST /soap/endpoint HTTP/1.1 |
| 12605 | 19:54:56.338401 | 61267 | HTTP/XML | POST /soap/endpoint HTTP/1.1 |
| 12613 | 19:54:56.338588 | 61268 | HTTP/XML | POST /soap/endpoint HTTP/1.1 |
| 12615 | 19:54:56.338619 | 61265 | HTTP/XML | POST /soap/endpoint HTTP/1.1 |
3.3. 分析結果と結論
- 異なるSource Portを持つ複数のリクエストが、わずか 0.000345秒(345マイクロ秒) の間に立て続けにネットワーク上に記録されている。
- もしリクエストが前の応答を待って直列に発行されていた場合、この短い時間間隔で4つのリクエストが送出されることはありえない。
- この結果は、
multiprocessingによって生成された複数のプロセスが完全に同時に動作し、SOAPサービスへ同時的にPOSTアクセスを実行していることを、ネットワークの客観的な証拠をもって証明している。
4. まとめ
-
multiprocessingの導入により、SOAP負荷ツールは高い同時実行性を実現できていることが検証できた。 - 負荷テストの検証においては、ネットワークI/Oのログを確認することで、プログラムの動作が設計通りかを確認できる。