Ich verwende die Mux-Bibliothek von Gorilla Web Toolkit zusammen mit dem mitgelieferten Go http-Server.
Das Problem ist, dass in meiner Anwendung der HTTP-Server nur eine Komponente ist und nach meinem Ermessen gestoppt und gestartet werden muss.
Wenn ich http.ListenAndServe(fmt.Sprintf(":%d", service.Port()), service.router)
es blockiere, kann ich den Server anscheinend nicht stoppen.
Ich bin mir bewusst, dass dies in der Vergangenheit ein Problem war. Ist das immer noch der Fall? Gibt es neue Lösungen?
nil
,srv.Shutdown
bekomme ichpanic: runtime error: invalid memory address or nil pointer dereference
. Übergebencontext.Todo()
funktioniert stattdessen.Wie in
yo.ian.g
der Antwort erwähnt. Go 1.8 hat diese Funktionalität in die Standardbibliothek aufgenommen.Minimales Beispiel für
Go 1.8+
:Ursprüngliche Antwort - Pre Go 1.8:
Aufbauend auf Uvelichitels Antwort.
Sie können eine eigene Version erstellen,
ListenAndServe
die ein zurückgibtio.Closer
und nicht blockiert.Vollständiger Code hier verfügbar .
Der HTTP-Server wird mit dem Fehler geschlossen
accept tcp [::]:8080: use of closed network connection
quelle
Go 1.8 wird anmutig und kraftvoll shutdown, erhältlich über umfassen
Server::Shutdown(context.Context)
undServer::Close()
jeweils.Das entsprechende Commit finden Sie hier
quelle
go func() { X() }()
Anschließend wirdY()
dem Leser die falsche Annahme gemacht, dassX()
er zuvor ausgeführt wirdY()
. Wartegruppen usw. stellen sicher, dass Timing-Fehler wie diese Sie nicht beißen, wenn Sie es am wenigsten erwarten!Sie können konstruieren
net.Listener
was du kannst
Close()
und
http.Serve()
daraufquelle
http.ListenAndServe
aus bestimmten Gründen. So benutze ich die GWT MUX Bibliothek, ich bin mir nicht sicher, wie ich net.listen dafür verwenden soll.Da in keiner der vorherigen Antworten angegeben ist, warum Sie dies nicht tun können, wenn Sie http.ListenAndServe () verwenden, habe ich den http-Quellcode v1.8 verwendet.
Wie Sie sehen können, gibt die Funktion http.ListenAndServe die Servervariable nicht zurück. Dies bedeutet, dass Sie nicht zum 'Server' gelangen können, um den Befehl Herunterfahren zu verwenden. Daher müssen Sie Ihre eigene 'Server'-Instanz erstellen, anstatt diese Funktion zu verwenden, damit das ordnungsgemäße Herunterfahren implementiert werden kann.
quelle
Sie können den Server schließen, indem Sie seinen Kontext schließen.
Und wann immer Sie bereit sind, es zu schließen, rufen Sie an:
quelle
ctx
toserver.Shutdown
ist falsch. Der Kontext ist bereits abgebrochen, sodass er nicht sauber heruntergefahren werden kann. Möglicherweise haben Sieserver.Close
ein unreines Herunterfahren gefordert . (Für ein sauberes Herunterfahren müsste dieser Code umfassend überarbeitet werden.Es ist möglich , dies mit einem lösen
context.Context
mit einnet.ListenConfig
. In meinem Fall wollte ich nicht verwendensync.WaitGroup
oderhttp.Server
‚sShutdown()
Ruf, sondern stützen sich auf einecontext.Context
(die mit einem Signal geschlossen wurde).quelle
Was ich für solche Fälle getan habe, in denen die Anwendung nur der Server ist und keine andere Funktion ausführt, ist die Installation
http.HandleFunc
eines Musters wie/shutdown
. Etwas wieEs erfordert nicht 1.8. Aber wenn 1.8 verfügbar ist, kann diese Lösung hier eingebettet werden, anstatt den
os.Exit(0)
Aufruf, falls gewünscht, glaube ich.Der Code zur Durchführung all dieser Aufräumarbeiten bleibt dem Leser als Übung überlassen.
Zusätzliches Guthaben, wenn Sie sagen können, wo dieser Bereinigungscode am vernünftigsten platziert werden könnte, da ich dies hier nicht empfehlen würde und wie dieser Endpunktschlag den Aufruf dieses Codes verursachen sollte.
Mehr zusätzliche Gutschrift, wenn Sie sagen können, wo dieser
os.exit(0)
Anruf (oder welcher Prozess-Exit, den Sie verwenden möchten), der hier nur zur Veranschaulichung angegeben wird, am vernünftigsten platziert wäre.Noch mehr zusätzliche Anerkennung, wenn Sie erklären können, warum dieser Mechanismus der HTTP-Server-Prozesssignalisierung vor allen anderen Mechanismen in Betracht gezogen werden sollte, die in diesem Fall für praktikabel gehalten werden.
quelle