错误:ssh:握手失败:读取 tcp 读取:对等方重置连接

时间:2021-04-21 06:06:53

标签: go tcp ftp sftp

我正在尝试使用以下 golang 代码连接到我供应商的 SFTP 服务器。

    config := &ssh.ClientConfig{
        User:            user,
        Auth:            []ssh.AuthMethod{ssh.PublicKeys(signer)},
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }
    config.SetDefaults()

    // connect
    conn, err = ssh.Dial(network, address+port, config)
    if err != nil {
        return err
    }
    defer conn.Close()

我随机收到ssh:握手失败:读取tcp :->::读取:连接重置由对等方 ssh.Dial() 方法中的错误。它在 5 次中有 2 次有效,但其他 3 次失败。这可能是由于 FTP 服务器从其他客户端获取的大量连接请求造成的吗?在这些情况下是否建议使用指数退避重试?

1 个答案:

答案 0 :(得分:1)

<块引用>

这可能是由于 FTP 服务器从其他客户端获取的连接请求量很大吗?

这确实是由 golang/go issue 20960 "net/http: read: connection reset by peer under high load" 提出的:(获得了 HTTPS,但限制也适用于 SSH 连接)

<块引用>

如果您的网络连接断开,它们可能是真实的(对等方确实断开了连接),或者它们可能是因为在一侧达到内核限制。

示例:

<块引用>

我正在运行 1000 个并发连接,它最终在 OSX 上也遇到了这个问题,文件描述符从默认值 (256) 增加到 4096。

server configuration 很重要。

或者:

<块引用>

我也在 macOS 下看到这个问题,其中服务器和客户端通过 localhost 通信。我不知道问题的确切原因,但在高负载期间运行 netstat 会显示大量处于 TIME_WAIT 状态的连接。

我要么用尽文件描述符,要么用尽本地端口。
或者两者兼而有之。

我一直看到对等连接重置,直到 TIME_WAIT 连接数约为 7k。如果我让测试进一步运行,我最终会收到 connect: can't assign requested address 错误,这表明我用尽了本地端口。
TIME_WAIT 连接数为 15k。

对于我不需要的项目,我可以通过限制并发连接数来解决问题。通过限制 goroutine 的数量来解决我的代码中的问题似乎是随意的,但仍然偶尔会失败。
在 http 传输中限制 MaxConnsPerHost 成功了,问题完全消失了。