Heim >Backend-Entwicklung >Golang >Wie kann ich einen Go-Listening-Server ordnungsgemäß herunterfahren?

Wie kann ich einen Go-Listening-Server ordnungsgemäß herunterfahren?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-24 03:15:12625Durchsuche

How to Gracefully Shut Down a Go Listening Server?

So stoppen Sie einen Listening-Server in Go ordnungsgemäß

In Go blockiert die listen.Accept-Funktion die Ausführung, was das Beenden eines Servers schwierig macht Server ordnungsgemäß abhören. Um zu bestimmen, wann der Server beendet werden muss, besteht ein Ansatz darin, den Listening-Socket zu schließen und den spezifischen Fehler zu erkennen, der auf eine geschlossene Netzwerkverbindung hinweist. Allerdings wird dieser Fehler nicht vom Net-Paket exportiert, sodass Entwickler auf eine umständliche Fehlerbehandlung zurückgreifen müssen.

Glücklicherweise gibt es eine elegantere Lösung. Durch die Verwendung eines fertigen Kanals können Sie dem Server signalisieren, dass er anhalten soll, bevor die Verbindung geschlossen wird. So kann es mit Beispielcode implementiert werden:

package main

import (
    "io"
    "log"
    "net"
    "sync"
    "time"
)

// Echo server struct
type EchoServer struct {
    listen net.Listener
    done   sync.WaitGroup
}

// Respond to incoming connection
//
// Write the address connected to then echo
func (es *EchoServer) respond(remote *net.TCPConn) {
    defer remote.Close()
    _, err := io.Copy(remote, remote)
    if err != nil {
        log.Printf("Error: %s", err)
    }
}

// Listen for incoming connections
func (es *EchoServer) serve() {
    for {
        conn, err := es.listen.Accept()
        if err != nil {
            select {
            case <-es.done:
                // Server has been stopped, so we can exit without showing the error.
            default:
                log.Printf("Accept failed: %v", err)
            }
            return
        }
        es.done.Add(1) // Increment the waitgroup for each incoming connection
        go func() {
            es.respond(conn.(*net.TCPConn))
            es.done.Done() // Decrement the waitgroup when done handling the connection
        }()
    }
}

// Stop the server by closing the listening listen
func (es *EchoServer) stop() {
    es.done.Wait() // Wait for all outstanding connections to finish handling
    es.listen.Close() // Now it the Accept will have an error above
}

// Make a new echo server
func NewEchoServer(address string) *EchoServer {
    listen, err := net.Listen("tcp", address)
    if err != nil {
        log.Fatalf("Failed to open listening socket: %s", err)
    }
    es := &amp;EchoServer{
        listen: listen,
    }
    es.done.Add(1)
    go es.serve()
    return es
}

// Main
func main() {
    log.Println("Starting echo server")
    es := NewEchoServer("127.0.0.1:18081")
    // Run the server for 1 second
    time.Sleep(1 * time.Second)
    // Close the server
    log.Println("Stopping echo server")
    es.stop()
}

In diesem Code beendet die Serve-Funktion den Server ordnungsgemäß, indem sie zurückkehrt, wenn auf dem Fertig-Kanal ein Wert empfangen wird. Die Hauptfunktion zeigt, wie Sie den Server starten, auf Verbindungen warten und ihn dann ordnungsgemäß beenden. Durch die Verwendung eines fertigen Kanals wird die Fehlerbehandlung sauber von der Abschaltlogik getrennt, was zu einem besser wartbaren und fehlerfreien Server führt.

Das obige ist der detaillierte Inhalt vonWie kann ich einen Go-Listening-Server ordnungsgemäß herunterfahren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn