Wie übertrage ich einen TCP-Abhörsocket mit minimaler Ausfallzeit?

8

Während diese Frage mit EventMachine getaggt ist, werden auch generische BSD-Socket-Lösungen in jeder Sprache sehr geschätzt.

Irgendein Hintergrund:

Ich habe eine Anwendung, die auf einem TCP-Socket zuhört. Es wird mit einem regulären System V-Stil-Init-Skript gestartet und heruntergefahren.

Mein Problem ist, dass es etwas Zeit braucht, um zu starten, bevor es bereit ist, den TCP-Socket zu bedienen. Es ist nicht zu lang, vielleicht nur 5 Sekunden, aber das ist 5 Sekunden zu lang, wenn während eines Arbeitstages ein Neustart durchgeführt werden muss. Es ist auch wichtig, dass bestehende Verbindungen offen bleiben und normal beendet werden.

Gründe für einen Neustart der Anwendung sind Patches, Upgrades und Ähnliches. Ich bin leider in der Lage, dass ich ab und zu solche Dinge in der Produktion machen muss.

Die Frage:

Ich bin auf der Suche nach einer Möglichkeit, den TCP-Abhörsockel von einem Prozess zum anderen sauber zu übergeben und dadurch nur einen Bruchteil einer Sekunde Ausfallzeit zu bekommen. Ich möchte, dass bestehende Verbindungen / Sockets offen bleiben und die Verarbeitung im alten Prozess beenden, während der neue Prozess beginnt, neue Connectinos zu bedienen.

Gibt es eine bewährte Methode, dies mit BSD-Sockets zu tun? (Bonuspunkte für eine EventMachine-Lösung.)

Gibt es vielleicht Open-Source-Bibliotheken, die das implementieren, die ich verwenden kann, wie sie sind, oder als Referenz verwenden? (Auch hier werden Nicht-Ruby und Nicht-EventMachine-Lösungen geschätzt!)

    
Stéphan Kochen 05.02.2010, 11:52
quelle

2 Antworten

8

Es gibt mehrere Möglichkeiten, dies ohne Ausfallzeit zu tun, mit entsprechenden Änderungen am Serverprogramm.

Eine besteht darin, eine Neustartfähigkeit im Server selbst zu implementieren, zum Beispiel beim Empfang eines bestimmten Signals oder einer anderen Nachricht. Das Programm würde dann seine neue Version ausführen, wobei es die Datei-Deskriptor-Nummer des hörenden Sockets z. als ein Argument. Dieser Socket würde das FD_CLOEXEC -Flag so deaktivieren (den Standardwert), dass dies der Fall wäre vererbt werden. Da die anderen Sockets weiterhin vom ursprünglichen Prozess bedient werden und nicht an den neuen Prozess weitergegeben werden sollen, sollte das Flag z. mit fcntl() . Nach dem Verzweigen und Ausführen des neuen Prozesses kann der ursprüngliche Prozess den hörenden Socket ohne Unterbrechung des Dienstes schließen, da der neue Prozess nun diesen Socket überwacht.

Eine alternative Methode, wenn Sie nicht möchten, dass der alte Server den neuen Server selbst ausbuchen und ausführen muss, wäre ein Unix-Domain-Socket , um zwischen dem alten und dem neuen Server-Prozess zu kommunizieren. Ein neuer Serverprozess könnte an einem bekannten Speicherort im Dateisystem nach einem solchen Socket suchen, wenn er gestartet wird. Falls vorhanden, würde der neue Server eine Verbindung zu diesem Socket herstellen und anfordern, dass der alte Server seinen abhörenden Socket als Zusatzdaten über SCM_RIGHTS überträgt. Ein Beispiel dafür finden Sie am Ende von cmsg (3) .

    
mark4o 05.02.2010, 16:57
quelle
1

Jean-Paul Calderone schrieb eine ausführliche Präsentation im Jahr 2004 eine ganzheitliche Lösung für Ihr Problem mit Twisted, einschließlich Socket-Migration und andere Probleme.

    
Glyph 29.05.2010 14:03
quelle