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点
收工
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)