Назад | Перейти на главную страницу

Как дублировать TCP-трафик на один или несколько удаленных серверов для целей тестирования?

Инфраструктура: серверы в Datacenter, ОС - Debian Squeeze, веб-сервер - Apache 2.2.16


Ситуация:

Живой сервер используется нашими клиентами каждый день, что делает невозможным тестирование настроек и улучшений. Поэтому мы хотели бы дублировать входящий HTTP-трафик на реальном сервере на один или несколько удаленных серверов в реальном времени. Трафик должен передаваться на локальный веб-сервер (в данном случае Apache) И на удаленные серверы. Таким образом, мы можем настроить конфигурации и использовать другой / обновленный код на удаленном сервере (ах) для тестирования производительности и сравнения с текущим живым сервером. В настоящее время веб-сервер прослушивает прибл. 60 дополнительных портов помимо 80 и 443 из-за клиентской структуры.


Вопрос: Как можно реализовать дублирование на один или несколько удаленных серверов?

Мы уже пробовали:

Здесь у нас заканчиваются варианты.

Есть ли способ отключить принудительное использование «сервер в локальной сети» функции TEE при использовании IPTABLES?

Может ли наша цель быть достигнута с помощью различного использования 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: удаленный порт целевого сервера
и вернуть настройки

Судя по тому, что вы описываете, GOR соответствует вашим потребностям. https://github.com/buger/gor/ «Воспроизведение HTTP-трафика в реальном времени. Воспроизведение трафика от производственной среды до промежуточной среды и среды разработки». ?

Это невозможно. TCP - это протокол с сохранением состояния. Пользовательский конечный компьютер участвует на каждом этапе подключения, и он никогда не будет отвечать двум отдельным серверам, пытающимся с ним связаться. Все, что вы можете сделать, это собрать все HTTP-запросы на веб-сервере или прокси-сервере и воспроизвести их. Но это не даст точных данных о состоянии параллелизма или трафика на реальном сервере.

Teeproxy может использоваться для репликации трафика. Использование действительно простое:

./teeproxy -l :80 -a localhost:9000 -b localhost:9001
  • a производственный сервер
  • b тестовый сервер

Когда вы ставите HAproxy (с roundrobin) перед вашим веб-сервером вы можете легко перенаправить 50% вашего трафика на тестовый сайт:

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

Как отмечает @KazimierasAliulis, TCP, будучи протоколом с отслеживанием состояния, не поддается простой передаче копий пакетов на другой хост.

Разумно собирать пакеты на уровне завершения TCP и ретранслировать их как новый поток TCP. В инструмент для дублирования ссылка, на которую вы ссылаетесь, выглядит как лучший выбор. Он работает как TCP-прокси, позволяя конечному автомату TCP работать правильно. Ответы с ваших тестовых машин будут отброшены. Похоже, это точно соответствует тому, что вы хотите.

Мне непонятно, почему вы списали дубликатор как неприемлемый. Вам нужно будет запустить несколько экземпляров инструмента, поскольку он прослушивает только один порт, но, предположительно, вы хотите ретранслировать каждый из этих разных портов прослушивания на разные порты внутренней системы. Если нет, вы можете использовать iptables DNAT, чтобы направить все слушающие порты на одну слушающую копию инструмента дублирования.

Если тестируемые вами приложения не очень просты, я ожидаю, что у вас возникнут проблемы с этой методологией тестирования, связанные со временем и внутренним состоянием приложения. То, что вы хотите сделать, кажется обманчиво простым - я ожидаю, что вы найдете много крайних случаев.

Я пытаюсь сделать что-то подобное, однако, если вы просто пытаетесь имитировать нагрузку на сервер, я бы посмотрел на что-то вроде структуры нагрузочного тестирования. Раньше я использовал locust.io, и он очень хорошо работал для имитации нагрузки на сервер. Это должно позволить вам имитировать большое количество клиентов и позволить вам поиграть с конфигурацией сервера без необходимости проходить болезненный процесс перенаправления трафика на другой сервер.

Что касается «мы хотели бы дублировать входящий HTTP-трафик с реального сервера на один или несколько удаленных серверов в реальном времени», есть один способ, не упомянутый выше, а именно настройка зеркального порта на коммутаторе, к которому он подключен.

В случае коммутаторов Cisco Catalyst это называется SPAN (подробнее Вот). В среде Cisco вы можете даже иметь зеркальный порт на другом коммутаторе.

Но цель этого - анализ трафика, поэтому он будет однонаправленным - ключевое слово в цитируемом тексте в первом абзаце выше: входящий. Я не думаю, что этот порт разрешит какой-либо обратный трафик, и если бы это было так, как бы вы справились с дублированием обратного трафика? Это, вероятно, только нанесет ущерб вашей сети.

Итак ... просто хотел добавить одну возможность в ваш список, но с оговоркой, что она действительно будет для одностороннего движения. Возможно, вы можете поместить концентратор на этот зеркальный порт и получить дублирующиеся ответы сервера, передаваемые каким-либо локальным симулятором клиента, который будет принимать инициированные сеансы и отвечать, но тогда вы будете дублировать входящий трафик на свой дублированный сервер ... вероятно, не то, что вы хотеть.

Я также написал обратный прокси / балансировщик нагрузки для той же цели с Node.js (это просто для удовольствия, в настоящий момент не готово к производству).

https://github.com/losnir/ampel

Он очень самоуверенный и в настоящее время поддерживает:

  • GET Использование кругового отбора (1: 1)
  • POST Использование разделения запроса. Понятия «мастер» и «тень» отсутствуют - первый ответивший бэкэнд - это тот, который будет обслуживать запрос клиента, а затем все остальные ответы будут отброшены.

Если кто-то сочтет это полезным, я могу улучшить его, сделав более гибким.

у моей компании было аналогичное требование, чтобы клонировать пакет и отправить на другой хост (мы запускаем симуляторы рыночных данных и нуждаемся во временном решении, которое будет прослушивать поток TCP с рыночными данными, принимать каждый пакет, но также отправлять клон каждого пакета в другой симулятор сервер)

этот двоичный файл работает очень хорошо, это версия TCP Duplicator, но написанная на golang вместо jscript, поэтому он работает быстрее и работает как рекламируется,

https://github.com/mkevac/goduplicator

есть инструмент, созданный парнем из китайской компании, и возможно это то, что вам нужно: https://github.com/session-replay-tools/tcpcopy