我正在尝试以这种方式异步处理 Go 中的 HTTP 请求:
- 我将处理函数传递给 HTTP 服务器
- 在处理程序中,我将 HttpRequest/HttpResponse 对象存储在 slice 或映射中
- 当从处理函数返回时——响应不会返回给客户端,但连接保持打开状态
- 当从另一个来源接收到“一些”异步输入时,我从内存中获取相关的 HttpRequest/HttpResponse 对象,写入响应并关闭连接。
我的目标与 Java 中的 Jetty-Continuation 非常相似。
如何在 Go 语言中实现这样的行为?
最佳答案
在 Go 中不需要这种行为。
Java HTTP 服务器使用线程,如果 servlet 等待某事,它会有效地阻塞当前线程。线程繁重,线程池有限。
在 Go 中,HTTP 服务器实现使用 goroutines,如果它们在等待,它们不会阻塞操作系统线程。 Goroutines 是轻量级的,并由 Go 运行时有效地调度。我所说的有效调度是指在 goroutine 进行系统调用或在 channel 上等待时进行切换。
简单地说,不要尝试从 Java servlet 复制变通方法,因为 Go 中不需要变通方法。
让我们考虑一个 Java servlet,servlet 共享操作系统线程
class Slow extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
Thread.sleep(1000);
// stops the thread for a second
// operating system puts a thread aside and reuses processor
// it is out of Java control
// when all pooled HTTP server threads are sleeping no request is served
}
}
和 Go HTTP 处理程序,每个处理程序都在单独的 goroutine 中运行
func fast(w http.ResponseWriter, r *http.Request) {
time.Sleep(10000 * time.Second)
// Go scheduler puts the goroutine aside
// and reuses OS thread for handling another request
// when one second passes the goroutine is scheduled again
// and finishes serving request
}
在 Go 中,默认情况下你会得到你想要的。
关于http - 异步 http 请求处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49254774/