为什么 golang http 服务器在响应超过 8kb 时失败并显示 "broken pipe"?
why is golang http server failing with "broken pipe" when response exceeds 8kb?
我在下面有一个示例 Web 服务器,如果您立即调用 curl localhost:3000 -v
然后 ^C
(取消)(在 1 秒之前),它将报告 write tcp 127.0.0.1:3000->127.0.0.1:XXXXX: write: broken pipe
.
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
log.Fatal(http.ListenAndServe(":3000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(1 * time.Second)
// Why 8061 bytes? Because the response header on my computer
// is 132 bytes, adding up the entire response to 8193 (1 byte
// over 8kb)
if _, err := w.Write(make([]byte, 8061)); err != nil {
fmt.Println(err)
return
}
})))
}
根据我的调试,我已经能够得出结论,只有当整个响应写入超过 8192 字节(或 8kb)时才会发生这种情况。如果我整个响应写的少于8192,则不会返回broken pipe
错误。
我的问题是这个 8192 字节(或 8kb)的缓冲区限制设置在哪里?这是 Golang 的 HTTP 写缓冲区中的限制吗?这与响应被分块有关吗?这只与curl
客户端有关,还是与浏览器客户端有关?我如何更改此限制以便在连接关闭之前写入更大的缓冲区(用于调试目的)?
谢谢!
在net/http/server.go
中,输出缓冲区设置为4<<10
,即4KB。
您在 8KB 处看到错误的原因是,至少需要写入 2 次套接字才能检测到已关闭的远程连接。第一次写入成功,但远程主机发送 RST 数据包。第二次写入将写入一个已关闭的套接字,这就是 returns 和 broken pipe
错误。
根据套接字写入缓冲区和连接延迟,在注册第一个 RST 数据包之前,可能会有更多写入成功。
我在下面有一个示例 Web 服务器,如果您立即调用 curl localhost:3000 -v
然后 ^C
(取消)(在 1 秒之前),它将报告 write tcp 127.0.0.1:3000->127.0.0.1:XXXXX: write: broken pipe
.
package main
import (
"fmt"
"net/http"
"time"
)
func main() {
log.Fatal(http.ListenAndServe(":3000", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(1 * time.Second)
// Why 8061 bytes? Because the response header on my computer
// is 132 bytes, adding up the entire response to 8193 (1 byte
// over 8kb)
if _, err := w.Write(make([]byte, 8061)); err != nil {
fmt.Println(err)
return
}
})))
}
根据我的调试,我已经能够得出结论,只有当整个响应写入超过 8192 字节(或 8kb)时才会发生这种情况。如果我整个响应写的少于8192,则不会返回broken pipe
错误。
我的问题是这个 8192 字节(或 8kb)的缓冲区限制设置在哪里?这是 Golang 的 HTTP 写缓冲区中的限制吗?这与响应被分块有关吗?这只与curl
客户端有关,还是与浏览器客户端有关?我如何更改此限制以便在连接关闭之前写入更大的缓冲区(用于调试目的)?
谢谢!
在net/http/server.go
中,输出缓冲区设置为4<<10
,即4KB。
您在 8KB 处看到错误的原因是,至少需要写入 2 次套接字才能检测到已关闭的远程连接。第一次写入成功,但远程主机发送 RST 数据包。第二次写入将写入一个已关闭的套接字,这就是 returns 和 broken pipe
错误。
根据套接字写入缓冲区和连接延迟,在注册第一个 RST 数据包之前,可能会有更多写入成功。