トンネルは一日中安定しているのに、大きなアップロードが始まると必ず切断される。対話的なリクエストが最初に止まり、クライアントがタイムアウトを報告し、転送が終わると接続が戻る。このパターンは、サーバーには時間内に応答する機会が一度も与えられていないため、リモートサーバーが落ちているのではなくキューイングと処理を示している。やるべきことは、制御された負荷の下で再現し、正しいカウンターを読むことだ。

一度の実行につき変数を一つだけ変え、エンドポイントは固定しておく。

再現可能な負荷比較を組み立てる

リンクがアイドルの状態で、往復時間、いくつかのアプリケーションリクエスト、トンネル自身のイベントログという基準値を記録する。次に既知のサイズのアップロードを開始し、実行中にまったく同じ測定を繰り返す。エンドポイント、クライアント、テスト先を変えないのは、二つを同時に変えても何も分からないからだ。

どのイベントが最初に現れるかに注目する。エラーより先に往復時間が上昇すればキューイングを示し、遅延が安定したままの厳しいタイムアウトは別の原因、たとえば鍵の更新やアカウント側の操作を示す。二つのパターンは異なる次の手順につながる。何かを変える前に観察を書き留めておく。

出力はタイムスタンプ付きで保存し、負荷時とアイドル時の実行を行単位で比較できるようにする。

速度ではなくキューを読む

家庭用回線はプロバイダーの機器でパケットをバッファリングしており、上りキューが満杯になると、トンネルを維持する小さな制御パケットを含めてすべてが遅れる。高い数値を報告する速度テストはその遅延についてほとんど語らず、だからこそアイドル時のテストは通り、飽和した回線は失敗する。

ping -c 20 -i 0.2 203.0.113.10
mtr -rwc 20 203.0.113.10
tc -s qdisc show dev eth0
ss -ti dst 203.0.113.10
nstat -az | grep -E 'Retrans|Timeout'

負荷時の遅延の数値をアイドル時と比較する。パケット損失なしで数十ミリ秒から数百ミリ秒へ跳ね上がればキューイングであり、遅延が安定したままの損失は別の障害を指す。

デバイスと制御経路を確認する

暗号化と転送はプロセッサ時間を消費し、小型ルーターや熱で制限されたノートPCは処理中にパケットを落とすことがある。一つのプロセスの割合ではなく全体の負荷を見るのは、カーネル内の転送と割り込み処理が人が普通に見る場所には現れないからだ。

uptime
mpstat -P ALL 1 3
dmesg | grep -i -E 'thermal|throttl'
journalctl -u openvpn-server@server --since '10 min ago' | tail -20

クライアントのタイムアウトは、予定された鍵の更新やセッションポリシーのイベントと重なることもある。アプリケーションのエラーメッセージだけでなく、イベントの順序についてクライアント自身のログを読む。

一つだけ変えて繰り返す

プラットフォームが対応していれば、アップロード速度を制限するか、バルク通信を対話的な通信より下位に分類してキューが満杯にならないようにする。そのうえで同じ作業負荷を繰り返し、以前と同じ三つの数値を比較する。速度テストを改善してもタイムアウトが残る変更は、何も直していない。

タイムアウトを一律に引き上げることと暗号化を弱めることは、どの境界が破綻したかを特定せずに症状を消す二つの変更だ。どちらも修理ではない。どちらも障害を後ろへ移し、原因の特定を難しくする。

新しいリクエストと、利用者が実際に頼っている再接続の挙動をテストして終える。苦情を引き起こした負荷の下での安定性だけが、記録する価値のある結果だ。

関連記事