FastDFS——文件上传失败问题(java.io.IOException: recv package size -1 != 10)
·
FastDFS文件上传失败问题(java.io.IOException: recv package size -1 != 10)
文章目录
前言
需求分析:本来是一个很简单的操作,往文件服务器上传文件,并将冗余文件进行删除操作。
一、情景再现
1.出事代码
/**
* 上传文件
* @param file
* @return
* @throws IOException
*/
private String saveFile(FastDfsFile file) throws IOException {
boolean activeTest = ProtoCommon
.activeTest(new TrackerClient(ClientGlobal.g_tracker_group).getConnection().getSocket());
// 相当于发起第一次握手,之后文件上传就是第二次了。
// org.csource.fastdfs.ProtoCommon.activeTest(trackerServer.getSocket());
logger.info("File Name: " + file.getFileName() + "File Length:" + file.getFileContent().length);
NameValuePair[] metaList = new NameValuePair[] { new NameValuePair("author", file.getAuthor()) };
long startTime = System.currentTimeMillis();
String[] uploadResults;
try {
// storageClient = new StorageClient(trackerServer, storageServer);
uploadResults = storageClient.upload_file(file.getFileContent(), file.getFileType(), metaList);
} catch (IOException e) {
logger.error("IO Exception when uploading the file:" + file.getFileName(), e);
throw e;
} catch (MyException var10) {
logger.error("Non IO Exception when uploading the file:" + file.getFileName(), var10);
return null;
}
logger.info("上传文件耗时:" + (System.currentTimeMillis() - startTime) + " ms");
if (uploadResults == null) {
logger.error("upload file fail, error code:" + storageClient.getErrorCode());
return null;
} else {
String groupName = uploadResults[0];
String remoteFileName = uploadResults[1];
logger.info("upload file successfully!!!group_name:" + groupName + ", remoteFileName: " + remoteFileName);
String resultUrl = groupName + "/" + remoteFileName;
return resultUrl;
}
}
/**
* 删除文件
*/
@Override
public EcpResult deleteFile(String groupName, String remoteFileName) {
try {
storageClient = new StorageClient(trackerServer, storageServer);
int i = storageClient.delete_file(groupName, remoteFileName);
logger.info("delete file successfully!!!" + i);
return EcpResult.buildDeleteSucess();
} catch (IOException var4) {
var4.printStackTrace();
} catch (MyException var5) {
var5.printStackTrace();
}
return EcpResult.buildQueryFailed();
}
接口:
@PostMapping("/save/{eventId}")
public EcpResult save(@PathVariable Integer eventId ,@RequestParam("file") MultipartFile file,HttpServletRequest request, HttpServletResponse response){
/** 上传文件 */
String dfsPath = fileService.uploadFile(file);
EmergencyNew emergencyNew = emergencyNewService.getById(eventId);
if (oConvertUtils.isEmpty(file)){
return EcpResult.buildUpdateFailed("文件不能为空!");
}
if (oConvertUtils.isEmpty(emergencyNew)){
return EcpResult.buildUpdateFailed("事件不存在,保存文件失败");
}
/** 删除冗余文件 */
if (oConvertUtils.isNotEmpty(emergencyNew.getAnalysis())){
String analysis = emergencyNew.getAnalysis();
String[] split = analysis.split("/");
fileService.deleteFile(split[0], analysis);
}
if (oConvertUtils.isEmpty(dfsPath)){
return EcpResult.failed("保存文件失败");
}
User user = CacheUtil.getUser(request);
if (oConvertUtils.isNotEmpty(user)){
emergencyNew.setUpdateBy(user.getId()+"");
}
emergencyNew.setAnalysis(dfsPath);
emergencyNew.setUpdateTime(new Date());
boolean b = emergencyNewService.updateById(emergencyNew);
if (b){
String name = file.getOriginalFilename();
System.out.println(name);
System.out.println(filePath+name);
FileUtil.deleteFile(filePath+name);
}
return EcpResult.success(dfsPath);
}
2.文件上传异常
java.io.IOException: recv package size -1 != 10
at org.csource.fastdfs.ProtoCommon.recvHeader(ProtoCommon.java:206)
at org.csource.fastdfs.ProtoCommon.recvPackage(ProtoCommon.java:242)
at org.csource.fastdfs.TrackerClient.getStoreStorage(TrackerClient.java:143)
at org.csource.fastdfs.StorageClient.newWritableStorageConnection(StorageClient.java:1912)
at org.csource.fastdfs.StorageClient.do_upload_file(StorageClient.java:702)
at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:207)
at org.csource.fastdfs.StorageClient.upload_file(StorageClient.java:225)
at org.csource.fastdfs.StorageClient1.upload_file1(StorageClient1.java:112)
3.异常情况分析
现象:第一次调用接口文件正常上传,后面再次调用文件上传接口,会一直提示文件上传异常(java.io.IOException: recv package size -1 != 10),将删除方法注释后,文件上传正常。
分析:文件上传和文件删除方法都会建立一次连接(storageClient = new StorageClient(trackerServer, storageServer)),两次建立的连接的对象不是同一个对象,客户端第二次建立连接后,文件服务器会把第一次建立的连接对象剔除掉,后面就会一直出现连接超时的情况。
二、解决方案
1.初始化注入StorageClient对象
代码如下(示例):
@Autowired
private StorageClient storageClient;
@Bean
public StorageClient getStorageClient(){
return new StorageClient(trackerServer, storageServer);
}
2.使用连接池
更多推荐
所有评论(0)