代码之家  ›  专栏  ›  技术社区  ›  Rodolphe

仅在Azure web app中从FTP下载文件失败

  •  2
  • Rodolphe  · 技术社区  · 7 年前

    我有一个从FTP服务器下载文本文件列表的非常基本的代码:

    foreach (var fileUri in files)
    {
        try
        {
            var ftpRequest = (FtpWebRequest)FtpWebRequest.Create(fileUri);
            ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
            ftpRequest.Credentials = new NetworkCredential("***", "***");
            ftpRequest.UseBinary = false;
            ftpRequest.Timeout = 10_000;
            ftpRequest.ReadWriteTimeout = 10_000;
    
            using (WebResponse response = await ftpRequest.GetResponseAsync().ConfigureAwait(false))
            using (var stream = response.GetResponseStream())
            {
                // Copy the file to an Azure storage
                await CopyAsync(stream, container, GetFilename(fileUri), false).ConfigureAwait(false);
            }
        }
        catch (Exception e)
        {
            Logger.Error(Unknow, $"Error downloading {fileUri.AbsoluteUri}:\n{e}");
        }
    }
    

    当从Visual Studio运行时,此代码工作正常。 但当在Azure中作为web作业运行时,它只下载了几个文件,然后就永远挂起了。

    我没有超时或异常。

    我添加了一些调试日志,发现它被卡住了 GetResponseAsync() . 我试过不用 ConfigureAwait(false) 但也有同样的行为。

    我还使用 this answer 检查网络跟踪,但我在日志中找到的所有FTP命令都正常。对于成功下载的每个文件,我都会看到以下几行,但对于被阻止的文件,我看不到任何“不完整”的FTP命令:

    System.Net Information: 0 : [22712] FtpWebRequest#2543959::.ctor(ftp://<ftpserver>/<filename>)
    System.Net Information: 0 : [21728] FtpWebRequest#2543959::BeginGetResponse(Method=RETR.)
    System.Net Information: 0 : [21728] Associating FtpWebRequest#2543959 with FtpControlStream#64735656
    System.Net Information: 0 : [21728] FtpControlStream#64735656 - Sending command [PASV]
    System.Net Information: 0 : [9444] FtpControlStream#64735656 - Received response [227 Entering Passive Mode (104,45,19,12,117,54).]
    System.Net Information: 0 : [9444] FtpControlStream#64735656 - Sending command [RETR <filename>]
    System.Net Information: 0 : [17608] FtpControlStream#64735656 - Received response [150 Opening ASCII mode data connection for <filename> (19262 bytes)]
    System.Net Information: 0 : [21804] FtpControlStream#64735656 - Received response [226 Transfer complete]
    System.Net Information: 0 : [21804] FtpWebRequest#2543959::(Releasing FTP connection#64735656.)
    

    如有任何帮助/线索,将不胜感激!

    编辑1

    我试过使用 WebClient 而不是 FtpWebRequest 得到了同样的结果。它在我的机器上运行得很好,但在Azure上作为web作业运行时,它会下载几个文件,然后挂起 webClient.DownloadFileTaskAsync(...) 线此外,为了确保我上传到Azure存储不会干扰这个过程,我现在只需在本地下载文件。agin:无异常,无超时。它永远挂着。

    编辑2

    我尝试删除将文件上载到Azure存储的行,以防万一,但没有成功。然后,根据第一位评论者的建议,我添加了一个“超时包装器”,它本质上是作为任务运行我的代码,一个 Task.Delay(10_000) ,然后等待第一个任务完成。如果下载任务先完成,那么一切都很好,但是如果 任务延迟(10\u 000) 首先完成,我只需中止下载请求并重试。这样做,我观察到以下几点:首先,文件都是在第一次尝试时下载的。然后,一些文件需要尝试2次,在某些情况下,所有文件都会失败,尽管尝试了10次。所以基本上,一切都开始得很好,但很快就会退化。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Rodolphe    6 年前

    所以。。。我觉得有点傻,但问题不在我猜测的代码中。这只是一个CPU使用问题。我最终发现(在Azure支持的帮助下),我在同一个应用程序服务计划中有其他web作业,总的来说,这些web作业消耗了太多的CPU。但坦率地说,我发现这些症状很容易让人误解。

    不管怎样,我希望这会对将来的人有所帮助。

    TL;博士 始终检查您的CPU使用情况!