项目版本:
项目是SpringBoot的1.5.9-release版本,fastdfs版本如下:
<dependency>
<groupId>net.arccode</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0</version>
</dependency>
调用方式如下:
我的fastdfs.conf配置:
connect_timeout = 10 network_timeout = 30 charset = UTF-8 tracker_service = xxx.xxx.xxx.xxx:xxx
java调用:
public class {
private TrackerClient trackerClient;
private TrackerService trackerService;
public (){
ClientGlobal.init("fastdfs.conf");
trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
trackerService = trackerClient.getConnection();
}
public void upload(){
StorageClient storageClient = new StorageClient(trackerService,null);
storageClient.upload_file(.....);
...
}
...
}
报错情况:
每次刚启动服务,如果没有直接使用,过一段时间,再调用上传文档服务,会报错,但是再次上传,就没事了,又正常了,报错信息如下:
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)
异常分析
经过多次验证重现这个错误,发现刚启动,间隔时间30秒,就会报错,不能上传,目测和fastdfs.conf配置的network_timeout =30有关系。
然后各种百度谷歌,发现有这么一句话:如果客户端服务启动,成功链接到dfs服务器,如果在network_timeout时间内,dfs服务没有接收到任何请求信息,会吧这个客户端踢掉!
日了,为毛要踢掉,我还要用啊,看来每次启动链接成功都需要给dfs服务发送点什么才行!
对dfs有研究了一波,发现fastdfs-client-java包到ProtoCommon.java本来已经提供了一个发送信息到一个方法,如下:
public static boolean activeTest(Socket sock)
解决办法
废话不多少,先试一波,修改上面dfs初始化代码如下:
public class FileManage{
private TrackerClient trackerClient;
private TrackerService trackerService;
public FileManage(){
ClientGlobal.init("fastdfs.conf");
trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
trackerService = trackerClient.getConnection();
ProtoCommon.activeTest(trackerService.getSocket());
}
//文档上传
public void upload(){
StorageClient storageClient = new StorageClient(trackerService,null);
storageClient.upload_file(.....);
...
}
...
}
启动项目,等30秒以上,测试,成功!
方法二:
在上传文件那作一次try,如果失败再次上传
String[] fileInfos = null;
try{
fileInfos = storageClient.upload_file(......); // 这里第一次访问时fileInfos返回值为null
}catch(Exception e){
e.printStackTrace();
fileInfos = storageClient.upload_file(......);
}