インフラストラクチャ:データセンターのサーバー、OS-Debian Squeeze、ウェブサーバー-Apache 2.2.16
状況:
ライブサーバーは私たちの顧客によって毎日使用されているため、調整や改善をテストすることは不可能です。したがって、ライブサーバー上のインバウンドHTTPトラフィックを1つまたは複数のリモートサーバーにリアルタイムで複製します。トラフィックはローカルWebサーバー(この場合はApache)とリモートサーバーに渡す必要があります。これにより、構成を調整し、ベンチマークや現在のライブサーバーとの比較のためにリモートサーバーで異なるコードや更新されたコードを使用できます。現在、ウェブサーバーは約聞いています。クライアント構造のため、80と443の他に60個の追加ポート。
質問:1つまたは複数のリモートサーバーへのこの複製をどのように実装できますか?
私たちはすでに試しました:
ここではオプションが不足しています。
IPTABLESを使用するときにTEE機能の「ローカルネットワーク内のサーバー」の適用を無効にする方法はありますか?
IPTABLESまたはルートのさまざまな使用法によって目標を達成できますか?
この目的のためにテストされ、これらの特定の状況で機能する別のツールを知っていますか?
Tプロキシの別のソースはありますか(これは、AFAIKの要件に完全に適合します)?
返信ありがとうございます。
編集:05.02.2014
pythonスクリプトは次のとおりです。これは、必要な方法で機能します。
import socket
import SimpleHTTPServer
import SocketServer
import sys, thread, time
def main(config, errorlog):
sys.stderr = file(errorlog, 'a')
for settings in parse(config):
thread.start_new_thread(server, settings)
while True:
time.sleep(60)
def parse(configline):
settings = list()
for line in file(configline):
parts = line.split()
settings.append((int(parts[0]), int(parts[1]), parts[2], int(parts[3])))
return settings
def server(*settings):
try:
dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
dock_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
dock_socket.bind(('', settings[0]))
dock_socket.listen(5)
while True:
client_socket = dock_socket.accept()[0]
client_data = client_socket.recv(1024)
sys.stderr.write("[OK] Data received:\n %s \n" % client_data)
print "Forward data to local port: %s" % (settings[1])
local_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
local_socket.connect(('', settings[1]))
local_socket.sendall(client_data)
print "Get response from local socket"
client_response = local_socket.recv(1024)
local_socket.close()
print "Send response to client"
client_socket.sendall(client_response)
print "Close client socket"
client_socket.close()
print "Forward data to remote server: %s:%s" % (settings[2],settings[3])
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((settings[2], settings[3]))
remote_socket.sendall(client_data)
print "Close remote sockets"
remote_socket.close()
except:
print "[ERROR]: ",
print sys.exc_info()
raise
if __name__ == '__main__':
main('multiforwarder.config', 'error.log')
このスクリプトを使用するためのコメント:
このスクリプトは、いくつかの構成済みローカルポートを別のローカルおよびリモートソケットサーバーに転送します。
構成:
次の内容を含む構成ファイルのport-forward.config行に追加します。
エラーメッセージは「error.log」ファイルに保存されます。
スクリプトは設定ファイルのパラメータを分割します:
各構成行をスペースで分割します
0:待機するローカルポート
1:転送先のローカルポート
2:宛先サーバーのリモートIPアドレス
3:宛先サーバーのリモートポート
および戻り設定
それは無理だ。 TCPはステートフルプロトコルです。ユーザーエンドコンピューターは接続のすべてのステップに関与しており、通信を試みる2つの個別のサーバーに応答することはありません。Webサーバー上のすべてのhttp要求を収集するだけです。またはいくつかのプロキシとそれらを再生しますが、ライブサーバーの同時実行性またはトラフィック状態を正確に提供しません。
あなたの説明から、GORはあなたのニーズに合っているようです。 https://github.com/buger/gor/ 「HTTPトラフィックをリアルタイムで再生します。本番環境からステージング環境および開発環境へのトラフィックを再生します。」 ?
Teeproxy を使用してトラフィックを複製できます。使い方は本当に簡単です:
./teeproxy -l :80 -a localhost:9000 -b localhost:9001
a
本番サーバーb
テストサーバーWebサーバーの前にHAproxy(roundrobin
付き)を配置すると、トラフィックの50%をテストサイトに簡単にリダイレクトできます。
/------------------> production
HAproxy / ^
\ /
\---- teeproxy -.....> test (responses ignored)
ステートフルプロトコルであるTCPは、@ KazimierasAliulisが指摘しているように、別のホストでパケットのコピーをブラストするだけでは対応できません。
TCPターミネーションの層でパケットを取得し、それらを新しいものとしてリレーするTCPストリームは妥当です。 複製ツール あなたにリンクされているように見えます。これはTCPプロキシとして動作し、TCPステートマシンが適切に動作できるようにします。テストマシンからの応答は、それはまさにあなたが欲しいものの法案に合うように聞こえます。
なぜあなたがデュプリケーターツールを受け入れられないものとして書いたのか、私にははっきりしません。ツールは単一のポートでのみリッスンするため、ツールの複数のインスタンスを実行する必要がありますが、おそらく、これらの異なるリッスンポートのそれぞれをバックエンドシステムの異なるポートにリレーする必要があります。そうでない場合は、iptables DNATを使用して、すべてのリスニングポートをデュプリケータツールの単一のリスニングコピーに転送できます。
テストするアプリケーションが単純なものでない限り、タイミングと内部アプリケーションの状態に関連するこのテスト方法論に問題が発生すると思います。あなたがしたいことは一見単純そうに聞こえます-私はあなたが多くのEdgeケースを見つけることになると思います。
私は同様のことをしようとしていますが、単にサーバーの負荷をシミュレートしようとしているのであれば、負荷テストフレームワークのようなものを検討します。私は過去にlocust.ioを使用しましたが、サーバーの負荷をシミュレートするのに非常によく機能しました。これにより、多数のクライアントをシミュレートして、別のサーバーにトラフィックを転送するという面倒なプロセスを実行しなくても、サーバーの構成を試すことができます。
私の会社にも同様の要件があり、パケットを複製して別のホストに送信しました(市場データシミュレーターを実行し、市場データをリッスンする一時的なソリューションが必要でしたTCPフィード、各パケットを取り込みますが、各パケットのクローンを別のシミュレータサーバーに送信する)
このバイナリは非常にうまく動作し、TCP Duplicatorのバージョンですが、jscriptではなくgolangで記述されているため、高速であり、宣伝どおりに機能します。
「ライブサーバーのインバウンドHTTPトラフィックを1つまたは複数のリモートサーバーにリアルタイムで複製したい」という限り、上記に記載されていない1つの方法があります。それは、接続先のスイッチにミラーポートを構成することです。
Cisco Catalystスイッチの場合、これはSPANと呼ばれます(詳細 こちら )。シスコ環境では、ミラーリングされたポートを別のスイッチに配置することもできます。
しかし、これの目的はトラフィック分析であるため、単方向になります-上記の最初の段落の引用テキスト内のキーワード:inbound。このポートでリターントラフィックが許可されるとは思いません。許可すると、重複するリターントラフィックにどのように対処しますか?それはおそらくあなたのネットワークに大混乱をもたらすでしょう。
つまり、リストに1つの可能性を追加したいだけですが、実際には一方通行のトラフィックになる可能性があるという警告があります。多分あなたはそのミラーポートにハブを置くことができ、開始されたセッションをピックアップして応答するローカルクライアントシミュレーターによって複製されたサーバー応答を渡すことができますが、その場合、あなたの複製サーバーへの着信トラフィックを複製するでしょう...欲しいです。
Node.jsを使用して、同様の目的でリバースプロキシ/ロードバランサーも作成しました(現時点では面白くするためのものであり、現時点では本番環境に対応していません)。
https://github.com/losnir/ampel
それは非常に独断的であり、現在サポートしています:
GET
ラウンドロビン選択の使用(1:1)POST
リクエスト分割を使用します。 「マスター」と「シャドウ」の概念はありません-応答する最初のバックエンドはクライアント要求を処理するものであり、その後、他のすべての応答は破棄されます。誰かがそれが便利だと思ったら、私はそれをより柔軟に改善することができます。