如何将TCPstream量复制到一个或多个远程服务器以进行基准testing?

基础架构:数据中心,操作系统中的服务器 – Debian Squeeze,Webserver – Apache 2.2.16


情况:

现场服务器每天都在使用我们的cusotmers,这使得不可能testing调整和改进。 因此,我们希望将实时服务器上的入站HTTPstream量实时复制到一个或多个远程服务器。 stream量必须传递到本地Web服务器(在本例中为Apache),并传递到远程服务器。 因此,我们可以调整configuration,并在远程服务器上使用不同的/更新的代码,以便与当前的现场服务器进行基准testing和比较。 目前,networking服务器正在收听约。 由于客户结构的原因,除了80和443之外还有60个附加端口。


问题:如何重复执行一个或多个远程服务器?

我们已经尝试过了:

  • agnoster复制器 – 这将需要每个端口打开一个不适用的会话。 ( https://github.com/agnoster/duplicator )
  • kklis代理 – 只会将stream量转发到远程服务器,但不会将它传递给lcoal web服务器。 ( https://github.com/kklis/proxy )
  • iptables – DNAT只转发stream量,但不传递给本地networking服务器
  • iptables – TEE只复制到本地networking中的服务器 – >由于数据中心的结构,服务器不在同一个networking中
  • 在stackoverflow( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy )上提供的“使用代理复制tcpstream量”提供的替代scheme是不成功的。 如上所述,TEE不能与本地networking以外的远程服务器一起工作。 teeproxy不再可用( https://github.com/chrislusf/tee-proxy ),我们无法在其他地方find它。
  • 我们添加了第二个IP地址(在同一networking中),并将其分配给eth0:0(主IP地址分配给eth0)。 将这个新的IP或虚拟接口eth0:0与iptables TEE函数或路由相结合没有成功。
  • 为“在debian挤压下重复传入的TCPstream量 ”( 在Debian Squeeze上重复传入的TCPstream量 )提供的build议替代scheme不成功。 在客户端的每个请求/连接之后,cat | tc / 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。
  • 当然,谷歌search和search这个“问题”或设置也是不成功的。

我们在这里没有select。

使用IPTABLES时,是否有禁用TEEfunction的“本地networking中的服务器”强制执行的方法?

我们的目标是否可以通过IPTABLES或路线的不同使用来实现?

你知道一个不同的工具,这个目的已经过testing,适用于这些特定的情况吗?

是否有一个不同的来源,发球代理(这将完全符合我们的要求,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') 

使用这个脚本的注释:
该脚本将多个configuration的本地端口转发到另一个本地和远程套接字服务器。

组态:
添加到configuration文件port-forward.config行的内容如下:

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

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

是不可能的。 TCP是有状态的协议。 用户端计算机涉及到每一个连接的步骤,它不会回答两个独立的服务器,试图与之通信。 你所能做的就是在networking服务器或代理服务器上收集所有http请求并重播。 但是这并不能提供和确切的活动服务器的并发或stream量情况。

Teeproxy可以用来复制stream量。 用法很简单:

 ./teeproxy -l :80 -a localhost:9000 -b localhost:9001 
  • a生产服务器
  • btesting服务器

当你在你的web服务器之前放置一个HAproxy(带有roundrobin )时,你可以很容易地将50%的stream量redirect到testing站点:

  /------------------> production HAproxy / ^ \ / \---- teeproxy -.....> test (responses ignored) 

作为一个有状态的协议,TCP不能简单地在另一个主机上发送数据包的副本,正如@KazimierasAliulis指出的那样。

在TCPterminal层拾取数据包并将它们作为新的TCP数据stream进行传输是合理的。 你链接到的复制器工具看起来像你最好的select。 它作为TCP代理运行,允许TCP状态机正常运行。 您的testing机器的回应将被丢弃。 这听起来像它适合你想要什么的法案。

目前还不清楚为什么你把复印机工具注销是不可接受的。 您将不得不运行该工具的多个实例,因为它只监听单个端口,但是,大概您希望将这些不同的侦听端口中的每一个转发到后端系统上的不同端口。 如果没有,您可以使用iptables DNAT将所有侦听端口指向复制器工具的单个侦听副本。

除非您正在testing的应用程序非常简单,否则我认为您将遇到与时序和内部应用程序状态有关的testing方法问题。 你想做的事听起来似乎很简单 – 我希望你会发现很多边缘情况。

我试图做类似的事情,但是,如果你只是试图模拟服务器上的负载,我会看起来像一个负载testing框架。 我过去使用过locust.io,它在模拟服务器上的负载方面效果非常好。 这应该允许你模拟大量的客户端,让你玩的服务器的configuration,而不必经历痛苦的​​过程转发stream量到另一台服务器。

就“我们希望实时将活动服务器上的入站HTTPstream量复制到一个或多个远程服务器”中,有一种方法没有在上面提到,这是在它所连接的交换机上configuration一个镜像端口。

在Cisco Catalyst交换机的情况下,这被称为SPAN(更多信息在这里 )。 在思科环境中,您甚至可以在不同的交换机上使用镜像端口。

但这样做的目的是为了进行stream量分析,所以它将是单向的 – 上面第一段引用文本中的关键字: 入站 。 我不认为这个港口将允许任何回程的stream量,如果这样做,你将如何处理重复的回报stream量? 这可能会肆虐你的networking。

所以…只是想给你的清单添加一个可能性,但要注意的是,对于单向stream量来说确实是这样。 也许你可以在这个镜像端口上放置一个集线器,并且有一些本地客户端模拟器交付的服务器应答,可以接收启动的会话并响应,但是这样你就可以复制到你的复制服务器的传入stream量…可能不是你想。