Если вы выберете отсрочку восстановления всего, я предлагаю потратить некоторое время, чтобы убедиться, что собрано четкое сообщение об ошибке с достаточным количеством информации, чтобы быстро на него реагировать.
Написание паникисообщение для stderr / stdout не очень хорошее, так как будет очень трудно найти причину проблемы.По моему опыту, лучший подход - потратить немного времени на то, чтобы ваши программы Go обрабатывали ошибки разумным образом.Например, errors.Wrap
из " github.com / pkg / errors " позволяет обернуть все ошибки и получить трассировку стека.
Восстановление паники часто является неизбежным злом.Как вы говорите, не идеальный сбой всей программы только потому, что один запрос вызвал панику.В большинстве случаев восстановление паники не приведет к обратному эффекту, но программа может оказаться в неопределенном состоянии, которое невозможно восстановить, которое может исправить только перезапуск вручную.При этом я предлагаю в этом случае убедиться, что ваша программа Go предоставляет способ создания дампа ядра.
Вот как записать дамп ядра в stderr, когда SIGQUIT отправляется в программу Go (например,. kill pid -QUIT
)
go func() {
// Based on answers to this stackoverflow question:
// https://stackoverflow.com/questions/19094099/how-to-dump-goroutine-stacktraces
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGQUIT)
for {
<-sigs
fmt.Fprintln(os.Stderr, "=== received SIGQUIT ===")
fmt.Fprintln(os.Stderr, "*** goroutine dump...")
var buf []byte
var bufsize int
var stacklen int
// Create a stack buffer of 1MB and grow it to at most 100MB if
// necessary
for bufsize = 1e6; bufsize < 100e6; bufsize *= 2 {
buf = make([]byte, bufsize)
stacklen = runtime.Stack(buf, true)
if stacklen < bufsize {
break
}
}
fmt.Fprintln(os.Stderr, string(buf[:stacklen]))
fmt.Fprintln(os.Stderr, "*** end of dump")
}
}()