Como duplicar o tráfego TCP para um ou vários servidores remotos para fins de benchmarking?

27

Infraestrutura: Servidores em Datacenter, OS - Debian Squeeze, Webserver - Apache 2.2.16

Situação:

O servidor live está sendo usado pelos nossos clientes todos os dias, o que torna impossível testar ajustes e melhorias. Portanto, gostaríamos de duplicar o tráfego HTTP de entrada no servidor ativo para um ou vários servidores remotos em tempo real. O tráfego deve ser passado para o servidor Web local (neste caso, o Apache) E para o (s) servidor (es) remoto (s). Dessa forma, podemos ajustar configurações e usar código diferente / atualizado no (s) servidor (es) remoto (s) para comparação e comparação com o servidor ao vivo atual. Atualmente, o servidor está ouvindo aprox. 60 portas adicionais além de 80 e 443, por causa da estrutura do cliente.

Pergunta: Como essa duplicação para um ou vários servidores remotos pode ser implementada?

Já tentamos:

  • duplicador de agnoster - isso exigiria uma sessão aberta por porta que não é aplicável. ( link )
  • proxy kklis - só encaminha o tráfego para o servidor remoto, mas não o transmite para o servidor web lcoal. ( link )
  • iptables - O DNAT somente encaminha o tráfego, mas não o encaminha para o servidor da Web local
  • iptables - TEE apenas duplica para servidores na rede local - > os servidores não estão localizados na mesma rede devido à estrutura do datacenter
  • alternativas sugeridas fornecidas para a pergunta "tráfego tcp duplicado com um proxy" em stackoverflow ( link ) não tiveram sucesso. Como mencionado, o TEE não funciona com servidores remotos fora da rede local. O teeproxy não está mais disponível ( link ) e não conseguimos encontrá-lo em outro lugar.
  • Adicionamos um segundo endereço IP (que está na mesma rede) e atribuímo-lo a eth0: 0 (o endereço IP principal é atribuído a eth0). Não há sucesso em combinar este novo IP ou interface virtual eth0: 0 com a função TEE do iptables ou rotas.
  • alternativas sugeridas fornecidas para a questão "tráfego tcp de entrada duplicado no squeeze debian" ( Duplicar o tráfego TCP de entrada no Debian Squeeze não teve sucesso. As sessões cat | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 e cat / tmp / testpipe | nc 127.0.0.1 23456) são interrompidas após cada solicitação / conexão por um cliente sem qualquer aviso ou log. O keepalive não mudou essa situação. Pacotes TCP não foram transportados para o sistema remoto.
  • Tentativas adicionais com diferentes opções de socat (HowTo: link , < um href="https://stackoverflow.com/questions/9024227/duplicate-input-unix-stream-to-multiple-tcp-clients-using-socat"> link ) e ferramentas semelhantes foram mal sucedidas, porque a função TEE fornecida só grava em FS.
  • É claro que pesquisar e pesquisar esse "problema" ou a configuração também não foi bem-sucedida.

Estamos ficando sem opções aqui.

Existe um método para desabilitar a aplicação de "servidor na rede local" da função TEE ao usar IPTABLES?

O nosso objetivo pode ser alcançado pelo uso diferente de IPTABLES ou Rotas?

Você conhece uma ferramenta diferente para esse propósito que foi testada e funciona para essas circunstâncias específicas?

Existe uma fonte diferente para o tee-proxy (que se encaixaria perfeitamente em nossos requisitos, AFAIK)?

Agradecemos antecipadamente por suas respostas.

----------

editar: 05.02.2014

aqui está o script python, que funciona da maneira que precisamos:

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')

Os comentários para usar este script:
Este script encaminha um número de portas locais configuradas para outro servidor de soquete local e remoto.

Configuração:
Adicione as linhas port-forward.config do arquivo de configuração com o seguinte conteúdo:

Mensagens de erro são armazenadas no arquivo 'error.log'.

O script divide os parâmetros do arquivo de configuração:
Dividir cada linha de configuração com espaços
0: porta local para ouvir
1: porto local para encaminhar para o
2: endereço IP remoto do servidor de destino
3: porta remota do servidor de destino
e retornar configurações

    
por Sise 29.01.2014 / 16:02

9 respostas

10

É impossível. TCP é o protocolo statefull. O computador final do usuário está envolvido em cada etapa da conexão e nunca responderá a dois servidores separados que tentam se comunicar com ele. Tudo o que você pode fazer é coletar todas as solicitações HTTP no servidor da Web ou em algum proxy e reproduzi-las. Mas isso não dará condições exatas de concorrência ou tráfego de um servidor ativo.

    
por 29.01.2014 / 16:19
20

Pelo que você descreve, o GOR parece se adequar às suas necessidades. link "Repetição do tráfego HTTP em tempo real. Repetir o tráfego da produção para os ambientes de preparação e desenvolvimento." ?

    
por 03.09.2014 / 15:43
7

