Heim  >  Artikel  >  Backend-Entwicklung  >  So stoppen Sie das Abhören eines Servers in Go

So stoppen Sie das Abhören eines Servers in Go

王林
王林nach vorne
2024-02-09 12:09:22680Durchsuche

如何在 Go 中停止监听服务器

In der Go-Sprache ist eine häufige Frage, wie man das Abhören des Servers ordnungsgemäß beenden kann. Wenn wir den Server stoppen müssen, möchten wir in der Lage sein, alle Verbindungen ordnungsgemäß zu schließen, ohne die verarbeiteten Anforderungen zu beeinträchtigen. In diesem Artikel werden verschiedene gängige Methoden vorgestellt, die Ihnen bei der Lösung dieses Problems helfen. Erstens können wir ein Semaphor verwenden, um das Herunterfahren des Servers zu steuern. Das Betriebssystempaket in der Go-Sprache bietet eine Signalmethode, mit der vom Betriebssystem gesendete Signale erfasst werden können. Wir können das Herunterfahren des Servers auslösen, indem wir auf das os.Interrupt-Signal, also Strg+C, hören. In der Signalverarbeitungsfunktion können wir einige Bereinigungsarbeiten durchführen, z. B. das Schließen der Datenbankverbindung, das Speichern von Daten usw. Rufen Sie dann die Shutdown-Methode des Servers auf, die auf die Verarbeitung vorhandener Anforderungen wartet, bevor der Server heruntergefahren wird. Auf diese Weise können wir den lauschenden Server ordnungsgemäß stoppen. Es ist zu beachten, dass wir die WithTimeout-Methode im Kontextpaket verwenden können, um ein Timeout festzulegen, wenn der Server innerhalb eines bestimmten Zeitraums nicht heruntergefahren werden kann. Nach Überschreiten dieser Zeit wird der Server zum Herunterfahren gezwungen. Mit diesem Ansatz können wir sicherstellen, dass der Server unter allen Umständen ordnungsgemäß heruntergefahren wird. Zusätzlich zur Verwendung von Semaphoren können wir auch eine Variable vom Typ Bool verwenden, um das Herunterfahren des Servers zu steuern. Wenn der Server startet, können wir eine globale Bool-Variable definieren, z. B. isShutdown. Dann können wir in der Funktion, die die Anfrage verarbeitet, den Wert dieser Variablen überprüfen und, wenn er wahr ist, sofort zurückkehren und die Verarbeitung der aktuellen Anfrage stoppen. Beim Herunterfahren des Servers setzen wir isShutdown auf true und warten dann, bis alle Anfragen verarbeitet wurden, bevor wir das Programm beenden. Diese Methode ist relativ einfach, erfordert jedoch das Hinzufügen zusätzlicher logischer Beurteilungen zur Funktion, die die Anforderung verarbeitet, was sich geringfügig auf die Leistung auswirken kann. Zusammenfassend lässt sich sagen, dass wir unabhängig davon, ob wir ein Semaphor oder eine Bool-Variable verwenden, die Funktion zum ordnungsgemäßen Stoppen des lauschenden Servers in der Go-Sprache implementieren können. Welche Methode Sie wählen, hängt von Ihren spezifischen Anforderungen und der Komplexität Ihres Projekts ab.

Frageninhalt

Ich habe versucht, einen Weg zu finden, einen Überwachungsserver in Go ordnungsgemäß zu stoppen. Da listen.accept blockiert, muss der Listening-Socket geschlossen werden, um das Ende zu signalisieren. Ich kann diesen Fehler jedoch nicht von anderen Fehlern unterscheiden, da die zugehörigen Fehler nicht exportiert werden.

Kann ich es besser machen? Bitte beachten Sie fixme中以下代码中的serve()

package main

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

// echo server struct
type echoserver struct {
    listen net.listener
    done   chan bool
}

// 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()
        // fixme i'd like to detect "use of closed network connection" here
        // fixme but it isn't exported from net
        if err != nil {
            log.printf("accept failed: %v", err)
            break
        }
        go es.respond(conn.(*net.tcpconn))
    }
    es.done <- true
}

// stop the server by closing the listening listen
func (es *echoserver) stop() {
    es.listen.close()
    <-es.done
}

// 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 := &echoserver{
        listen: listen,
        done:   make(chan bool),
    }
    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()
}

Dies wird gedruckt

2012/11/16 12:53:35 Starting echo server
2012/11/16 12:53:36 Stopping echo server
2012/11/16 12:53:36 Accept failed: accept tcp 127.0.0.1:18081: use of closed network connection

Ich möchte die Meldung accept failed ausblenden, aber natürlich möchte ich andere Fehler, die accept melden kann, nicht maskieren. Ich könnte mir natürlich den Fehlertest für Verwendung einer geschlossenen Netzwerkverbindung ansehen, aber das wäre wirklich hässlich. Ich könnte ein Flag setzen, um anzuzeigen, dass ich gleich schließen werde, und den Fehler ignorieren, wenn er gesetzt ist, denke ich – gibt es einen besseren Weg? accept failed 消息,但显然我不想掩盖 accept 可以报告的其他错误。我当然可以查看 use of closed network connection 的错误测试,但这真的很难看。我可以设置一个标志,表示我即将关闭并忽略错误(如果已设置),我想 - 有更好的方法吗?

解决方法

accept() 调用之后检查循环中的一些“是时候停止”标志,然后从 mainProblemumgehung Überprüfen Sie, ob in der Schleife nach dem accept()-Aufruf ein „Time to Stop“-Flag vorhanden ist, schalten Sie es dann von main um und verbinden

Sie mit Ihrem Der Überwachungsport, um den Server-Socket zu erhalten, „ohne hängen zu bleiben“. Dies ist dem alten 🎜„Self-Piping-Trick“🎜 sehr ähnlich. 🎜

Das obige ist der detaillierte Inhalt vonSo stoppen Sie das Abhören eines Servers in Go. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen