too many files open ftp(并发下载坑) 记录一次宕机

too many files open ftp(并发下载坑) 记录一次宕机,第1张

too many files open ftp(并发下载坑) 记录一次宕机

1、问题排查(如果没有什么相关工具可用,就比如我不知道用什么插件来排查,这就需要对业务了解)

查看某个进程下打开文件数量,虽可以设置文件打开数量,但不治本。

是因为并发太多的原因吗,修改核心线程数减少一半10改为3

发现并没有解决,再次宕机

继续排查发现这个进程打开的文件数达到3000后宕机(已经确定和ftp下载有关)

打开代码

测试下载方法

发现下载速度超快(万兆网)300张图片300M时间

2021-12-19 00:07:06.155 [schedule-pool-3] INFO  c.b.utils.time.Times - [test,24] - 结束:00:07:06.155
2021-12-19 00:07:06.155 [schedule-pool-3] INFO  c.b.utils.time.Times - [test,26] - 耗时:1.996秒

好像看不出问题

继续排查,在下载完成后(其实是上面的方法执行完,而图片可能因为网络原因阻塞)

有些图片的大小是0KB,而目标服务器上在告诉我可以下载之前也确实有该图片。那么问题确定 

图片没有下载完成,而我默认它下载完成了,最终导致文件打开的越来越多,系统宕机

解决办法:

修改下载方法(将原来的一个连接下多个图片改为一个连接下一个图片)

public boolean downloadFile(String destDir, String destFile, String localDir) {

        log.info("=============" + destDir + "====" + "===" + destFile + "+====" + localDir);
        boolean result = false;
        if (!connect()) {
            return result;
        }
        File localDirFile = new File(localDir);
        checkLocalDirExists(localDirFile);

        OutputStream os = null;
        ftpClient.enterLocalPassiveMode();
        try {
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.changeWorkingDirectory(destDir);
            ftpClient.enterLocalPassiveMode();
            FTPFile[] ftpFiles = ftpClient.listFiles();
//            if (destFile == null) {   ########## bug toomanyopenfiles
//                log.info(" === currentThreadName === " + Thread.currentThread().getName() + "n" + " === imgCount ===" + ftpFiles.length);
//                for (FTPFile file : ftpFiles) {
//                    File localFile = new File(localDirFile, file.getName());
//                    os = new FileOutputStream(localFile);
//                    ftpClient.retrieveFile(file.getName(), os);
                    InputStream inputStream = ftpClient.retrieveFileStream();
                    inputStream.close();
                    ftpClient.completePendingCommand();
//                    os.flush();
//                    result = true;
                    log.info("downLoading.... " + destDir + "/" + file.getName());
//                }
//            } else {
                log.info(" === currentThreadName === " + Thread.currentThread().getName() + "n" + " === FileCount ===" + ftpFiles.length);
                for (FTPFile file : ftpFiles) {
                    if (destFile.equalsIgnoreCase(file.getName())) {
                        log.info(" === TMS IncludeThisFile === " + "tms local file_name,{} ", file.getName());
                        File localFile = new File(localDirFile, file.getName());
                        os = new FileOutputStream(localFile);
                        ftpClient.retrieveFile(file.getName(), os);
                        os.flush();
                        result = true;
//                        log.info("downLoading...." + destDir + "/" + file.getName());
                        break;
                    }
                }
//            }

        } catch (Exception exception) {
            log.info("######### download error xml error xml_name: " + destFile + " destDir: "  + destDir + " localDir: " + localDir);
            exception.printStackTrace();
        } finally {
            if (os != null) {
                try {
                    os.close();
//                    ftpClient.completePendingCommand();
                } catch (IOException exception) {
                    exception.printStackTrace();
                }
            }
            disconnect();
        }

        return result;
    }

 加入超时时间保证图片下载不会因为网络原因一直阻塞

public boolean connect() {
        if (ftpClient.isConnected()) {
            return true;
        }
        try {
            ftpClient.connect(ftpConfig.getHost(), ftpConfig.getPort());
            ftpClient.login(ftpConfig.getUserName(), ftpConfig.getPassWord());
            int replyCode = ftpClient.getReplyCode();
            ftpClient.setControlKeepAliveTimeout(60);
            ftpClient.setDataTimeout(3000);
            ftpClient.setDefaultTimeout(3000);
            ftpClient.setSoTimeout(10000);
            if (!FTPReply.isPositiveCompletion(replyCode)) {
                ftpClient.disconnect();
                log.info("FTP connect failed.");
                return false;
            }
            if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
                LOCAL_CHARSET = "UTF-8";
            }
            ftpClient.setControlEncoding(LOCAL_CHARSET);
        } catch (IOException exception) {
            exception.printStackTrace();
            return false;
        }
        return true;
    }

凌晨3点

收工 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5704270.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存