【问题标题】:How do you keep goroutines running if another one crashes?如果另一个 goroutines 崩溃了,你如何保持 goroutines 运行?
【发布时间】:2021-03-04 12:56:57
【问题描述】:

我一直在努力寻找可以回答这个问题的东西,但我找不到任何关于它的东西。

假设我在 Go 中有一个类似这样的函数:

func main() {
    // assume this wrapped in a waitgroup or something 
    // so that it doesnt exit
    go queue.ConsumeAndDoSomething()
    go api.StartServer()
}

我这里有两个 goroutines 做完全不同的事情,理想情况下一个应该在另一个崩溃/恐慌时继续运行。如果队列操作失败,API 服务器应该会受到影响,反之亦然。

我不确定这是否可能(甚至推荐)。是否有一种干净的方法来执行此操作,或者一旦 goroutine 发生恐慌,整个程序是否应该退出?

【问题讨论】:

  • 我刚刚在其中一个 goroutine 中尝试了 panic 并且整个程序退出了
  • 使用 recover 从恐慌中恢复。
  • 虽然值得注意的是panic的目的是让应用程序崩溃;适合recover 的情况实际上相当少见(例如,net/http 的服务器将在处理程序发生恐慌时恢复,因此一个处理程序不会使整个服务器崩溃)并且通常表明panic 不应该一开始就在那里,它应该只是一个错误。

标签: go concurrency goroutine


【解决方案1】:

您必须使用内置的recover() 函数从恐慌中恢复,并且您必须在deferred 函数中调用它。

假设您有一个可能会出现恐慌的函数:

func doPanic() {
    log.Println("about to panic")
    panic("test")
}

创建一个辅助函数以将函数作为“受保护”的 goroutine 启动(避免恐慌):

func protect(f func()) {
    defer func() {
        if err := recover(); err != nil {
            log.Printf("Recovered: %v", err)
        }
    }()

    f()
}

并像这样使用它:

func main() {
    go protect(doPanic)

    for {
        time.Sleep(time.Second)
        fmt.Println("tick")
    }
}

此测试应用将输出:

2021/03/04 14:12:31 about to panic
2021/03/04 14:12:31 Recovered: test
tick
tick
tick
...

查看相关问题:Generic panic recovering in go programs

【讨论】:

  • 我认为退出整个程序可能更容易,因为 goroutine 不会重新启动。知道这里推荐的做法或约定是什么吗?
  • @ninesalt 理想情况下/通常情况下,goroutine 不应该恐慌。 goroutine 本身应该处理错误和重试操作。如果它内部出现可以恢复的问题,它应该重试。
【解决方案2】:

如果您不希望其他 goroutine 受到影响,每个 goroutine 都必须推迟 recover 调用以从潜在的恐慌中恢复。

代替

go queue.ConsumeAndDoSomething()

你应该使用

go func(){
    defer func() {
            if r := recover(); r != nil {
                log.Error("goroutine paniqued: ", r)
            }
        }()
    queue.ConsumeAndDoSomething()
}() 

【讨论】:

  • 我有点困惑。在我的示例中,这是最外层的 go func 调用应该是第一个 goroutine 吗?
  • 为更清晰而编辑
猜你喜欢
  • 2021-12-19
  • 1970-01-01
  • 2021-10-22
  • 1970-01-01
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
  • 2013-03-03
  • 2014-10-22
相关资源
最近更新 更多