Speedbump - 可変レイテンシをサポートするTCPプロキシ
(github.com/kffl)- SpeedbumpはGoで書かれたTCPプロキシで、プロキシされるTCPトラフィックに可変ネットワークレイテンシを追加して遅延状況をシミュレーションする
- 基本レイテンシに正弦波、のこぎり波、矩形波、三角波形式のレイテンシ成分を加えることができ、複数のレイテンシ成分を同時に組み合わせられる
- 例では、
localhost:80宛てのトラフィックをポート2000でプロキシしつつ、100msの基本遅延、100msの正弦波振幅、1mの周期を適用する構成を示している - インストールは、リリースごとの事前ビルド済みバイナリのダウンロード、ソースからの
go build、またはkffl/speedbumpコンテナイメージの実行で行える - CLIに加えて、Goの
libパッケージ経由でライブラリとして利用でき、バッファサイズ・遅延キューサイズ・ログレベル・リッスンするホストやポートなどを引数で調整できる
TCP遅延シミュレーション用プロキシ
- SpeedbumpはGoで書かれたTCPプロキシで、可変ネットワークレイテンシをシミュレーションできる
- プロキシ先はCLIの
<destination>引数で指定し、形式はhost:postと案内されている - 基本動作は、TCPトラフィックを宛先へプロキシしながら設定した遅延を追加する方式である
インストールと実行方法
- 最も簡単なインストール方法は、各releaseの
Assetsに自動添付される事前ビルド済みバイナリをダウンロードすること - ソースからビルドするには、リポジトリをクローンした後に
go buildを実行する - コンテナで実行するには、kffl/speedbumpイメージを利用できる
基本的な使用例
- ポート
2000で待ち受け、localhost:80へTCPトラフィックをプロキシしながら、基本遅延100msと正弦波振幅100ms、周期1mを適用できる- この構成では、追加レイテンシの最大値は
200ms、最小値は0になる - 実行例は
speedbump --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
- この構成では、追加レイテンシの最大値は
- 同じ構成をコンテナイメージで実行することもできる
- 例は
docker run --net=host kffl/speedbump:latest --latency=100ms --sine-amplitude=100ms --sine-period=1m --port=2000 localhost:80
- 例は
- のこぎり波の遅延成分も設定できる
- 例では、基本遅延
300ms、のこぎり波振幅200ms、周期2m、ポート2000、宛先localhost:80の構成を示している - 実行コマンドは
speedbump --latency=300ms --saw-amplitude=200ms --saw-period=2m --port=2000 localhost:80
- 例では、基本遅延
レイテンシ成分の組み合わせ
- Speedbumpは複数のレイテンシ成分を同時に適用できる
- READMEには、のこぎり波と正弦波を組み合わせた遅延グラフの例が含まれている
CLI引数とライブラリ利用
speedbump --helpはspeedbump [<flags>] <destination>形式の使用法を提供する- 主なネットワーク設定は次のとおり
--host: 待ち受けるIPまたはホスト名。指定しない場合はすべてのネットワークインターフェースにバインドする--port: 待ち受けポート。デフォルト値は8000--buffer: TCP読み取りに使用するバッファサイズ。デフォルト値は64KB--queue-size: 読み取りバッファを保存する遅延キューのサイズ。デフォルト値は1024
- 遅延関連のデフォルト値と波形オプションを提供する
--latency: プロキシトラフィックに追加される基本レイテンシ。デフォルト値は5ms--sine-amplitude,--sine-period: 正弦波レイテンシの振幅と周期--saw-amplitude,--saw-period: のこぎり波レイテンシの振幅と周期--square-amplitude,--square-period: 矩形波レイテンシの振幅と周期--triangle-amplitude,--triangle-period: 三角波レイテンシの振幅と周期
- 運用関連オプションも含まれる
--log-level: ログレベル。利用可能な値はDEBUG、TRACE、INFO、WARN、ERROR--version: アプリケーションのバージョンを表示する
- SpeedbumpはGoライブラリとしても利用でき、
libパッケージ経由で提供される - ライセンスはApache 2.0 License
1件のコメント
Hacker Newsのコメント
さまざまなActivityPub実装を、いろいろなネットワーク規模や条件でテストするために似たようなものを調べたことがあるが、必要なものはすでに自分のマシンに
tcとして全部入っていた自分のディストリビューションでは iproute2 パッケージに含まれていて、説明はここにもある: https://wiki.archlinux.org/title/advanced_traffic_control
特定のインターフェースに遅延を追加するには、
tc qdisc add dev eth0 root netem delay 100msのように実行すればいい使いやすく、Dockerコンテナでもうまく動作し、遅延・パケット損失・重複のような条件を適用でき、すでにインストールされている可能性も高い
tc/netem/tbfは本当に素晴らしい。その上に簡単なPython GUIを作って、タッチスクリーンのケースに入れたPiで動かしたことがあるが、「パケットドロップ: [0%] [1%] [10%] [50%] / パケット破損: ...」のような小さな黒い箱で、顧客はかなり感心していたこういうフロントエンドが商用ハードウェア製品としてあまり見当たらないのは意外で、検索で見落としていないなら市場に存在しないようだ
tcの欠点は、受信パケットに適用しようとすると少し変で扱いづらいことだ以前、特定の商用衛星端末をまねるために自作のエミュレーターを作ったことがある。その端末はパケットをキューにため込み、特定のしきい値に達するか時間制限を超えるとまとめて一気に送り出していた。また、小さなパケットを「親切にも」キューの先頭へ並べ替えて遅延を減らそうとしていたが、TCPスタックはそれを非常に嫌っていた
tcにはそれができない時間とともに変化する衛星/RFの気象影響をシミュレーションするのにかなり役立つかもしれない
Netflixが作ったのがまさにこれで、名前はlatency monkeyだった
下位サービスが「遅い」かどうかを判定するのは「利用不能」かどうかを判定するよりはるかに難しいと分かり、そのためサービスの低速化やネットワーク問題をどう処理するかを試す重要な方法だった
実装は非常に単純で、設定可能な割合でパケットをドロップし、それによって再送を強制して、相手側にはパケットが遅れて順序も乱れた状態で到着するようにしていた
最終的に、ネットワークアクセスに関するエラー処理コードで多くの問題を発見した
対話型インターネットアプリケーションを作るすべてのソフトウェアエンジニアは、日常業務でこうしたツールを必ず使うべきだと思う。TCPだけでなくQUICも必要で、DNSまで対象にするなら理想的にはすべてのUDPも含めるべきだ
作る側の人たちが金ぴかのCadillacのような計算環境しか使っていなければ、Webアプリの肥大化の90%は消えていただろうと確信している
https://firefox-source-docs.mozilla.org/devtools-user/networ...
もちろん、これはフロントエンドのブラウザベーステストにしか適用できない
災害救援のようにネットワーク接続が断続的に切れる環境では、多くのアプリがひどい動作をする
もっと多くのアプリ開発者が断続的な接続をシミュレーションしてテストすれば、他の人たちの助けになるかもしれない
「Toxiproxy is a framework for simulating network conditions」(2021) https://news.ycombinator.com/item?id=29084277#29088775 からの内容:
50バイトのパケットしか送っておらず、そのうち10個に1個が失われるからだ。その間、サーバーの1スレッドは有用な仕事ができない
Macでは内蔵ツールだけでも同じことができる
しばらく更新されていないが、名前だけでも多くを物語るプロジェクトがある: https://github.com/tylertreat/comcast
最近Macで遅いネットワークをシミュレーションしようとしてNetwork Link Conditionerを見つけたが、かなり良い。プロキシのようなものを設定する必要がない
Xcode追加ツールからインストールする必要がある
https://nshipster.com/network-link-conditioner/
Shopifyの優れたツールtoxiproxyも見る価値がある: https://github.com/Shopify/toxiproxy
ネットワーキングライブラリを自前実装してテストする際にも非常に良いやり方だ。スタックは大半の不利な状況を正しく処理できるべきだからだ
「カオスエンジニアリング」という発想は素晴らしい
Webクローラー用の進捗表示バーを開発中だが、localhostでテストすると速すぎて問題があるのか分かりづらい
speedbumpなら、
podman run --net=host kffl/speedbump:latest --latency=1s --port=8001 localhost:8000を実行して、http://localhost:8001でクローラーをテストするだけでいいすっきりしたツールだ
Windowsで使ったことのある似たツールがある
https://jagt.github.io/clumsy/
FreeBSDにも ipfw の一部としてdummynetがあり、遅延、帯域制限、キューサイズ、パケット損失を注入できる。MacOSにあるものと同じ機能だ
tcと同じようなもの?