英文:
Shall we run a goroutine for every async request, even when they are spawned from each other?
问题
我正在使用Go语言开发一个Web应用程序,我知道在http包中,每个请求都在一个单独的goroutine中运行。现在,如果这个goroutine中的代码查询数据库,然后等待并使用数据库结果调用远程API来获取一些相关数据,以此类推,我应该将这些调用中的每一个都放在单独的goroutine中运行,还是使用http提供的那个goroutine就足够了?
英文:
I'm developing a web application in go and I know in http package, every request is run in a separate goroutine. Now, if the code inside this goroutine queries a database then wait and using db result calls a remote api to fetch some related data and son on and so forth, shall I run each of these calls in separate goroutine or the one provided by http is enough?
答案1
得分: 4
这取决于你在做什么。
每个HTTP请求应该按顺序处理。也就是说,你不应该为处理请求本身而启动一个goroutine:
func myHandler(w http.ResponseWriter, r *http.Request) {
go func(w http.ResponseWriter, r *http.Request) {
// 这样做没有优势
}(w,r)
}
然而,在处理HTTP响应时,仍然有时候使用goroutines是有意义的。最常见的两种情况可能是:
- 你想要并行执行某些操作。
func myHandler(w http.ResponseWriter, r *http.Request) {
wg := &sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
/* 查询远程API */
}()
go func() {
defer wg.Done()
/* 查询数据库 */
}()
wg.Wait()
// 完成处理响应
}
- 你想要在响应HTTP请求后完成某些处理,这样网页客户端就不必等待。
func myHandler(w http.ResponseWriter, r *http.Request) {
// 处理请求
w.Write( ... )
go func() {
// 记录请求并发送电子邮件
}()
}
英文:
That depends on what you're doing.
Each HTTP request should be handled sequentially. That is to say, you shouldn't fire off a goroutine for handling the request itself:
func myHandler(w http.ResponseWriter, r *http.Request) {
go func(w http.ResponseWriter, r *http.Request) {
// There's no advantage to this
}(w,r)
}
However, there are still times when goroutines make sense when handling an HTTP response. The two most common situations are probably:
-
You want to do something in parallel.
func myHandler(w http.ResponseWriter, r *http.Request) { wg := &sync.WaitGroup{} wg.Add(2) go func() { defer wg.Done() /* query a remote API */ }() go func() { defer wg.Done() /* query a database */ }() wg.Wait() // finish handling the response }
-
You want to finish handling something after responding to the HTTP request, so that the web client doesn't have to wait.
func myHandler(w http.ResponseWriter, r *http.Request) { // handle request w.Write( ... ) go func() { // Log the request, and send an email }() }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论