世界觀點:問題解決系列:ftp并發讀取文件內容時,會出現ftp連接數過多,進而導致讀取文件出現問題

2022-12-06 19:08:57 來源:51CTO博客

@??TOC??

場景

ftp并發讀取文件內容時,過了一段時候,連接數過多,進而導致讀取文件出現問題,被??ftp??服務器給限制了。截圖如下:


(資料圖)

環境

軟件

版本

centos

7

jdk

8

問題原因

原來的操作代碼如下:

InputStream in = null;ByteArrayOutputStream output = null;try {    in = ftpClient.retrieveFileStream(ftpFilePath);    output = new ByteArrayOutputStream();    byte[] buffer = new byte[1024 * 4];    int len = 0;    while ((len = in.read(buffer)) != -1) {        output.write(buffer, 0, len);    }} catch (Exception e) {    throw e;} finally {    if (in != null) {        in.close();    }    if (output != null) {        output.close();    }}

這個是讀取文件內容到程序的變量里面去,而不落地到本地文件,減少本地IO交互。程序執行完畢之后,就會關閉對應的流。但是就是這里出現了問題,沒有等待??ftp???服務器返回響應,就直接關閉了流。官方解釋,有幾種FTPClient方法是沒辦法完成整個FTP命令序列,進而完成事務的。所以這些命令要求我們在收到肯定的中間命令后采取一些措施來保證整個事務的完成。而我們的代碼完成其操作后,必須調用??completePendingCommand??來接收來自服務器的完成答復并驗證整個事務是否成功。

所以,問題出現的原因是沒有調用??completePendingCommand???來完成整個事務,導致??ftp???連接頻繁掛掉,然后不斷重新啟動新的??ftp???連接,導致連接數過多,被??ftp??服務器給限制了。

解決方案

1. 官方方案

下面是官方提供的解決方法:

InputStream input;OutputStream output;input  = new FileInputStream("foobaz.txt");output = ftp.storeFileStream("foobar.txt")if(!FTPReply.isPositiveIntermediate(ftp.getReplyCode())) {    input.close();    output.close();    ftp.logout();    ftp.disconnect();    System.err.println("File transfer failed.");    System.exit(1);}Util.copyStream(input, output);input.close();output.close();// Must call completePendingCommand() to finish command.if(!ftp.completePendingCommand()) {    ftp.logout();    ftp.disconnect();    System.err.println("File transfer failed.");    System.exit(1);}

2. 本文的解決方法

在關閉流的時候,判斷是否完成,以下為解決方法代碼:

InputStream in = null;ByteArrayOutputStream output = null;try {    in = ftpClient.retrieveFileStream(ftpFilePath);    output = new ByteArrayOutputStream();    byte[] buffer = new byte[1024 * 4];    int len = 0;    while ((len = in.read(buffer)) != -1) {        output.write(buffer, 0, len);    }} catch (Exception e) {    throw e;} finally {    if (in != null) {        in.close();    }    if (output != null) {        output.close();    }    if (ftp != null) {        // completePendingCommand 不能執行兩次        if (!ftp.getClient().completePendingCommand()) {            log.warn("ftp 關閉連接,對應的ITEM信息如下:{}",itemInfo);        }    }}

結果

使用命令??netstat -an|grep :21???來檢測??ftp??連接數,結果如下:

觀察程序運行結果,過了一個小時,未發現異常。問題得到解決。

總結

使用??FTPClient??的相關方法的時候,記得查看相關的文檔,里面已經有比較完善的解決措施。

求贊、關注

如果我的文章對大家產生了幫忙,可以在文章底部點個贊或者收藏;

如果有好的討論,可以留言;

如果想繼續查看我以后的文章,可以點擊關注

也可以掃描以下二維碼,關注我的公眾號:楓夜之求索閣,查看我最新的分享!

標簽: 出現問題 關閉連接 程序運行

上一篇:QT實現串口調試器
下一篇:微頭條丨#yyds干貨盤點# LeetCode程序員面試金典:移除重復節點