Infrastruktura: serwery w centrum danych, OS - Debian Squeeze, Webserver - Apache 2.2.16
Sytuacja:
Serwer na żywo jest używany przez naszych klientów każdego dnia, co uniemożliwia testowanie poprawek i ulepszeń. Dlatego chcielibyśmy powielić przychodzący ruch HTTP na serwerze na żywo do jednego lub wielu serwerów zdalnych w czasie rzeczywistym. Ruch musi zostać przekazany do lokalnego serwera WWW (w tym przypadku Apache) ORAZ do zdalnego serwera (serwerów). W ten sposób możemy dostosować konfiguracje i użyć innego / zaktualizowanego kodu na zdalnym serwerze (serwerach) do testów porównawczych i porównania z bieżącym serwerem na żywo. Obecnie serwer nasłuchuje około. 60 dodatkowych portów oprócz 80 i 443, ze względu na strukturę klienta.
Pytanie: Jak można wdrożyć tę duplikację na jednym lub wielu zdalnych serwerach?
Próbowaliśmy już:
- powielacz agnoster - wymagałoby to jednej otwartej sesji na port, co nie ma zastosowania. ( https://github.com/agnoster/duplicator )
- kklis proxy - przesyła tylko ruch do zdalnego serwera, ale nie przekazuje go do serwera Lcoal. ( https://github.com/kklis/proxy )
- iptables - DNAT przekazuje tylko ruch, ale nie przekazuje go do lokalnego serwera WWW
- iptables - TEE duplikuje się tylko na serwerach w sieci lokalnej -> serwery nie znajdują się w tej samej sieci ze względu na strukturę centrum danych
- sugerowane alternatywy dla pytania „zduplikowany ruch TCP z proxy” na stackoverflow ( https://stackoverflow.com/questions/7247668/duplicate-tcp-traffic-with-a-proxy ) okazały się nieskuteczne. Jak wspomniano, TEE nie działa ze zdalnymi serwerami poza siecią lokalną. teeproxy nie jest już dostępny ( https://github.com/chrislusf/tee-proxy ) i nie mogliśmy go znaleźć gdzie indziej.
- Dodaliśmy drugi adres IP (który jest w tej samej sieci) i przypisaliśmy go do eth0: 0 (podstawowy adres IP jest przypisany do eth0). Bez powodzenia połączenie nowego IP lub interfejsu wirtualnego eth0: 0 z funkcją i trasami iptables TEE.
- sugerowane alternatywy dla pytania „zduplikowany przychodzący ruch TCP przy ściśnięciu Debiana” ( Zduplikowany przychodzący ruch TCP przy ściśnięciu Debiana ) nie powiodły się. Sesje cat | nc (cat / tmp / prodpipe | nc 127.0.0.1 12345 i cat / tmp / testpipe | nc 127.0.0.1 23456) są przerywane po każdym żądaniu / połączeniu przez klienta bez powiadomienia lub dziennika. Keepalive nie zmieniło tej sytuacji. Pakiety TCP nie zostały przetransportowane do systemu zdalnego.
- Dodatkowe próby z różnymi opcjami socat (HowTo: http://www.cyberciti.biz/faq/linux-unix-tcp-port-forwarding/ , https://stackoverflow.com/questions/9024227/duplicate-input- unix-stream-to-multiple-tcp-client-using-socat ) i podobne narzędzia zakończyły się niepowodzeniem, ponieważ podana funkcja TEE zapisze tylko FS.
- Oczywiście przeglądanie i wyszukiwanie tego „problemu” lub konfiguracji również nie powiodło się.
Brakuje nam tutaj opcji.
Czy istnieje metoda wyłączenia wymuszania „serwera w sieci lokalnej” funkcji TEE podczas korzystania z IPTABLES?
Czy nasz cel może zostać osiągnięty poprzez różne użycie IPTABLES lub tras?
Czy znasz inne narzędzie do tego celu, które zostało przetestowane i działa w tych konkretnych okolicznościach?
Czy istnieje inne źródło tee-proxy (które idealnie pasowałoby do naszych wymagań, AFAIK)?
Z góry dziękuję za twoje odpowiedzi.
----------
edycja: 05.02.2014
oto skrypt Pythona, który działałby tak, jak go potrzebujemy:
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')
Komentarze do użycia tego skryptu: Skrypt
ten przekazuje wiele skonfigurowanych portów lokalnych do innych lokalnych i zdalnych serwerów gniazd.
Konfiguracja:
Dodaj do pliku konfiguracyjnego linie port-forward.config z zawartością w następujący sposób:
Komunikaty o błędach są przechowywane w pliku „error.log”.
Skrypt dzieli parametry pliku konfiguracyjnego:
Podziel każdy wiersz konfiguracji spacjami
0: port lokalny, aby nasłuchiwać
1: port lokalny, aby przekazać do
2: zdalny adres IP serwera docelowego
3: zdalny port serwera docelowego
i ustawienia powrotu
Odpowiedzi:
To jest niemożliwe. TCP jest stanowym protokołem. Komputer końcowy użytkownika jest zaangażowany w każdy etap połączenia i nigdy nie będzie odpowiadać dwóm oddzielnym serwerom próbującym się z nim komunikować. Wszystko, co możesz zrobić, to zebrać wszystkie żądania HTTP na serwerze internetowym lub serwerze proxy i odtworzyć je. Ale to nie da dokładnych warunków współbieżności lub ruchu na żywo serwera.
źródło
Z tego, co opisujesz, GOR wydaje się pasować do twoich potrzeb. https://github.com/buger/gor/ "Odtwarzanie ruchu HTTP w czasie rzeczywistym. Odtwarzanie ruchu z produkcji do środowisk inscenizacyjnych i programistycznych." ?
źródło
Teeproxy można wykorzystać do replikacji ruchu. Użycie jest bardzo proste:
a
serwer produkcyjnyb
serwer testowyKiedy umieścisz HAproxy (z
roundrobin
) przed serwerem, możesz łatwo przekierować 50% swojego ruchu na stronę testową:źródło
TCP, będący protokołem stanowym, nie może po prostu wysadzić kopii pakietów na innym hoście, jak wskazuje @KazimierasAliulis.
Pobieranie pakietów na poziomie zakończenia TCP i przekazywanie ich jako nowego strumienia TCP jest rozsądne. Narzędzie powielacz jesteś związana wygląda najlepiej. Działa jako proxy TCP, pozwalając maszynie stanów TCP działać poprawnie. Odpowiedzi z twoich maszyn testowych zostaną po prostu odrzucone. Wygląda na to, że pasuje dokładnie do tego, czego dokładnie chcesz.
Nie jest dla mnie jasne, dlaczego spisałeś narzędzie do powielania jako niedopuszczalne. Będziesz musiał uruchomić wiele instancji narzędzia, ponieważ nasłuchuje tylko na jednym porcie, ale prawdopodobnie chcesz przekazać każdy z tych różnych portów nasłuchu do różnych portów w systemie zaplecza. Jeśli nie, możesz użyć iptables DNAT, aby skierować wszystkie porty nasłuchujące do pojedynczej nasłuchującej kopii narzędzia powielającego.
O ile testowane aplikacje nie są proste, spodziewam się, że będziesz mieć problemy z tą metodologią testowania związaną z czasem i wewnętrznym stanem aplikacji. To, co chcesz zrobić, brzmi zwodniczo prosto - spodziewam się, że znajdziesz wiele skrzynek.
źródło
Próbuję zrobić coś podobnego, jednak jeśli próbujesz po prostu symulować obciążenie serwera, spojrzałbym na coś w rodzaju struktury testowania obciążenia. W przeszłości korzystałem z locust.io i działało to bardzo dobrze do symulacji obciążenia serwera. Powinno to pozwolić na symulację dużej liczby klientów i umożliwić zabawę z konfiguracją serwera bez konieczności przechodzenia przez bolesny proces przekazywania ruchu na inny serwer.
źródło
O ile „chcielibyśmy zduplikować przychodzący ruch HTTP na serwerze na żywo do jednego lub wielu zdalnych serwerów w czasie rzeczywistym”, nie ma jednego sposobu, o którym nie wspomniano powyżej, czyli skonfigurowania portu lustrzanego na przełączniku, z którym jest on podłączony.
W przypadku przełączników Cisco Catalyst nazywa się to SPAN (więcej informacji tutaj ). W środowisku Cisco możesz nawet mieć port lustrzany na innym przełączniku.
Ale ma to na celu analizę ruchu, więc będzie jednokierunkowe - słowo kluczowe w cytowanym tekście w pierwszym akapicie powyżej: przychodzące . Nie sądzę, aby ten port zezwalał na ruch powrotny, a jeśli tak, to jak poradziłbyś sobie z powielonym ruchem powrotnym? Prawdopodobnie spowoduje to spustoszenie w twojej sieci.
Więc ... chciałem tylko dodać jedną opcję do listy, ale z zastrzeżeniem, że rzeczywiście będzie to ruch jednokierunkowy. Być może możesz umieścić hub na tym porcie lustrzanym i mieć zduplikowane odpowiedzi serwera przekazywane przez lokalny symulator klienta, który odbierze zainicjowane sesje i odpowie na nie, ale wtedy będziesz duplikował ruch przychodzący na twój duplikat serwera ... prawdopodobnie nie to, co ty chcieć.
źródło
Napisałem również odwrotny serwer proxy / moduł równoważenia obciążenia do podobnego celu w Node.js (jest to po prostu dla zabawy, a nie jest obecnie gotowe do produkcji).
https://github.com/losnir/ampel
Jest bardzo opiniotwórczy i obecnie obsługuje:
GET
Korzystanie z selekcji round-robin (1: 1)POST
Korzystanie z podziału żądań. Nie ma pojęcia „master” i „shadow” - pierwszy backend, który odpowiada to ten, który obsłuży żądanie klienta, a następnie wszystkie pozostałe odpowiedzi zostaną odrzucone.Jeśli ktoś uzna to za przydatne, mogę go ulepszyć, aby był bardziej elastyczny.
źródło
moja firma miała podobny wymóg, aby sklonować pakiet i wysłać go do innego hosta (prowadzimy symulatory danych rynkowych i potrzebowaliśmy tymczasowego rozwiązania, które nasłuchiwałoby kanału TCP danych rynkowych, przyjmował każdy pakiet, ale także wysyłał klon każdego pakietu do innego symulatora serwer)
ten plik binarny działa bardzo dobrze, jest to wersja TCP Duplicator, ale napisana w golang zamiast w jscript, więc jest szybsza i działa zgodnie z reklamą,
https://github.com/mkevac/goduplicator
źródło
istnieje narzędzie stworzone przez faceta z chińskiej firmy i być może jest to, czego potrzebujesz: https://github.com/session-replay-tools/tcpcopy
źródło