Heim >Backend-Entwicklung >Golang >Wie kann ich einen Go-HTTP-Server nach der Rückgabe einer Antwort ordnungsgemäß herunterfahren?

Wie kann ich einen Go-HTTP-Server nach der Rückgabe einer Antwort ordnungsgemäß herunterfahren?

DDD
DDDOriginal
2024-10-28 19:12:29225Durchsuche

How to Gracefully Shut Down a Go HTTP Server After Returning a Response?

HTTP-Server nach Rückgabe der Antwort herunterfahren

In diesem Szenario haben Sie einen Go-Befehlszeilen-Bot erstellt, der mit der Instagram-API interagiert. Um das Zugriffstoken zu erhalten, starten Sie einen lokalen HTTP-Server, um den Umleitungs-URI zu erfassen. Beim Versuch, den Server nach dem Abrufen des Zugriffstokens manuell herunterzufahren, tritt jedoch ein Problem auf.

Problem:

Beim Herunterfahren treten die Fehler „Server geschlossen“ und „Ungültige Speicheradresse“ auf Server

Analyse:

Die aufgetretenen Fehler deuten darauf hin, dass der HTTP-Server vorzeitig heruntergefahren wird, bevor alle Verbindungen ordnungsgemäß geschlossen werden. Dies kann aufgrund asynchronen Verhaltens im HTTP-Handler und beim Herunterfahren des Servers auftreten.

Lösung 1: Verwenden von Context.WithCancel:

Erwägen Sie die Verwendung von context.WithCancel, um einen Kontext zu erstellen, der abgebrochen werden kann wenn das Zugriffstoken abgerufen wird. Übergeben Sie diesen Kontext an den HTTP-Handler und verwenden Sie CancelFunc, um den Server ordnungsgemäß herunterzufahren, wenn der Kontext geschlossen wird.

<code class="go">package main

import (
    "context"
    "io"
    "log"
    "net/http"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Bye\n")
        cancel()
    })
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Hi\n")
    })

    srv := &http.Server{Addr: ":8080"}
    go func() {
        err := srv.ListenAndServe()
        if err != http.ErrServerClosed {
            log.Println(err)
        }
    }()

    <-ctx.Done()

    err := srv.Shutdown(context.Background())
    if err != nil {
        log.Println(err)
    }

    log.Println("done.")
}</code>

Lösung 2: Den gleichen Kontext für alle Funktionen verwenden:

Sie können auch verwenden Derselbe Kontext über mehrere HTTP-Handler und die Hauptfunktion hinweg, um sicherzustellen, dass alle Funktionen benachrichtigt werden, wenn der Server heruntergefahren werden soll.

<code class="go">package main

import (
    "context"
    "io"
    "log"
    "net/http"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Hi\n")
    })
    http.HandleFunc("/quit", func(w http.ResponseWriter, r *http.Request) {
        io.WriteString(w, "Bye\n")
        cancel()
    })
    srv := &http.Server{Addr: ":8080"}
    go func() {
        if err := srv.ListenAndServe(); err != nil {
            log.Printf("Httpserver: ListenAndServe() error: %s", err)
        }
    }()
    <-ctx.Done()

    if err := srv.Shutdown(ctx); err != nil && err != context.Canceled {
        log.Println(err)
    }
    log.Println("done.")
}</code>

Schlussfolgerung:

Durch die Verwendung von context.WithCancel oder die Übergabe von Wenn Sie über mehrere Funktionen hinweg denselben Kontext verwenden, können Sie sicherstellen, dass der HTTP-Server ordnungsgemäß heruntergefahren wird, nachdem alle Verbindungen geschlossen wurden. Dadurch werden die Fehler vermieden, auf die Sie derzeit stoßen.

Das obige ist der detaillierte Inhalt vonWie kann ich einen Go-HTTP-Server nach der Rückgabe einer Antwort 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