記事に戻る

低速受信とAPI応答の実験データ

2026-11-02測定。記事本文の数値は本測定だけを集計しています。

条件

Linux 6.12 / aarch64 / glibc 2.36、CPython 3.11.2、Gunicorn 23.0.0、NGINX 1.22.1(Debian 1.22.1-9+deb12u10)。

ファイルと集計

API遅延グラフの点は3試行の中央値、縦線は最小〜最大です。送信/受信の棒グラフは低速2接続の6応答の中央値、黒点は個別の送信時間です。時系列図は経路ごとにp95が中央の試行を選んでいます。図によって集計単位が違うため、それぞれに明記しました。

再現について

標準ライブラリの測定コードはLinuxのsystemdユーザーサービスとcgroup v2を必要とします。prepareはDebian bookworm-securityのarm64索引と配布物を専用ディレクトリへ取得・展開し、ホストへパッケージをインストールしません。現在の配布索引から取得するため、再実行時のNGINXパッケージ版が測定時と同じとは限りません。完全に版を揃える場合はdependencies.jsonのURLとSHA-256を確認してください。

以下は元の環境と同じ条件のLinuxホストでの例です。リソースに余裕があることを確認してから実行します。既存のサービス・クラスタへ設定を適用する手順ではありません。

lab_root=$(mktemp -d /tmp/kamui-slow-client-XXXXXXXX)
cp app.py experiment.py "$lab_root/"
python3 "$lab_root/experiment.py" --root "$lab_root" --stage prepare
lab_unit="$(basename "$lab_root")-controller.service"
systemd-run --user --wait --pipe --collect --unit "$lab_unit" \
  -p CPUQuota=20% -p CPUQuotaPeriodSec=10ms -p MemoryMax=128M \
  -p MemorySwapMax=0 -p TasksMax=24 -p RuntimeMaxSec=720 -p TimeoutStopSec=3 \
  /usr/bin/python3 "$lab_root/experiment.py" --root "$lab_root" \
  --stage main --controller-unit "$lab_unit"

各試行のサーバーは測定コードのfinallyで停止します。実行後は結果を回収し、当該実験の専用サービス・プロセスが残っていないことを確認したうえで、作成した専用一時ディレクトリだけを片付けてください。

除外と限界

8MiB・1MiB/sの探索的予備測定と16MiB条件の予備測定は本測定に混ぜていません。8MiB・1MiB/sから16MiB・2MiB/sへは応答サイズと読み取り速度の両方を変えているため、条件間の差をサイズ単独の効果とは解釈しません。本測定はホスト全体のCPU閾値超過で一度安全停止し、未完了試行を除外して、完了済み17試行の後の13試行を再開しました。安全閾値やアプリ条件は変更していません。

受信側のreceive_sは、最後のソケットread直後の時刻ではありません。各読み取り後に設けた速度調整の待ち(最後の読み取り後も含む)を終えた完了時刻までを測ります。約8秒という値はこの受信ペース制御を含み、実回線の純粋な転送性能を示しません。gthread補助条件はワーカー方式・プロセス数・同時対応数を同時に変更しており、方式だけの効果や最適な担当数を切り分ける比較ではありません。

アプリはフレームワークなしで書いたWSGIアプリです。Flask・Django・FastAPI等のフレームワーク間比較、非同期方式の測定、実サービスとしてのPaaS構成の測定は実施していません。TCPバッファの個別使用量やワーカースタックも採取していないため、実測した書き込み時間・API遅延・一時ファイルと、仕様に基づく説明を区別します。

全条件を最大処理能力まで負荷をかけた実験ではありません。OSの各TCPバッファ容量、TCP_INFO、実インターネット回線、TLS、HTTP/2/3、SSE、WebSocket、低速アップロード、長時間・多数接続、ディスク枯渇を測定していません。他のWebサーバーやPaaSの性能保証には使えません。

Markdown