Heim  >  Artikel  >  Backend-Entwicklung  >  Der Golang-Prozess verschwindet von selbst

Der Golang-Prozess verschwindet von selbst

PHPz
PHPzOriginal
2023-05-10 10:14:06799Durchsuche

Kürzlich bin ich in einem in Golang geschriebenen Programm auf ein sehr seltsames Problem gestoßen, das heißt, der Prozess ist von selbst verschwunden. Nach einiger Fehlerbehebung habe ich das Problem gefunden und einige Erfahrungen zusammengefasst. Lassen Sie mich unten die Probleme und Lösungen mitteilen, auf die ich gestoßen bin.

Problembeschreibung

In den letzten Tagen habe ich festgestellt, dass die Aufgabe immer nach ein paar Minuten gestoppt wurde Der Prozess wird in eine Datei ausgegeben, und wenn ich dann das Protokoll überprüfe, stelle ich fest, dass der Prozess nur ein paar Minuten lief und dann verschwand. Diese Situation ist sehr seltsam, da ich bei normaler Entwicklung und Tests noch nie auf ähnliche Probleme gestoßen bin.

Fehlerbehebungsprozess

Zuerst dachte ich an die einfachste Lösung: Debug-Informationen zum Code hinzufügen. Wenn ich also den Prozess gestartet habe, habe ich ein start-Protokoll ausgegeben, und jedes Mal, wenn ich einige wichtige Vorgänge ausgeführt habe, habe ich ein entsprechendes Protokoll ausgegeben. Dann habe ich die Aufgabe neu gestartet, darauf gewartet, dass sie gestoppt wurde, und dann das Protokoll überprüft und festgestellt, dass der Prozess nur wenige Minuten nach dem Start gestoppt wurde, aber keine Fehlermeldung im Protokoll ausgegeben wurde. Es schien, als ob er beendet wurde selbst. start 的 log,然后每执行一些重要的操作,再输出一条相应的 log。然后,我重新启动了任务,等待它停止,然后查看 log,发现进程刚启动了几分钟就停止了,但是它在 log 中没有输出任何错误信息,似乎它就是自己终止了。

接着,我尝试使用 strace 命令来跟踪进程的系统调用,看看它终止的原因。但是,这个进程的结构比较复杂,有多个 goroutine 在运行。我使用了 strace 命令来跟踪其中的一个 goroutine(ndeliver),看看它的系统调用情况。以下是 ndeliver goroutine 的相关代码:

c := make(chan os.Signal, 1)

signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)

go func() {
    sig := <-c
    log.Errorf("main: received signal %s, shutting down server", sig.String())
    server.Stop()
    os.Exit(0)
}()

go func() {
    err := server.Start()
    if err != nil {
        log.Fatalf("ndeliver: server start error: %s", err)
    }
}()

这段代码的作用是为进程注册信号处理函数,并启动一个 goroutine 来执行 server.Start() 函数,该函数会一直阻塞直到进程退出。

通过 strace 命令,我发现这个 goroutine 没有任何异常,它也没有遇到什么错误就退出了。但是,我发现进程中还有其他的 goroutine,我继续使用 strace

Als nächstes habe ich versucht, mit dem Befehl strace die Systemaufrufe des Prozesses zu verfolgen, um herauszufinden, warum er beendet wurde. Die Struktur dieses Prozesses ist jedoch relativ komplex, da mehrere Goroutinen ausgeführt werden. Ich habe den Befehl strace verwendet, um eine der Goroutinen (ndeliver) zu verfolgen und deren Systemaufrufe anzuzeigen. Das Folgende ist der relevante Code der Goroutine ndeliver:

defer func() {
    if r := recover(); r != nil {
        log.Errorf("goroutine panic: %v", r)
        // TODO: 处理 panic
    }
}()

// 代码片段

Die Funktion dieses Codes besteht darin, eine Signalverarbeitungsfunktion für den Prozess zu registrieren und eine Goroutine zu starten, um auszuführen server.Start( )-Funktion, die blockiert, bis der Prozess beendet wird.

Durch den Befehl strace habe ich festgestellt, dass diese Goroutine keine Ausnahmen hatte und ohne Fehler beendet wurde. Ich stellte jedoch fest, dass es andere Goroutinen im Prozess gab. Ich benutzte weiterhin den Befehl strace, um eine der Goroutinen zu verfolgen. Dann löste eine Goroutine eine Panik aus Die Verarbeitung wurde nicht gelöst, sodass der gesamte Prozess abstürzt.

Lösung

Beim Betrachten des Codes stellte ich fest, dass diese Panik durch das Löschen einer Datei verursacht wurde, aber unser Code konnte diesen Fehler nicht behandeln. Wenn eine Goroutine-Panik nicht behandelt wird, stürzt der gesamte Prozess ab, weshalb der Prozess von selbst verschwindet.

Um dieses Problem zu lösen, müssen wir mit der Panik umgehen, um zu verhindern, dass sie den gesamten Prozess zum Absturz bringt. Wir können die Wiederherstellungsfunktion bei Bedarf verwenden, um Panik zu erfassen und sie dann zu behandeln, um einen Prozessabsturz zu vermeiden.

Das Folgende ist ein Codebeispiel für den Umgang mit Panik:

rrreee

Durch die Verwendung der Verzögerungsfunktion können wir die Beendigung der Goroutine, auch wenn sie in Panik gerät, erfassen und entsprechend fortfahren Verarbeitung, hier geben wir einfach die Panikinformationen aus, aber tatsächlich können wir hier auch andere Verarbeitungen durchführen, z. B. das Senden einer Warnung oder das Protokollieren weiterer Informationen zum Fehler. #🎜🎜##🎜🎜#Zusammenfassung#🎜🎜##🎜🎜#Wenn beim Schreiben von Golang-Code aufgrund der besonderen Natur von Goroutine eine Goroutine in Panik gerät, kann dies zum Absturz des gesamten Prozesses führen. Daher müssen wir beim Schreiben von Code diese Situation berücksichtigen und Code schreiben, um mit dieser Situation umzugehen. Es ist sehr wichtig, dem Code eine Panikbehandlung hinzuzufügen. Dies kann uns helfen, ähnliche Probleme in der Produktionsumgebung zu vermeiden. #🎜🎜#

Das obige ist der detaillierte Inhalt vonDer Golang-Prozess verschwindet von selbst. 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
Vorheriger Artikel:Golang-Karte zum SchneidenNächster Artikel:Golang-Karte zum Schneiden