Go如何处理HTTP keep-alive?

4
我理解,如果客户端和服务器都支持持久连接,可以通过第一个请求中的Connection:keep-alive标头来使用它。之后,当客户端和服务器完成第一个请求/响应后,他们仍将保持底层TCP连接打开,并在随后的请求/响应中使用相同的连接。
我不清楚的是编程模型。考虑以下go代码中的客户端:
resp, _ := client.Get("http://www.stackoverflow.com")
// do some other things
resp, _ = client.Get("http://www.stackoverflow.com/questions")

据我所知,keep-alive是HTTP/1.1的默认策略。
Q1:这两个请求是否使用同一个TCP连接?
在服务器端:
当一个请求到来时,Go HTTP框架会将其分派给处理程序,然后由于keep-alive,框架应该为同一TCP连接准备下一个请求。但是,在处理程序中我没有看到任何阻塞读取代码。所以,
Q2:Go HTTP框架是否使用某种非阻塞模式来处理keep-alive?
我的意思是,处理程序不会阻塞读取,而只是在完成请求后返回,然后框架将轮询每个非阻塞TCP连接,如果其中一个有数据到达,则将其分派给关联的处理程序,依此类推。仅当请求具有Connection: Close头时,框架才会在处理程序返回时关闭TCP连接。
1个回答

3

问题1:这两个请求是否使用同一个TCP连接?

是的,如果连接没有被服务器关闭,http.Transport可以在默认配置下重新使用该连接。

问题2:Go Http框架是否使用某种非阻塞模式来处理keep-alive?

Go HTTP Server默认处理keep-alive连接。不存在HTTP的“非阻塞模式”。它按照HTTP规范描述的方式,在单个连接上按顺序处理请求和响应。


逻辑上,当 go http 框架处理完一个请求后,它应该从 tcp 中读取以等待下一个请求。我认为 read 会阻塞直到数据到来,但我没有感觉到框架被阻塞。那么,这是如何实现的呢? - dastan
@H.W.Du:如果你想知道它是如何实现的,请阅读源代码。处理请求的实际循环目前在func (c *conn) serve()中,位于http/server.go - JimB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接