Infrastruktur: Server im Rechenzentrum, Betriebssystem - Debian Squeeze, Webserver - Apache 2.2.16
Lage:
Der Live-Server wird täglich von unseren Kunden genutzt, sodass Anpassungen und Verbesserungen nicht getestet werden können. Daher möchten wir den eingehenden HTTP-Verkehr auf dem Live-Server in Echtzeit auf einen oder mehrere Remote-Server duplizieren. Der Datenverkehr muss an den lokalen Webserver (in diesem Fall Apache) UND an die Remote-Server weitergeleitet werden. Dadurch können wir Konfigurationen anpassen und anderen / aktualisierten Code auf den Remote-Servern für das Benchmarking und den Vergleich mit dem aktuellen Live-Server verwenden. Derzeit hört der Webserver ca. 60 zusätzliche Ports neben 80 und 443, aufgrund der Client-Struktur.
Frage: Wie kann diese Duplizierung auf einen oder mehrere Remote-Server implementiert werden?
Wir haben bereits versucht:
- agnoster duplicator - dies würde eine offene Sitzung pro Port erfordern, was nicht zutreffend ist. ( https://github.com/agnoster/duplicator )
- kklis proxy - leitet den Datenverkehr nur an den Remote-Server weiter, leitet ihn jedoch nicht an den lcoal-Webserver weiter. ( https://github.com/kklis/proxy )
- iptables - DNAT leitet den Datenverkehr nur weiter, nicht jedoch an den lokalen Webserver
- iptables - TEE dupliziert nur auf Servern im lokalen Netzwerk -> Die Server befinden sich aufgrund der Struktur des Datencenters nicht im selben Netzwerk
- Vorgeschlagene Alternativen für die Frage "TCP-Datenverkehr mit einem Proxy duplizieren" bei stackoverflow ( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy ) waren nicht erfolgreich. Wie bereits erwähnt, funktioniert TEE nicht mit Remoteservern außerhalb des lokalen Netzwerks. teeproxy ist nicht mehr verfügbar ( https://github.com/chrislusf/tee-proxy ) und wir konnten es nirgendwo anders finden.
- Wir haben eine zweite IP-Adresse hinzugefügt (die sich im selben Netzwerk befindet) und sie eth0: 0 zugewiesen (die primäre IP-Adresse wird eth0 zugewiesen). Kein Erfolg bei der Kombination dieser neuen IP- oder virtuellen Schnittstelle eth0: 0 mit der iptables-TEE-Funktion oder -Routen.
- vorgeschlagenen Alternativen für die Frage „duplicate eingehender TCP - Datenverkehr auf debian squeeze“ (vorausgesetzt Doppelte eingehenden TCP - Datenverkehr auf Debian Squeeze ) waren erfolglos. Die cat | nc-Sitzungen (cat / tmp / prodpipe | nc 127.0.0.1 12345 und cat / tmp / testpipe | nc 127.0.0.1 23456) werden nach jeder Anforderung / Verbindung durch einen Client ohne Benachrichtigung oder Protokoll unterbrochen. Keepalive hat diese Situation nicht geändert. TCP-Pakete wurden nicht zum fernen System transportiert.
- Zusätzliche Versuche mit mit verschiedenen Optionen von socat (HowTo: 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 ) und ähnliche Tools waren nicht erfolgreich, da die bereitgestellte TEE-Funktion nur in FS schreibt.
- Natürlich war es auch nicht erfolgreich, zu googeln und nach diesem "Problem" oder Setup zu suchen.
Hier gehen uns die Optionen aus.
Gibt es eine Methode zum Deaktivieren der Durchsetzung von "Server im lokalen Netzwerk" der TEE-Funktion bei Verwendung von IPTABLES?
Kann unser Ziel durch unterschiedliche Nutzung von IPTABLES oder Routes erreicht werden?
Kennen Sie ein anderes Werkzeug für diesen Zweck, das getestet wurde und für diese speziellen Umstände geeignet ist?
Gibt es eine andere Quelle für Tee-Proxy (die perfekt zu unseren Anforderungen passen würde, AFAIK)?
Vielen Dank im Voraus für Ihre Antworten.
----------
bearbeiten: 05.02.2014
Hier ist das Python-Skript, das so funktioniert, wie wir es brauchen:
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')
Die Kommentare zur Verwendung dieses Skripts:
Dieses Skript leitet eine Reihe von konfigurierten lokalen Ports an einen anderen lokalen und einen Remote-Socket-Server weiter.
Konfiguration:
Fügen Sie der Konfigurationsdatei port-forward.config die folgenden Zeilen mit Inhalten hinzu:
Fehlermeldungen werden in der Datei 'error.log' gespeichert.
Das Skript teilt die Parameter der Konfigurationsdatei auf:
Teilen Sie jede Konfigurationszeile mit Leerzeichen auf.
0: Lokaler Port zum Abhören
1: Lokaler Port zum Weiterleiten an
2: Remote-IP-Adresse des Zielservers
3: Remote-Port des Zielservers
und Rückgabe der Einstellungen
Antworten:
Es ist unmöglich. TCP ist ein Statefull-Protokoll. Der Endcomputer des Benutzers ist an jedem Verbindungsschritt beteiligt und antwortet niemals auf zwei separate Server, die versuchen, mit ihm zu kommunizieren. Alles, was Sie tun können, ist, alle http-Anfragen auf dem Webserver oder einem Proxy zu sammeln und sie erneut abzuspielen. Aber das gibt nicht und genaue Nebenläufigkeit oder Verkehrsbedingungen eines Live-Servers.
quelle
Nach allem, was Sie beschreiben, scheint GOR Ihren Bedürfnissen zu entsprechen. https://github.com/buger/gor/ "Wiedergabe des HTTP-Datenverkehrs in Echtzeit. Wiedergabe des Datenverkehrs von der Produktion über Staging- und Entwicklungsumgebungen." ?
quelle
Teeproxy kann zum Replizieren des Datenverkehrs verwendet werden. Die Bedienung ist denkbar einfach:
a
Produktionsserverb
Test ServerWenn Sie einen HAproxy (mit
roundrobin
) vor Ihren Webserver stellen, können Sie 50% Ihrer Zugriffe einfach auf die Testseite umleiten:quelle
TCP ist ein statusbehaftetes Protokoll, das nicht dazu geeignet ist, Kopien der Pakete auf einem anderen Host zu senden, wie @KazimierasAliulis hervorhebt.
Es ist vernünftig, die Pakete auf der Ebene der TCP-Terminierung aufzunehmen und als neuen TCP-Stream weiterzuleiten. Das Duplikator-Tool , mit dem Sie verlinkt haben, scheint Ihre beste Wahl zu sein. Es fungiert als TCP-Proxy, sodass die TCP-Zustandsmaschine ordnungsgemäß funktioniert. Die Antworten Ihrer Testmaschinen werden einfach verworfen. Das klingt so, als würde es genau zu dem passen, was Sie wollen.
Mir ist nicht klar, warum Sie das Duplizierwerkzeug als inakzeptabel abgeschrieben haben. Sie müssen mehrere Instanzen des Tools ausführen, da es nur einen einzelnen Port überwacht. Vermutlich möchten Sie jedoch jeden dieser verschiedenen Überwachungsports an verschiedene Ports des Back-End-Systems weiterleiten. Wenn nicht, können Sie iptables DNAT verwenden, um alle Listening-Ports auf eine einzelne Listening-Kopie des Duplikator-Tools zu lenken.
Ich gehe davon aus, dass Sie Probleme mit dieser Testmethode in Bezug auf das Timing und den internen Anwendungsstatus haben werden, es sei denn, die Anwendungen, die Sie testen, sind einfach. Was Sie tun möchten, klingt täuschend einfach. Ich gehe davon aus, dass Sie viele Randfälle finden werden.
quelle
Ich versuche jedoch, etwas Ähnliches zu tun. Wenn Sie lediglich versuchen, die Auslastung eines Servers zu simulieren, würde ich mir so etwas wie ein Framework zum Testen der Auslastung ansehen. Ich habe locust.io in der Vergangenheit verwendet und es hat sehr gut funktioniert, um eine Auslastung auf einem Server zu simulieren. Auf diese Weise können Sie eine große Anzahl von Clients simulieren und mit der Konfiguration des Servers spielen, ohne den schmerzhaften Prozess der Weiterleitung von Datenverkehr an einen anderen Server durchlaufen zu müssen.
quelle
Was "Wir möchten, dass der eingehende HTTP-Verkehr auf dem Live-Server in Echtzeit auf einen oder mehrere Remote-Server dupliziert wird", ist die oben nicht erwähnte Möglichkeit, einen Spiegelport auf dem Switch zu konfigurieren, mit dem er verbunden ist.
Bei Cisco Catalyst-Switches wird dies als SPAN bezeichnet (weitere Informationen hier ). In einer Cisco-Umgebung können Sie den gespiegelten Port sogar auf einem anderen Switch haben.
Der Zweck dieser Funktion ist jedoch die Analyse des Datenverkehrs, sodass sie unidirektional ist - Schlüsselwort im zitierten Text im ersten Absatz: eingehend . Ich glaube nicht, dass dieser Port Rückverkehr zulässt, und wenn ja, wie würden Sie mit doppeltem Rückverkehr umgehen? Das wird wahrscheinlich nur Verwüstung in Ihrem Netzwerk anrichten.
Also ... wollte nur eine Möglichkeit zu Ihrer Liste hinzufügen, aber mit dem Vorbehalt, dass es sich tatsächlich um eine Einbahnstraße handelt. Möglicherweise können Sie einen Hub an diesen Spiegelport anschließen und doppelte Serverantworten von einem lokalen Client-Simulator erhalten, der initiierte Sitzungen aufnimmt und antwortet. Dann duplizieren Sie eingehenden Datenverkehr auf Ihren doppelten Server wollen.
quelle
Ich habe auch einen Reverse-Proxy / Load-Balancer für einen ähnlichen Zweck mit Node.js geschrieben (nur zum Spaß, zur Zeit nicht produktionsbereit).
https://github.com/losnir/ampel
Es ist sehr aufgeschlossen und unterstützt derzeit:
GET
Verwenden der Round-Robin-Auswahl (1: 1)POST
Verwenden der Anforderungsaufteilung Es gibt kein Konzept für "master" und "shadow" - das erste Backend, das antwortet, ist dasjenige, das die Client-Anfrage bearbeitet, und alle anderen Antworten werden verworfen.Wenn jemand es nützlich findet, kann ich es verbessern, um flexibler zu sein.
quelle
Mein Unternehmen hatte eine ähnliche Anforderung, ein Paket zu klonen und an einen anderen Host zu senden (wir haben Marktdatensimulatoren ausgeführt und benötigten eine temporäre Lösung, die einen Marktdaten-TCP-Feed abhört, jedes Paket aufnimmt, aber auch einen Klon jedes Pakets an einen anderen Simulator sendet Server)
Diese Binärdatei läuft sehr gut. Sie ist eine Version von TCP Duplicator, wurde jedoch in Golang anstelle von jscript geschrieben, ist also viel schneller und funktioniert wie angekündigt.
https://github.com/mkevac/goduplicator
quelle
Es gibt ein Tool, das von einem Mann aus einem chinesischen Unternehmen erstellt wurde, und vielleicht ist es das, was Sie brauchen: https://github.com/session-replay-tools/tcpcopy
quelle