質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

解決済

HTTP リクエスト/レスポンスにかかる時間について

kuttsun
kuttsun

総合スコア53

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

2回答

0リアクション

2クリップ

314閲覧

投稿2022/08/01 09:42

前提

  • Docker コンテナ内で python のアプリケーションを動作させています。
  • アプリケーションでは複数のスレッドが動いています(5〜10程度)
  • requests モジュールを使って HTTP 通信を行っています

発生している問題・エラーメッセージ

以下のようにしてリクエストからレスポンスまでの時間を計測しています。

py

start = time.time() response = requests.post(url, files=files, data=data) elapsed_time = time.time() - start

また、response オブジェクトの elapsed でもリクエストからレスポンスまでの時間を取得できますが、

py

response.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

data = {} files = {} for input in inputs: json_data = input['json'] ret, jpeg_data = cv2.imencode('.jpg', input['image']) if not ret: continue data[input['key']] = json.dumps(json_data), # dict -> str への変換 files[input['key']] = ("", jpeg_data.tobytes(), 'image/jpeg') # ndarray -> bytes への変換 start = time.time() response = requests.post(url, files=files, data=data) elapsed_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

以上、よろしくお願いいたします。

以下のような質問にはリアクションをつけましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

リアクションが多い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

a.com

2022/08/01 15:58

リダイレクトしてるわけではないですよね?
kuttsun

2022/08/03 10:05

リダイレクトはしていませんが、通信相手はさらに下位のモジュールに HTTP リクエストを送ってはいます。
a.com

2022/08/04 05:34

レスポンスbody終了まで時間がかかっているかもしれないので postではなくてheadにしたらどうでしょう?headだとセッションcloseとconnectionpoolのcloseのみの処理の差ですが 私の環境ではそれでも5msec程度の差がでました。
kuttsun

2022/08/18 04:43

ありがとうございます。 マルチプロセス化したところ、私の環境でも数msecぐらいになりました。 そんなに大きなデータをやりとりしているつもりはありませんが、スレッドが多いことでヘッダーやペイロードなどの解析部分に影響が出ていたのかもしれません。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。