前提
- Docker コンテナ内で python のアプリケーションを動作させています。
- アプリケーションでは複数のスレッドが動いています(5〜10程度)
- requests モジュールを使って HTTP 通信を行っています
発生している問題・エラーメッセージ
以下のようにしてリクエストからレスポンスまでの時間を計測しています。
py
1start = time.time() 2response = requests.post(url, files=files, data=data) 3elapsed_time = time.time() - start
また、response オブジェクトの elapsed
でもリクエストからレスポンスまでの時間を取得できますが、
py
1response.elapsed.total_seconds()
この2つの値の差 (elapsed_time - response.elapsed.total_seconds()
) がかなり大きく、またばらつきも大きいのが問題となっています。
具体的には、response.elapsed.total_seconds()
の値が 250msec 程度なのに対し、上述の elapsed_time
の値はそれより大体 100msec 程度は遅いです(350 msec程度)。
また値のばらつきも大きく、遅いときは 300msec〜500msec 程度遅いですが、早いときは数 10msec 程度だったりします。
response.elapsed
はリクエストの最初のバイトを送信してからレスポンスヘッダの解析が終了するまでにかかる時間を測定したものだそうなので、上記の2つに差があること自体はわかるのですが、response.elapsed
での測定範囲以外の処理で数百 msec 以上も時間がかかるものでしょうか?
ある程度のリアルタイム性が要求されているシステムなので、この2つの値の差と値のばらつきをできるだけ小さくしたいのですが、どうしていいかわからず途方にくれている状態です。
これが仕方のないものなのか?post メソッドで送るデータに問題があるのか?他のモジュールだと違うのか?他に何か改善する方法があるのか?
など、何か情報をいただければ助かります。
該当のソースコード
リクエストの部分ですが、もう少し詳しく記述すると、以下のような感じです。
py
1data = {} 2files = {} 3for input in inputs: 4 json_data = input['json'] 5 ret, jpeg_data = cv2.imencode('.jpg', input['image']) 6 if not ret: 7 continue 8 data[input['key']] = json.dumps(json_data), # dict -> str への変換 9 files[input['key']] = ("", jpeg_data.tobytes(), 'image/jpeg') # ndarray -> bytes への変換 10start = time.time() 11response = requests.post(url, files=files, data=data) 12elapsed_time = time.time() - start
サーバー側に multipart/form-data
で JPEG 画像3枚と JSON を送っています。
input['image']
には OpenCV の VideoCapture で取得したフレームデータ(ndarray
型)が入っています。
試したこと
1リクエストでの話なので asyncio とかは関係ないと思いますが、一応 aiohttp モジュールでも試してみました。
しかし状況はほとんど変わりませんでした(若干遅くなったくらい)。
スレッドをやめて全てを asyncio で処理することも試したいですが、変更コストが大きすぎて無理です。
補足情報(FW/ツールのバージョンなど)
- docker 20.10.12
- Ubuntu 20.04
- python 3.8.10
- requests 2.22.0
以上、よろしくお願いいたします。

回答2件
あなたの回答
tips
プレビュー