[英]Sftp Retry Logic Inside Azure function App
我面临一个问题,我收到间歇性错误消息
“现有连接被远程主机强行关闭”
在尝试连接 sftp 服务器时。 我正在尝试在 azure function 应用程序中连接 sftp。 我相信在存在连接问题时会发生此错误。
为了处理这个问题,我需要实施重试逻辑,以防万一发生此类错误,以指定的延迟重复连接 sftp 服务器,直到达到配置的最大重试次数。 我相信 function 应用程序允许的最大执行时间是 5 分钟(需要从 azure 专家那里听到)。
谁能帮助我如何在 C# 中实现此重试功能?
我正在使用Renci.SshNet
nuget package 来管理 sftp
using (var _sftpCn = new SftpClient(host, port, userName, password))
{
_sftpCn.Connect();//error happens on this line:"An existing connection was forcibly closed by the remote host"
log.LogInformation("Successful");
byte[] byteArray = Encoding.UTF8.GetBytes(datacontent);
sftpCl.WriteAllBytes("{remotePath}", byteArray);
log.LogInformation("Sent successfully");
_sftpCn.Disconnect();
}
我建议在这里使用Polly 。
Polly 是一个 .NET 弹性和瞬态故障处理库,允许开发人员以流畅和线程安全的方式表达重试、断路器、超时、隔板隔离和回退等策略。
它是免费的库,可以通过以下命令下载为nuget package :
do.net add package Polly
如果您查看Connect
方法的源代码,那么您会发现它有关于异常的文档注释。 不幸的是,他们都没有提到您所面临的错误信息。
正如您在评论中所述,您不知道引发了哪个异常,因为您的日志记录系统仅捕获异常消息。 您怀疑是SSHException
和SShConnectionException
。
对于 Polly,您可以针对这种情况以多种方式定义重试策略
Handle
生成器方法var retryPolicy = Policy
.Handle<Exception>(ex => ex is SSHException || ex is SShConnectionException)
.WaitAndRetry(...);
Handle
和Or
构建器方法var retryPolicy = Policy
.Handle<SSHException>()
.Or<SShConnectionException>()
.WaitAndRetry(...);
const string ErrorPrefix = "An existing connection was forcibly closed by the remote host";
var retryPolicy = Policy
.Handle<Exception>(ex => ex.Message.StartsWith(ErrorPrefix)
|| (ex.InnerException?.Message.StartsWith(ErrorPrefix) ?? false))
.WaitAndRetry(...);
你也提到了
function 应用程序允许的最长执行时间为 5 分钟
Polly 的重试允许您定义最多要执行相同操作的次数:
Retry
或WaitAndRetry
构建器方法来实现RetryForever
或WaitAndRetryForever
构建器方法来实现如果您想在给定的时间范围内执行重试尝试,则需要组合重试和超时策略。
var timeoutPolicy = Policy.Timeout(TimeSpan.FromMinutes(4.5));
var retryPolicy = Policy
.Handle...
.WaitAndRetryForever(...);
var combinedPolicy = Policy.Wrap(timeoutPolicy, retryPolicy);
请记住Wrap
方法参数的顺序很重要:
这种灵活性允许您定义每次重试尝试和总体时间限制
var globalTimeoutPolicy = Policy.Timeout(TimeSpan.FromMinutes(4.5));
var perAttemptTimeoutPolicy = Policy.Timeout(TimeSpan.FromSeconds(5));
var retryPolicy = Policy
.Handle...
.WaitAndRetryForever(...);
var combinedPolicy = Policy.Wrap(globalTimeoutPolicy, retryPolicy, perAttemptTimeoutPolicy);
我希望这些示例可以帮助您解决问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.