Spring Integration Sftp не удалось загрузить, но простая загрузка Jsch в порядке. Почему?

Я использую Spring Integration SFTP для загрузки файлов на сервер sftp. Когда я отправляю несколько одновременных запросов или тяжелых файлов, я получал исключение Socket Clode. Но когда я отправляю один и тот же файл напрямую с помощью простого клиента Jsch, даже при одновременных вызовах, кажется, что все в порядке.

Я использую конфигурацию по умолчанию для обеих библиотек. Spring SFTP использует Jsch, настроен ли он таким образом, что может вызвать ошибку? Есть ли специальная конфигурация или операция, выполняемая Spring, но не в конфигурации или поведении по умолчанию, чем простой Jsch?


person Philippe Warnon    schedule 28.04.2021    source источник
comment
Я только что увидел, что isSharedSession = true в моей конфигурации sftp для весенней интеграции. Но по умолчанию false при прямом использовании jsch.   -  person Philippe Warnon    schedule 28.04.2021
comment
Это устранило вашу проблему? isSharedSession - это вариант DefaultSftpSessionFactory (следовательно, Spring). Это не имеет ничего общего с клиентом jsch. Было бы здорово увидеть разницу в конфигурации для raw jsch и всего, что у вас есть для _3 _...   -  person Artem Bilan    schedule 28.04.2021
comment
@ArtemBilan, да, проблема решена. Извините за мой запутанный предыдущий комментарий. Не очень хорошо написано. При установке для isSharedSession значения true Spring не закрывает сеанс, который остается в пуле, чтобы избежать операций закрытия / повторного открытия. Это вызывает некоторые ошибки Socket Closed с некоторыми серверами sftp (в зависимости от их конфигурации). При использовании необработанного клиента jsch с выделенным сеансом + канал для каждой операции its'ok, использование isSharedSession = false также нормально, поэтому в некотором смысле isSharedSession = false можно рассматривать как эквивалент необработанной операции jsch с открытием / закрытием для каждой операции.   -  person Philippe Warnon    schedule 29.04.2021
comment
Есть. Не могли бы вы объяснить это как ответ на свой вопрос? Это поможет остальной части сообщества решить аналогичную проблему в будущем.   -  person Artem Bilan    schedule 29.04.2021
comment
@ArtemBilan, скопировал мой комментарий как ответ. Но мой оставшийся вопрос: почему это не удалось? У вас есть идея, почему некоторые серверы, в зависимости от их конфигурации, не работают правильно с клиентом Spring, настроенным с параметром isSharedSession, установленным в значение true?   -  person Philippe Warnon    schedule 29.04.2021
comment
Или, может быть, иногда Spring не проверяет (правильно), что сеанс все еще открыт или не может повторно открыть его, прежде чем передать ему клиент пула сеансов?   -  person Philippe Warnon    schedule 29.04.2021


Ответы (2)


Проблема исправлена. При установке для isSharedSession значения true Spring не закрывает сеанс, который остается в пуле, чтобы избежать операций закрытия / повторного открытия. Это вызывает некоторые ошибки Socket Closed с некоторыми серверами sftp (в зависимости от их конфигурации). При использовании необработанного клиента jsch с выделенным сеансом + канал для каждой операции its'ok, использование isSharedSession = false также нормально, поэтому в некотором смысле isSharedSession = false можно рассматривать как эквивалент необработанной операции jsch с открытием / закрытием для каждой операции

person Philippe Warnon    schedule 29.04.2021
comment
Итак, да ... Не рекомендуется использовать общий сеанс для одновременной работы. В большинстве случаев нам просто нужен такой единственный сеанс на адаптере входящего канала, который, как правило, является однопоточным компонентом опроса: docs.spring.io/spring-integration/docs/current/reference/html/. Для параллельных отправок лучше разрешить сеансам порождаться через CachingSessionFactory и повторно использовать соответственно. - person Artem Bilan; 29.04.2021
comment
Я уже использую CachingSessionFactory. Когда я использую с общим сеансом, он не работает. Это нормально с isShareSession = false - person Philippe Warnon; 29.04.2021
comment
Но Spring docs без того, что isSharedSession = true, следует использовать с CachingsessionFactory, но иногда это не работает - person Philippe Warnon; 29.04.2021
comment
Я не вижу этого предложения, но все же оно, вероятно, в любом случае касается чтения в адаптере входящего канала: не о записи в адаптере исходящего канала, особенно когда он является параллельным и долгоживущим. - person Artem Bilan; 29.04.2021
comment
comment
JSch поддерживает несколько каналов (операций) через соединение с сервером. По умолчанию фабрика сеансов Spring Integration использует отдельное физическое соединение для каждого канала. Начиная с Spring Integration 3.0, вы можете настроить фабрику сеансов (используя логический конструктор arg - по умолчанию false) для использования одного подключения к серверу и создания нескольких каналов JSch для этого единственного подключения. При использовании этой функции вы должны заключить фабрику сеанса в кэширующую фабрику сеанса, как описано ниже, чтобы соединение не было физически закрыто после завершения операции. - person Philippe Warnon; 29.04.2021
comment
Что ж, это старый документ: с тех пор что-то изменилось. Я не рекомендую кеширование для операций отправки. - person Artem Bilan; 29.04.2021
comment
Некоторые компоненты (слушатели-кролики и т. Д.) Используют sessionFactory не только для загрузки. CachingSessionFactory позволяет использовать пул и ограничивает его размер. Есть ли проблема, если я инкапсулирую DefaultSftpSessionFactory (false), который закрывает сеансы после каждого использования, в CachingSessionFactory для управления размером пула и распределения сеансов? Или мне следует заменить CachingSessionFactory чем-то другим для управления пулом? - person Philippe Warnon; 29.04.2021
comment
Да, все в порядке: без обмена, но кеширование. - person Artem Bilan; 29.04.2021

Конфигурация бина, которая устранила проблему:

@Bean("speosSessionFactory")
public SessionFactory<ChannelSftp.LsEntry> speosSftpSessionFactory(ApplicationProperties applicationProperties) {
    DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory(false);
    factory.setHost(applicationProperties.getHost());
    factory.setPort(applicationProperties.getPort());
    factory.setUser(applicationProperties.getUser());
    if (applicationProperties.getPrivateKey() != null) {
        factory.setPrivateKey(applicationProperties.getPrivateKey());
        factory.setPrivateKeyPassphrase(applicationProperties.getPrivateKeyPassphrase());
    } else {
        factory.setPassword(applicationProperties.getPassword());
    }
    factory.setAllowUnknownKeys(true);
    return new CachingSessionFactory<>(factory, applicationProperties.getMaxSessions());
}
person Philippe Warnon    schedule 29.04.2021