簡體   English   中英

嘗試將文件放在 sftp 上的並行線程經常從 sftp 服務器獲取連接重置錯誤

[英]Getting Connection Reset error from sftp server frequently with parallel threads trying to put file on sftp

我有一段多線程代碼,它有 22 個線程並行運行並試圖將文件放在 sftp 服務器上。

但是我的日志中不斷出現連接重置錯誤,因此很少有記錄失敗。

初步分析,我發現 sftp 服務器的大小為 t2.small,CPU 使用率達到 92%。

考慮到這是我將服務器更改為 c5n.xlarge 的原因,現在錯誤發生的頻率降低了,但即使最大 CPU 使用率達到 63%,我有時也會遇到錯誤。

我無法在 /var/log/secure 的 sftp 服務器日志中找到任何不同之處。

下面是一段用於放置文件的代碼,每個線程創建一個新會話並關閉它。

JSch ssh = new JSch();
            // ssh.setKnownHosts("/path/of/known_hosts/file");
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            // Use key authentication if it is set, else use password auth
            if (mpServerDetails.get(SftpFile.SFTP_USERKEY) != null
                    && mpServerDetails.get(SftpFile.SFTP_USERKEY) != "") {
                    File userKeyFile = new File(mpServerDetails.get(SftpFile.SFTP_USERKEY).toString());
                if (userKeyFile == null || !userKeyFile.exists()) {
                    throw new NonRetriableException(
                            "Key file " + mpServerDetails.get(SftpFile.SFTP_USERKEY).toString() + "not found.");
                }
                ssh.addIdentity(userKeyFile.getAbsolutePath());
                session = ssh.getSession(mpServerDetails.get(SftpFile.SFTP_USERNAME).toString(),
                        mpServerDetails.get(SftpFile.SFTP_HOSTNAME).toString());
            } else if (mpServerDetails.get(SftpFile.SFTP_PASSWORD) != null) {
                session = ssh.getSession(mpServerDetails.get(SftpFile.SFTP_USERNAME).toString(),
                        mpServerDetails.get(SftpFile.SFTP_HOSTNAME).toString());
                session.setPassword(mpServerDetails.get(SftpFile.SFTP_PASSWORD).toString());
            }
            session.setConfig(config);
            session.connect();
            if (session != null && !session.isConnected()) {
                logger.warn("**session is not connected going to connect the sftp session ** {} ", session.getHost());
                session.connect();
            }
            channel = (ChannelSftp) session.openChannel("sftp");
            if (channel != null && !channel.isConnected()) {
                logger.warn("**channel is not connected going to connect the sftp channel ** {} ",
                        channel.getSession().isConnected());
                channel.connect();
            }
            channel.put(file.getAbsolutePath(), dest.getConfig().get(TransporterFileConstants.SFTP_DIRECTORY).toString()
                    + File.separatorChar + dest.getFileName(), new SystemOutProgressMonitor());

        }
        catch (NonRetriableException e) {
            throw new NonRetriableException(e);
        }
        catch (Exception e) {
            logger.error(
                    "Error occured while uploading file having name " + dest.getFileName() + " from remote directory:"
                            + dest.getConfig().get(TransporterFileConstants.SFTP_DIRECTORY).toString(),
                    e);
            logger.error("SFTP Exception : ", e);
            throw new RetriableException(e);
        }
        finally {
            if (null != channel && channel.isConnected()) {
                try {
                    channel.disconnect();
                }
                catch (Throwable e) {
                    logger.error("Error while disconnecting channel : ", e);
                }
            }
            if (null != session) {
                try {
                    session.disconnect();
                }
                catch (Throwable e) {
                    logger.error("Error while returning object to sftp pool : ", e);
                }
            }
        }

有人能幫我理解為什么我會得到這個例外嗎?

SFTP 服務器配置是

MaxSessions 50
Capacity - 25 GB
4 core server with 10 GB Ram

一段錯誤信息

com.jcraft.jsch.JSchException: Session.connect: java.net.SocketException: Connection reset
    at com.jcraft.jsch.Session.connect(Session.java:558) ~[honeybee-engine.jar:na]

如果這種情況繼續發生,我的數據處理將不一致。

MaxSessions 50

SSH 服務器MaxSessions參數限制可以通過單個 SSH 連接運行的“會話”數。 您僅通過每個連接運行一個會話(SFTP 會話),因此 MaxSessions 限制與您不是特別相關。

您的問題可能與MaxStartups設置有關:

MaxStartups
指定到 SSH 守護進程的最大並發未驗證連接數。 其他連接將被丟棄,直到身份驗證成功或連接的 LoginGraceTime 到期。 默認為 10:30:100....

基本上,如果有太多客戶端連接到尚未驗證的服務器,服務器將丟棄其中一些連接。 如果您的應用程序同時打開太多與服務器的連接,服務器可能會丟棄其中一些連接。 這里的解決方案是調整MaxStartups的值,或者改變你的應用程序不要一次打開那么多連接。

還有一個稱為listen backlog的操作系統限制。 基本上,操作系統只會保留一定數量的未決 TCP 連接。 如果同時有足夠多的連接嘗試進入,而 ssh 服務器進程接受它們的速度不夠快,那么操作系統將丟棄一些連接請求。 SSH 服務器請求 128 個連接的積壓,但操作系統可能會將積壓限制在較低的值。 如果您的 SSH 服務器足夠繁忙,您可能會遇到此限制。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM