Windows 服务 - 发生 FTP 提供程序维护窗口时不可恢复的 FtpWebRequest 超时



我有一个Windows服务,每小时都会从FTP服务器下载一个FTP文件。它使用以下代码来执行此操作:

var _request = (FtpWebRequest)WebRequest.Create(configuration.Url);
_request.Method = WebRequestMethods.Ftp.DownloadFile;
_request.Timeout = 20000;
_request.Credentials = new NetworkCredential("auser", "apassword");
using (var _response = (FtpWebResponse)_request.GetResponse())
using (var _responseStream = _response.GetResponseStream())
using (var _streamReader = new StreamReader(_responseStream))
{
    this.c_fileData = _streamReader.ReadToEnd();
}
通常,下载FTP

数据工作正常,但是每隔几个月FTP服务器提供商就会通知我们需要执行一些维护。因此,一旦开始维护(通常只有 2 或 3 小时),我们每小时尝试的 FTP 下载就会失败 - 即超时,这是意料之中的。

问题是,在维护窗口之后,我们的 Windows 服务每次尝试下载文件时都会继续超时。我们的 Windows 服务也有重试逻辑,但每次重试也会超时。

重新启动 Windows 服务后,应用程序将再次开始成功下载 FTP 文件。

有谁知道为什么我们必须重新启动Windows服务才能从这次故障中恢复?,这可能是网络问题,例如DNS?

注1:已经有与此类似的问题,但它们不涉及维护窗口,也没有任何可信的答案

注 2:我们分析了应用程序的内存,似乎所有 ftp 对象都已正确处理。

注意 3:我们在维护窗口后使用相同的 FTP 代码执行了一个控制台应用程序,它工作正常,而 Windows 服务仍然超时

任何帮助非常感谢

我们最终找到了这个问题的根源,尽管并非所有问题都得到了回答。

我们发现,当我们使用不同的内存探查器时,它显示两个 FtpWebRequest 对象在内存中,并且在此过程中几天没有被释放。这些对象是导致问题的原因,即它们没有得到适当的处置。

从研究到解决问题,我们做了以下工作:

  1. 将保持活动状态设置为 false
  2. 将连接租约超时设置为有限的超时值
  3. 将最大空闲时间设置为有限的超时值
  4. 包装在 try/catch/finally 中,其中请求在 finally 块中中止

我们将代码更改为以下内容:

var _request = (FtpWebRequest)WebRequest.Create(configuration.Url);
_request.Method = WebRequestMethods.Ftp.DownloadFile;
_request.Timeout = 20000;
_request.Credentials = new NetworkCredential("auser", "apassword");
_request.KeepAlive = false;
_request.ServicePoint.ConnectionLeaseTimeout = 20000;
_request.ServicePoint.MaxIdleTime = 20000;
try
{
    using (var _response = (FtpWebResponse)_request.GetResponse())
    using (var _responseStream = _response.GetResponseStream())
    using (var _streamReader = new StreamReader(_responseStream))
    {
        this.c_fileData = _streamReader.ReadToEnd();
    }
}
catch (Exception genericException)
{
    throw genericException;
}
finally
{
    _request.Abort();
}

老实说,我们不确定是否需要在这里做所有事情,但问题不再存在,即对象不会闲逛,应用程序在维护窗口后仍然可以运行,所以我们很高兴!

最新更新