如何將 TCP 流量複製到一台或多台遠端伺服器以進行基準測試?
基礎設施:數據中心的伺服器,作業系統 - Debian Squeeze,網路伺服器 - Apache 2.2.16
情況:
我們的客戶每天都在使用實時伺服器,因此無法測試調整和改進。因此,我們希望將實時伺服器上的入站 HTTP 流量實時復製到一個或多個遠端伺服器。流量必須傳遞到本地 Web 伺服器(在本例中為 Apache)和遠端伺服器。因此,我們可以調整配置並在遠端伺服器上使用不同/更新的程式碼進行基準測試並與目前的實時伺服器進行比較。目前,網路伺服器正在收聽大約。由於客戶端結構,除了 80 和 443 之外,還有 60 個額外的埠。
問題:如何實現對一台或多台遠端伺服器的複制?
我們已經嘗試過:
- agnoster duplicator - 這將要求每個埠打開一個會話,這是不適用的。( https://github.com/agnoster/duplicator )
- kklis 代理 - 僅將流量轉發到遠端伺服器,但不將其傳遞給 lcoal 網路伺服器。( https://github.com/kklis/proxy )
- iptables - DNAT 只轉發流量,但不將其傳遞給本地網路伺服器
- iptables - TEE 只複製到本地網路中的伺服器 -> 由於數據中心的結構,伺服器不在同一個網路中
- 在stackoverflow( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy )上為“使用代理複製tcp流量”問題提供的建議替代方案不成功。如前所述,TEE 不適用於本地網路之外的遠端伺服器。teeproxy 不再可用(https://github.com/chrislusf/tee-proxy),我們無法在其他地方找到它。
- 我們添加了第二個 IP 地址(位於同一網路中)並將其分配給 eth0:0(主 IP 地址分配給 eth0)。將這個新 IP 或虛擬介面 eth0:0 與 iptables TEE 功能或路由組合起來沒有成功。
- 為“在 debian Squeeze 上重複傳入的 tcp 流量”(在 Debian Squeeze 上重複傳入的 TCP 流量)問題提供的建議替代方案不成功。cat|nc 會話(cat /tmp/prodpipe | nc 127.0.0.1 12345 和 cat /tmp/testpipe | nc 127.0.0.1 23456)在客戶端每次請求/連接後中斷,沒有任何通知或日誌。Keepalive 並沒有改變這種情況。TCP 包未傳輸到遠端系統。
- 使用不同的 socat 選項進行額外嘗試(操作方法:http : //www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/,https ://stackoverflow.com/questions/9024227/duplicate-input- unix-stream-to-multiple-tcp-clients-using-socat)和類似的工具都沒有成功,因為提供的 TEE 函式只會寫入 FS。
- 當然,Google搜尋和搜尋這個“問題”或設置也不成功。
我們這裡的選擇已經不多了。
使用 IPTABLES 時,是否有一種方法可以禁用 TEE 功能的“本地網路中的伺服器”的強制執行?
我們的目標可以通過 IPTABLES 或 Routes 的不同用法來實現嗎?
您是否知道用於此目的的不同工具已經過測試並適用於這些特定情況?
tee-proxy 是否有不同的來源(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 是有狀態的協議。使用者端電腦參與連接的每一步,它永遠不會響應試圖與之通信的兩個單獨的伺服器。您所能做的就是收集網路伺服器或某些代理上的所有 http 請求並重播它們。但這不會給出實時伺服器的準確並發或流量條件。
根據您的描述,GOR 似乎符合您的需求。 https://github.com/buger/gor/ “HTTP 流量實時回放。回放從生產到登台和開發環境的流量。” ?