如何将 TCP 流量复制到一台或多台远程服务器以进行基准测试?

Sis*_*ise 34 debian proxy route iptables benchmark

基础设施:数据中心中的服务器、操作系统 - 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 ( /sf/ask/507336791/ ) 为问题“使用代理复制 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不同的选项(Howto:如何http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding//sf/ask/631695921/ unix-stream-to-multiple-tcp-clients-using-socat)和类似的工具都没有成功,因为提供的 TEE 函数只会写入 FS。
  • 当然,谷歌搜索和搜索这个“问题”或设置也没有成功。

我们在这里的选择不多了。

有没有办法在使用 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')
Run Code Online (Sandbox Code Playgroud)

使用此脚本的注释:
此脚本将一些配置的本地端口转发到另一个本地和远程套接字服务器。

配置:
添加到配置文件 port-forward.config 行,内容如下:

错误消息存储在文件“error.log”中。

该脚本拆分配置文件的参数:
用空格拆分每个配置行
0:要侦听的
本地端口 1:要转发到的本地端口
2:目标服务器的远程 IP 地址
3:目标服务器的远程端口
并返回设置

Art*_*utz 20

根据您的描述,GOR 似乎符合您的需求。 https://github.com/buger/gor/ “实时重播 HTTP 流量。重播从生产到登台和开发环境的流量。” ?

  • 这正是我一直在寻找的**,非常感谢,你让我在 Go 中写下了这个!:-) (2认同)

Kaz*_*lis 11

是不可能的。TCP 是有状态的协议。用户端计算机参与连接的每一步,它永远不会响应试图与其通信的两个独立服务器。您所能做的就是收集网络服务器或某些代理上的所有 http 请求并重放它们。但这不会给出实时服务器的精确并发或流量条件。


Tom*_*art 7

Teeproxy可用于复制流量。用法很简单:

./teeproxy -l :80 -a localhost:9000 -b localhost:9001
Run Code Online (Sandbox Code Playgroud)
  • a 生产服务器
  • b 测试服务器

当您roundrobin在您的网络服务器之前放置一个 HAproxy(带有)时,您可以轻松地将 50% 的流量重定向到测试站点:

         /------------------> production
HAproxy /                 ^
        \                /
         \---- teeproxy -.....> test (responses ignored)
Run Code Online (Sandbox Code Playgroud)