Teeproxy pode ser usado para replicar o tráfego. O uso é muito simples:

./teeproxy -l :80 -a localhost:9000 -b localhost:9001
  • a servidor de produção
  • b servidor de teste

Quando você coloca um HAproxy (com roundrobin ) antes do seu servidor web, você pode redirecionar facilmente 50% do seu tráfego para o site de teste:

         /------------------> production
HAproxy /                 ^
        \                /
         \---- teeproxy -.....> test (responses ignored)
    
por 16.02.2015 / 09:44
4

O TCP, sendo um protocolo com estado, não é passível de simplesmente explodir cópias dos pacotes em outro host, como aponta @KazimierasAliulis.

Pegar os pacotes na camada de terminação TCP e retransmiti-los como um novo fluxo TCP é razoável. A ferramenta duplicadora à qual você se vinculou parece sua melhor aposta. Ele opera como um proxy TCP, permitindo que a máquina de estado TCP funcione corretamente. As respostas de suas máquinas de teste serão descartadas. Parece que isso se encaixa no que você quer exatamente.

Não está claro para mim por que você descartou a ferramenta duplicadora como inaceitável. Você terá que executar várias instâncias da ferramenta, pois ela só escuta em uma única porta, mas, presumivelmente, você deseja retransmitir cada uma dessas diferentes portas de escuta para portas diferentes no sistema de backend. Se não, você pode usar o iptables DNAT para direcionar todas as portas de escuta para uma única cópia de escuta da ferramenta duplicadora.

A menos que os aplicativos que você está testando sejam simples, espero que você tenha problemas com essa metodologia de testes relacionados ao tempo e ao estado interno do aplicativo. O que você quer fazer soa enganadoramente simples - eu espero que você encontre muitos casos de limites.

    
por 29.01.2014 / 18:52
1

Estou tentando fazer algo semelhante, no entanto, se você estiver simplesmente tentando simular a carga em um servidor, eu veria algo como uma estrutura de teste de carga. Eu usei locust.io no passado e funcionou muito bem para simular uma carga em um servidor. Isso deve permitir que você simule um grande número de clientes e permita que você jogue com a configuração do servidor sem ter que passar pelo doloroso processo de encaminhar o tráfego para outro servidor.

    
por 30.07.2015 / 23:37
0

minha empresa tinha requisitos semelhantes, para clonar um pacote e enviar para outro host (rodamos simuladores de dados de mercado e precisávamos de uma solução temporária que escutasse um feed TCP de dados de mercado, ingerisse cada pacote mas também enviasse um clone de cada pacote para outro servidor simulador)

esse binário roda muito bem, é uma versão do Duplicador TCP, mas escrito em golang ao invés de jscript, então é mais rápido e funciona como anunciado,

link

    
por 25.01.2019 / 21:09
0

No que diz respeito a "gostaríamos de duplicar o tráfego HTTP de entrada no servidor ativo para um ou vários servidores remotos em tempo real", há uma maneira não mencionada acima, que é configurar uma porta de espelhamento no switch ao qual está conectada.

No caso dos switches Cisco Catalyst, isso é chamado de SPAN (mais informações aqui ). Em um ambiente Cisco, você pode até ter a porta espelhada em um switch diferente.

Mas o objetivo disso é para análise de tráfego, por isso, será unidirecional - palavra-chave no texto citado no primeiro parágrafo acima: entrada . Eu não acho que a porta irá permitir qualquer tráfego de retorno, e se o fizesse, como você lidaria com o tráfego de retorno duplicado? Isso provavelmente causará estragos na sua rede.

Então ... só queria adicionar uma possibilidade à sua lista, mas com a ressalva de que será de fato para o tráfego de mão única. Talvez você possa colocar um hub nessa porta de espelhamento e ter respostas de servidor duplicadas fornecidas por algum simulador de cliente local que atenda às sessões iniciadas e responda, mas você estará duplicando o tráfego de entrada para o servidor duplicado ... provavelmente não o que você quer.

    
por 29.01.2014 / 17:45
0

Eu também escrevi um proxy reverso / balanceador de carga para um propósito similar com o Node.js (é apenas por diversão, não produção pronta no momento).

link

É muito opinativo e atualmente suporta:

  • GET Usando a seleção round-robin (1: 1)
  • POST Usando a divisão de solicitação. Não há conceito de "mestre" e "sombra" - o primeiro back-end que responde é aquele que atenderá à solicitação do cliente e, em seguida, todas as outras respostas serão descartadas.

Se alguém achar útil, posso melhorar para ser mais flexível.

    
por 23.07.2018 / 12:06
-1

existe uma ferramenta criada por um cara de uma empresa chinesa, e talvez seja o que você precisa: link

    
por 16.10.2018 / 11:12