#java #jsch #sshd
#java #jsch #sshd
Вопрос:
У меня есть фрагмент многопоточного кода, в котором 22 потока выполняются параллельно и пытаются поместить файлы на sftp-сервер.
Но я продолжаю периодически получать ошибку сброса соединения в своих журналах, и из-за этого некоторые записи терпят неудачу.
При первоначальном анализе я обнаружил, что размер sftp-сервера был t2.small, а загрузка процессора составляла 92%.
Учитывая это, по моей причине я сменил сервер на c5n.xlarge, теперь ошибка появляется реже, но, тем не менее, я получаю ее время от времени, даже когда максимальная загрузка процессора достигает 63%.
Я не могу найти ничего другого в журналах sftp-сервера в /var/log/ secure.
Ниже приведен фрагмент кода, используемый для размещения файла, каждый поток создает новый сеанс и закрывает его.
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
amp;amp; 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 amp;amp; !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 amp;amp; !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 amp;amp; 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]
Если это будет продолжаться, моя обработка данных не будет согласованной.
Комментарии:
1. Вы открываете новое соединение для каждого отдельного файла?
2. Да, но также закрываю его.
3. И рассматривали ли вы возможность повторного использования соединения в каждом потоке?
4. На самом деле, это работает немного по-другому, есть различные исполнители, которые постоянно работают и выполняют различные задачи, и у нас есть эта задача, которая загружает файлы на sftp. Он может быть подобран любым потоком исполнителя. И эта задача использует службу загрузки sftp, которая создает новое соединение каждый раз, когда ее просят что-то поместить. Но одновременно эту задачу могут выполнять не более 22 исполнителей.
5. @MartinPrikryl Что я пытаюсь понять, так это то, что это проблема с моим кодом или какая-то проблема на стороне sftp-сервера, поскольку частота ошибок уменьшилась по мере увеличения размера сервера sftp, но все равно возникают ошибки при использовании 63%
Ответ №1:
MaxSessions 50
Параметр SSH server MaxSessions
ограничивает количество «сеансов», которые могут выполняться через одно SSH-соединение. Вы запускаете только один сеанс — сеанс SFTP — через каждое соединение, поэтому ограничение MaxSessions для вас не имеет особого значения.
Ваша проблема может быть связана с MaxStartups
настройкой:
MaxStartups
Указывает максимальное количество одновременных не прошедших проверку подлинности подключений к SSH-демону. Дополнительные соединения будут удаляться до тех пор, пока аутентификация не завершится успешно или время входа в систему не истечет для соединения. По умолчанию 10:30:100….
В принципе, если к серверу подключено слишком много клиентов, которые еще не прошли проверку подлинности, сервер удалит некоторые из этих подключений. Если ваше приложение одновременно открывает слишком много подключений к серверу, сервер может отбрасывать некоторые из этих подключений. Решение здесь состоит в том, чтобы настроить значение MaxStartups или изменить ваше приложение, чтобы не открывать столько соединений одновременно.
Существует также ограничение операционной системы, называемое отставанием в прослушивании. В принципе, операционная система будет поддерживать только определенное количество ожидающих TCP-соединений. Если одновременно поступает достаточное количество попыток подключения, а процесс ssh-сервера недостаточно быстр при их принятии, ОС отбрасывает некоторые запросы на подключение. SSH-сервер запрашивает отставание в 128 подключений, но ОС может ограничить отставание меньшим значением. Если ваш SSH-сервер достаточно занят, вы можете столкнуться с этим ограничением.