У меня большие проблемы с управлением SFTP-подключениями в очень важной службе C # .NET Windows, которая широко распространена среди наших клиентов.
В результате возникают такие простые операции, как подключение, отключение, загрузка, загрузкаи удаленная папка dir иногда застревает, и они замораживают весь сервис, даже если сообщаемое состояние в "services.msc" равно "Выполняется".Проблема не очень распространена, она не возникает во время значительных состояний сети, я вообще не могу ее воспроизвести и может случиться через 10 минут или даже через 1 месяц после запуска службы.
В нашем случае мы используем Renci SSH.NET для работы с SFTP, но зависания и зависания кажутся довольно распространенной проблемой и для других библиотек SFTP (WinSCP .NET API, SharpSSH и т. Д., Просто ищите в Интернете).).Учтите, что этот сервис является критически важным для бизнеса, он запускается каждые 30 минут и может привести к возникновению юридических проблем и штрафов в случае его зависания, поэтому ЭТО НЕ ДОЛЖНО ОСТАНОВИТЬСЯ.Это нормально с критическими исключениями, но замораживание не допускается.
Чтобы избежать подобных проблем в будущем, независимо от принятого API SFTP (мы подумываем перейти к WinSCP.NET, чтобы проверить, лучше ли этоМне интересно, как эти критические ситуации управляются в приложениях .NET.У меня есть следующие идеи, но у них есть большие недостатки:
Взаимодействие SFTP-клиента в задаче с Wait () с большим временем ожидания, как это:
private SftpClient _client = new SftpClient();
private sub Upload() {
var task = Task.Factory.StartNew(() => {
if(!_client.Connected) _client.Connect(); // Handle SFTP connection
_client.Upload(...); // Handle SFTP upload
});
task.Wait(3600000); // Wait 1 hour. If it fails who cares as long as it won't lock my service's main thread.
}
это может работать, но таким образом клиентский объект Sftp распределяется между потоками и может привести к проблемам, если сокет API не является полностью потокобезопасным (кто знает это?).Я также не могу продолжать создавать объекты SftpClient и открывать \ закрывать их для каждого взаимодействия SFTP, потому что частые соединения ухудшают производительность и, кажется, усиливают эту проблему.Более того, Wait () не прервет поток задачи, но вызовет исключение в потоке вызывающей стороны после истечения времени ожидания.Таким образом, дочерний поток будет зависать навсегда, и если API останется в несовместимом состоянии (я думаю о статических вещах внутри API), это может привести к неожиданному поведению в следующих исполнениях (проблемы с подключением, плохие чтения, плохие записи искоро...).Утилизация ресурсов тоже не произойдет, поэтому может произойти утечка памяти.
Взаимодействие SFTP-клиента в потоке и его прерывание по истечении длительного времени ожидания.Это тоже может сработать, но заявление об отказе от ответственности в MSDN https://docs.microsoft.com/it-it/dotnet/api/system.threading.thread.abort?view=netframework-4.7.2 - отличное «нет» для меня.
Создайте запланированное задание Windows, которое периодически NET STOP и NET START службы,Делая это, это, вероятно, смягчает проблему, но это реальная боль делать это на каждом клиентском сервере.
Использование библиотеки SFTP, которая не зависает, но выдает исключение в случае длительноговешать времяЭто было бы мечтой, но зависания довольно часто встречаются между API-интерфейсами FTP и SFTP.
Как бы вы работали с критически важными сервисами в .NET, где важны такие вещи, как безопасность человека, аэрокосмическое или военное оборудование?, финансы и тд) участвуют?Кажется, что здесь не работают паттерны «сторожевых программ» с потоками, потому что .NET полагается на кооперативную остановку потоков.
Некоторые идеи?