gpt4 book ai didi

multithreading - 戈朗 : to goroutine or not to goroutine?

转载 作者:IT王子 更新时间:2023-10-29 01:36:23 30 4
gpt4 key购买 nike

很多时候在用 Go 开发 http 服务器时,我都会遇到这种困境。

假设我想尽快用http statuscode 200响应客户端(然后在后面执行工作),这就是我通常这样做的原因:

我让我的主要 http 处理程序接收请求,我将 http 200 写入响应,然后通过 channel 发送消息(如果我有 N 工作人员在那个 channel 上监听,我正在使用 Nbuffered channel:

func myHttpHandler(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(200)
log(req)
}

func log(req *http.Request) {
msg := createLog(req)
if msg != nil {
channel <- msg
}
}

我有我的听众(在初始化时被解雇)永远在那个 channel 上收听:

func init() {
for i := 0; i < workerCount; i++ {
go worker(i, maxEntrySize, maxBufferSize, maxBufferTime)
}
}

func worker(workerID int, maxEntrySize int, maxBufferSize int, maxBufferTime time.Duration) {
for {
entry := <-channel
...
...
...

现在,我的主要问题是:我应该在 go 例程中触发 log(req) 函数吗?即

func myHttpHandler(rw http.ResponseWriter, req *http.Request) {
rw.WriteHeader(200)
go func() { log(req) } ()
}

据我所知,在这种情况下,为每个 http 请求打开一个 goroutine 是没有意义的。

由于 log(req) 函数的当前操作主要是通过 channel 发送一些数据 - 该操作非常快。唯一不快的情况是 channel 阻塞。现在,如果 channel 阻塞,则意味着 worker 被阻塞了。并且由于工作人员永远在 channel 上监听消息 - 如果工作人员被阻塞,这意味着我的机器确实无法产生更快的输出(工作人员执行一些 I/O 正如你想象的那样,但这也非常快,因为 I/O 每分钟只发生一次)。

此外,因为我有 N 个工作人员,所以我用来从处理程序发送消息的 channel 是用 N 缓冲的,所以只有当所有 N worker 都被阻塞时它才会阻塞。

这是正确的吗?在 log(req) 调用中使用 goroutine 的优缺点是什么?这个处理程序每​​秒接收多达 10K 个请求,我猜为每个请求打开一个 goroutine 不是一个好主意。

最佳答案

There's no point in opening up a goroutine for every http request in this case.

当您使用 net/http 的服务器时,这已经发生了。您的处理程序在其自己的协程中被调用。

I am guessing it's not a good idea to open a goroutine for each request.

这也不是一个坏主意。 Go 的运行时可以轻松处理数十万个 goroutine。

但是,如果 log 阻塞,您的客户端可能会超时,因为客户端正在等待接收完整的 HTTP 响应,而只执行 rw.WriteHeader(200) 不会'构成一个呢。

要解决这个问题,您可以执行以下操作:

if cr, ok := rw.(io.Closer) {
cr.Close()
}

将响应的 Content-Length header 设置为 0 可能也是个好主意。

关于multithreading - 戈朗 : to goroutine or not to goroutine?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32522762/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com