【问题标题】:Unstable proxy server as a result of rising CLOSE_WAIT and TIME_WAIT sockets由于 CLOSE_WAIT 和 TIME_WAIT 套接字上升导致代理服务器不稳定
【发布时间】:2019-10-30 18:49:44
【问题描述】:

我有用 golang 编写的 socks5 代理服务器。守护进程正在侦听从 15000 到 25000 的 10000 个端口,因此这是一个代理列表。最近我们开始用一些客户端对其进行测试,最终在 5000 个这些端口上实现了大约 500 rps。这不是我想的那么多,但我马上指出一堆问题。

服务器是 Ubuntu 18,8 核,32G RAM,1Gb 网络。我一直观察到几乎 800% 的 CPU,并且 CLOSE_WAIT 和 TIME_WAIT 套接字状态的数量不断增加。我仔细研究了大约一周的代码,但没有指出任何问题,所有连接都在关闭。

pprof 是说这都是关于系统调用,更准确地说是套接字读取。这里的 ReadAtLeast 是读取 socks5 请求的前 3 个字节以确定请求类型。

func (s *Server) Serve(conn net.Conn) error {
    defer conn.Close() // seems doesn't work too

    _ = conn.SetDeadline(time.Now().Add(time.Second * 30)) // doesn't work

    request, err := NewRequest(conn)
    if err != nil {
        return err
    }

    // Process the client request
    return s.handleRequest(request, conn)
}

func NewRequest(bufConn io.Reader) (*Request, error) {
    header := []byte{0, 0, 0}
    if _, err := io.ReadAtLeast(bufConn, header, 3); err != nil {
        return nil, fmt.Errorf("Failed to get command version: %v", err)
    }

    // ...
}

net.ipv4.tcp_fin_timeout=25 所以 2MSL 是 50 秒,但似乎套接字没有足够的时间关闭,因为新的套接字进入速度很快。这大约是 TIME_WAIT。 CLOSE_WAIT 有什么问题我不知道。我确实关闭了连接,但似乎没有从客户端获得 FIN_ACK。

作为临时解决方案,我每 15 分钟向 crontab 发送一次重启命令,因此所有 CLOSE_WAIT 连接都被丢弃,TIME_WAIT 减少了一点,但这是停机时间等。

【问题讨论】:

  • CLOSE_WAIT 表示您没有在应该关闭套接字时关闭套接字,即当您读取 EOS 时。 TIME_WAIT 是正常的,但您可以通过关闭直到从对等方获得 EOS 来减少它们。

标签: go tcp proxy


【解决方案1】:

你可以试试:

conn, ok = conn.(*net.TCPConn)
if ok {
     conn.SetLinger(0)
}

使用此选项,内核将更快地关闭 TIME_WAIT 和 CLOSE_WAIT(终止状态)套接字。

注释:

  • TIME_WAIT:您的服务器启动了 tcp 终止,TIME_WAIT 是您服务器上该 tcp 连接的最后状态
  • CLOSE_WAIT:客户端发起 tcp 终止,您的服务器正在等待来自客户端的 FIN ACK

【讨论】:

  • 使用此选项,内核将重置连接而不是关闭它们,并丢弃所有仍在运行的数据。这对于大多数目的来说是非常不合适的,当然对于代理来说也是如此。这并不能以任何方式解决 CLOSE_WAIT。
  • 同意 CLOSE_WAIT,但是如果你想清理 TIME_WAIT,SO_LINGER 是唯一的选择,可以将其设置为 > 0 tho
  • 这不是唯一的选择。如果你是总是收到第一个 FIN 的那端,你根本就不会进入 TIME_WAIT。见状态图。因此,在关闭之前等待来自对等方的 EOS。很简单。
猜你喜欢
  • 2017-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多