youbbs
youbbs
1534 0 0

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


Discussion

Login Topics