
オンラインのリクエスト複製およびTCPストリーム再生ツールで、実際のテスト、パフォーマンステスト、安定性テスト、ストレステスト、負荷テスト、スモークテストなどに最適です。
TCPCopyは、インターネットサーバーアプリケーションの現実的なテストのためのTCPストリーム再生ツールです。
実際のライブトラフィックはインターネットサーバーアプリケーションのテストにとって重要ですが、オンライン環境の複雑さのため、正確にシミュレートすることは困難です。より現実的なテストを可能にするために、TCPCopyは本番ワークロードに非常に近いテストワークロードを生成するライブフロー再現ツールとして開発されました。TCPCopyは中国の企業で広く使用されています。
TCPCopyは本番システムへの影響を最小限に抑え、追加のCPU、メモリ、帯域幅のみを消費します。再現されたワークロードは、リクエストの多様性、ネットワークレイテンシ、リソース使用量の点で本番環境を反映します。

図1. TCPCopyアーキテクチャの概要。
図1に示すように、TCPCopyはtcpcopyとinterceptの2つのコンポーネントで構成されています。tcpcopyコンポーネントはオンラインサーバー上で動作し、ライブリクエストをキャプチャします。一方、interceptはアシスタントサーバー上で動作し、応答情報をtcpcopyに渡すなどのタスクを実行します。テストアプリケーション自体はターゲットサーバー上で動作します。
デフォルトでは、tcpcopyはrawソケットを使用してネットワーク層でパケットをキャプチャします(図のオレンジ色の矢印で示されています)。TCPインタラクションシミュレーション、ネットワークレイテンシ制御、上位層インタラクションシミュレーションなどの処理を担当します。その後、rawソケットを使用して出力としてパケットをターゲットサーバーに送信します(図の薄赤色の矢印で示されています)。
ターゲットサーバーで必要な唯一のタスクは、応答パケット(図の薄緑色の矢印で示されています)をアシスタントサーバーに転送するためのルートルールを設定することです。
interceptコンポーネントの役割は、デフォルトで応答ヘッダーをtcpcopyに転送することです。応答パケットをキャプチャし、応答ヘッダー情報を抽出し、専用チャネル(図の水色の矢印で示されています)を介してこの情報をtcpcopyに送信します。応答ヘッダーを受信すると、tcpcopyはその情報を使用してオンラインパケットの属性を変更し、後続のパケットを送信します。
ターゲットサーバーからの応答がアシスタントサーバーにルーティングされ、アシスタントサーバーがブラックホールとして機能することに注意することが重要です。
interceptについては、2つのオプションがあります:
git clone git://github.com/session-replay-tools/intercept.git。tcpcopyについても、2つのオプションがあります:
git clone git://github.com/session-replay-tools/tcpcopy.git。interceptディレクトリに移動:cd intercept./configure makeinterceptツールをインストール:make installinterceptの設定オプション--single interceptを非分散モードで実行します。--with-pfring=PATH PF_RINGライブラリソースへのパスを指定します。--with-debug デバッグサポート付きでinterceptをコンパイルし、ログをファイルに保存します。tcpcopyのインストールtcpcopyディレクトリに移動:cd tcpcopy./configure maketcpcopyツールをインストール:make installtcpcopyの設定オプション--offline pcapファイルからTCPストリームを再生します。--pcap-capture データリンク層でパケットをキャプチャします。--pcap-send IP層の代わりにデータリンク層でパケットを送信します。--with-pfring=PATH PF_RINGライブラリソースへのパスを指定します。--set-protocol-module=PATH tcpcopyを外部プロトコルモジュールと連携するように設定します。--single interceptとtcpcopyの両方が--singleオプションで設定されている場合、1つのtcpcopyインスタンスのみがinterceptと連携し、パフォーマンスが向上します。--with-tcmalloc mallocの代わりにtcmallocを使用します。--with-debug デバッグサポート付きでをコンパイルし、ログをファイルに保存します。tcpcopyとinterceptの両方が./configureを使用して設定されていると仮定します。
サーバーアプリケーションを実行しているターゲットサーバー上:
応答パケットをアシスタントサーバーに転送するためのルートルールを設定します。例えば、61.135.233.161がアシスタントサーバーのIPアドレスの場合、次のルートコマンドを使用して、62.135.200.x範囲のクライアントからのすべての応答をアシスタントサーバーに転送します:
route add -net 62.135.200.0 netmask 255.255.255.0 gw 61.135.233.161
interceptを実行しているアシスタントサーバー上(root権限またはCAP_NET_RAWケイパビリティが必要):
./intercept -F <フィルタ> -i <デバイス>
フィルタ形式はpcapフィルタと同じであることに注意してください。例:
./intercept -i eth0 -F 'tcp and src port 8080' -d
この例では、interceptはeth0ネットワークデバイスを使用して、ポート8080でリッスンしているTCPベースのアプリケーションからの応答パケットをキャプチャします。
アシスタントサーバーではip_forwardが有効になっていないことに注意してください。
オンラインソースサーバー上(root権限またはCAP_NET_RAWケイパビリティが必要):
./tcpcopy -x localServerPort-targetServerIP:targetServerPort -s <interceptサーバー> [-c <IP範囲>]
例えば(61.135.233.160がターゲットサーバーのIPアドレスと仮定):
./tcpcopy -x 80-61.135.233.160:8080 -s 61.135.233.161 -c 62.135.200.x
CAP_NET_RAWケイパビリティが必要です(例:setcap CAP_NET_RAW=ep tcpcopy)。interceptの./configure --with-resp-payloadオプションは、tcpcopyの./configureオプションと一緒に使用できません。ip_forwardが有効になっていないことを確認してください。./tcpcopy -hまたは./intercept -hを実行してください。以下のセクションで詳述するように、いくつかの要因がTCPCopyに影響を与える可能性があります。
デフォルトでは、tcpcopyはオンラインサーバー上のネットワーク層でパケットをキャプチャするためにrawソケット入力インターフェースを使用します。高負荷時には、システムカーネルが一部のパケットをドロップする可能性があります。
--pcap-captureで設定すると、tcpcopyはデータリンク層でパケットをキャプチャし、カーネル内でパケットをフィルタリングできます。pcapキャプチャでPF_RINGを使用すると、パケットロスを減らすことができます。
最適なキャプチャのために、スイッチを介して入力パケットをミラーリングし、ロードバランサーでトラフィックを複数のマシンに分散することを検討してください。
tcpcopyはデフォルトでrawソケット出力インターフェースを使用して、ネットワーク層でパケットをターゲットサーバーに送信します。ip_conntrackの問題を回避したり、パフォーマンスを向上させるには、代わりに--pcap-sendを使用してデータリンク層でパケットを送信します。
tcpcopyによって送信されたパケットは、ターゲットサーバーに到達する前に課題に直面する可能性があります。ソースIPアドレスがエンドユーザーのIP(デフォルト)の場合、セキュリティデバイスが無効または偽造されたものとしてパケットをドロップする可能性があります。これをテストするには、ターゲットサーバーでtcpdumpを使用します。同じネットワークセグメント内でパケットが正常に送信されているが、セグメント間では送信されていない場合、パケットは途中でドロップされている可能性があります。
これに対処するには、tcpcopy、ターゲットアプリケーション、およびinterceptを同じネットワークセグメント内にデプロイします。または、同じセグメント内のプロキシを使用して、別のセグメントのターゲットサーバーにパケットを転送します。
同じセグメント内の仮想マシンにターゲットサーバーのアプリケーションをデプロイしても、これらの問題が発生する可能性があります。
ターゲットサーバーはrpfilterを使用して送信元IPアドレスの正当性を検証し、偽造と見なされたパケットをドロップする場合があります。tcpdumpでパケットがキャプチャされているが処理されていない場合は、rpfilter設定を確認し、必要に応じて調整または削除してください。iptables設定などの他の問題もtcpcopyに影響を与える可能性があります。
ターゲットサーバー上のアプリケーションは、すべてのリクエストを迅速に処理できない場合があります。アプリケーションのバグや制限により、応答の遅延やソケットバッファ内の未処理リクエストが発生する可能性があります。
アシスタントサーバーでip_forwardがfalseに設定されていることを確認して、パケットのルーティングを防ぎ、ブラックホールとして機能するようにします。
まず、オンラインサーバーでtelnetを使用してテストサーバーのポートに接続します。これにより、ネットワークパスがアクセス可能かどうかを確認します。接続が失敗した場合は、以下の診断を進める前にこの問題を解決してください。
tcpcopyテスト中に、テストサーバー上のアプリケーションがリクエストを受信しないと仮定します。初期ハンドシェイクパケット(SYNパケット)がテストサーバーに到達するかどうかを確認します。
1.1 SYNパケットのみキャプチャされる:
テストサーバーでtcpdumpを使用し、複製されたSYNパケットが到着しているのを確認した場合、それらはテストサーバーのデータリンク層に到達していることを示します。netstatでアプリケーションの接続が表示されない場合、パケットがIP層でドロップされたことを意味します。rpfilterが設定されているか確認し、設定されている場合は削除すれば、通常は問題が解決します。rpfilterが設定されていない場合は、iptables設定に競合がないことを確認し、必要に応じて関連ルールを調整してください。
1.2 SYNに続いてRSTパケット: SYNパケットの直後にリセット(RST)パケットが続く場合(同じセッションで1秒未満の間隔)、ルーティングの問題または競合を示し、応答パケットが実際のクライアントに直接送り返されている可能性があります。
1.3 テストサーバーが2番目のハンドシェイクパケットで応答する: アシスタントサーバーでパケットをキャプチャして、2番目のハンドシェイクパケットが到達しているか確認します。
パケットがアシスタントサーバーに到達していない場合、 ルーティング設定が効果的でないことを示し、そのためinterceptが2番目のハンドシェイクパケットをキャプチャできず、さらなるリプレイができません。潜在的な解決策は、interceptをテストサーバー上で直接実行することです(注意:ルーティング設定は変更せず、tcpcopyの-cパラメータがtcpcopyがinterceptに接続するために使用するIPアドレスに設定されていないことを確認してください。そうしないと、tcpcopyはinterceptに接続できません)。
2番目のハンドシェイクパケットがキャプチャされた場合、 ip_forwardが有効になっているか確認します。有効な場合は、この設定を無効にしてください。応答パケットがクライアントに直接送り返され、テストに干渉する可能性があります。
2.1 オンラインサーバーでtcpcopyパケットがキャプチャされる:
オンラインサーバーでtcpdumpを使用してtcpcopyの転送パケットをキャプチャしたが、パケットがテストサーバーに到達しない場合、途中でドロップされたことを示します。tcpcopyの-cパラメータを使用して、クライアントIPアドレスを有効なものに変更してみてください。極端な場合、クライアントIPをtcpcopyを実行しているマシンのIPアドレスに設定します(注意:NATの問題が発生する可能性があり、interceptがテストサーバー上で実行されている場合、tcpcopyの-cパラメータがtcpcopyがinterceptに接続するために使用するIPアドレスに設定されていないことを確認してください。そうしないと、tcpcopyはinterceptに接続できません)。
2.2 オンラインサーバーでtcpcopyパケットがキャプチャされない:
tcpcopyのログにall clt:xx情報が見つからない場合、 tcpcopyがIP層でパケットをキャプチャできないことを示します。この場合、--pcap-captureオプションを使用してデータリンク層でパケットをキャプチャします。-Fパラメータ(例:'tcp and dst port 80 and dst host 10.100.1.2')と-iパラメータ(ネットワークインターフェース)を設定して、IP層のキャプチャをバイパスします。
tcpcopyのログにall clt:xx(xx > 0)が表示された場合、 tcpcopyがパケットのキャプチャに成功したが、オンラインサーバーのIP層でフィルタリングされたことを意味します。出力チェーンに関するiptables制限などを確認してください。iptablesが問題で、オンラインサーバーで変更できない場合は、--pcap-sendオプションを使用してデータリンク層からパケットを送信します。
バグや機能リクエストがありますか? 新しいIssueを開いてください。Issueを開く前に、既存のIssueを検索してください。
このプロジェクトが役立つと思われたら、寄付をご検討ください:
Copyright 2025 BSDライセンスの下で。
この文書の作成にあたり、草稿をレビューしフィードバックを提供してくださった数名の方々が重要な役割を果たしました。特にHongshen Wang氏の貢献に感謝いたします。
tcpcopyこの例では、tcpcopyは現在のサーバーのポート80でパケットをキャプチャし、クライアントIPアドレスを62.135.200.x範囲のものに変更し、これらのパケットをターゲットサーバー(61.135.233.160)のポート8080に送信します。また、61.135.233.161に接続してinterceptに応答パケットの転送を要求します。-cパラメータはオプションですが、ここではルートルールを簡略化するために使用されています。