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

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

基础设施:数据中心的服务器,操作系统 - Debian Squeeze,Web 服务器 - Apache 2.2.16


情况:

我们的客户每天都在使用实时服务器,因此无法测试调整和改进。因此,我们希望将实时服务器上的入站 HTTP 流量实时复制到一个或多个远程服务器。流量必须传递到本地 Web 服务器(在本例中为 Apache)和远程服务器。这样,我们可以调整配置并在远程服务器上使用不同的/更新的代码来进行基准测试并与当前实时服务器进行比较。由于客户端结构的原因,目前 Web 服务器除了 80 和 443 之外还监听大约 60 个其他端口。


问题:如何实现到一台或多台远程服务器的复制?

我们已经尝试过:

我们现在没有选择了。

有没有办法在使用 IPTABLES 时禁用 TEE 功能的“本地网络中的服务器”的强制执行?

通过不同使用IPTABLES或者Routes能达到我们的目标吗?

您是否知道有其他可用于此目的且经过测试并适用于这些特定情况的工具?

是否有其他 tee-proxy 来源(据我所知,它完全符合我们的要求)?


提前感谢您的回复。

----------

编辑:2014 年 5 月 2 日

下面是 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:目标服务器的远程端口
和返回设置

答案1

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

答案2

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

答案3

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

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

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

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

答案4

我正在尝试做类似的事情,但是,如果您只是想模拟服务器上的负载,我会考虑使用负载测试框架之类的东西。我以前使用过 locust.io,它在模拟服务器上的负载方面效果非常好。这应该允许您模拟大量客户端,并让您使用服务器的配置,而不必经历将流量转发到另一台服务器的痛苦过程。

相关内容