Golang默认禁用Nagle算法
Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。 Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。
该算法在Golang 里默认被禁用,是被一个国外的博主发现。他是在家里使用git-lfs 时发现使用 Wi-Fi 速度太慢(50KB/s),换有线就快很多(2.5 MB/s)
参考 https://withinboredom.info/blog/2022/12/29/golang-is-evil-on-shitty-networks/
可以通过通过 SetNoDelay
方法禁用 TCP_NODELAY
,客户端的代码如下所示:
func main() {
target := "localhost:8000"
raddr, err := net.ResolveTCPAddr("tcp", target)
if err != nil {
log.Fatal(err)
}
// Establish a connection with the server.
conn, err := net.DialTCP("tcp", nil, raddr)
if err != nil {
log.Fatal(err)
}
conn.SetNoDelay(false) // Disable TCP_NODELAY; Nagle's Algorithm takes action.
fmt.Println("Sending Gophers down the pipe...")
for i := 1; i <= 5; i++ {
// Send the word "GOPHER" to the open connection.
_, err = conn.Write([]byte("GOPHER\n"))
if err != nil {
log.Fatal(err)
}
}
}
TCP_NODELAY
不是万能药,在决定禁用或保持启用之前需要进行实验。然而,了解它是否在我们最喜欢的编程语言中默认启用总是很好的。如果启用了Nagle的算法(SetNoDelay(false)),服务可能会表现得更好。TCP_NODELAY选项可用于发送端和接收端。没有限制。在我们的示例中,我们在客户端进行了实验。这一切都取决于我们在客户端和服务器上的工作负载和访问权限。
Nagle算法是时代的产物,因为当时网络带宽有限。而当前的局域网、广域网的带宽则宽裕得多,所以目前的TCP/IP协议栈默认将Nagle算法关闭。
0
See Also
Nearby
- 上一篇 › conc: 更优雅的使用并发
- 下一篇 › pdfcpu: GO 语言实现写的 PDF 处理器