项目版本:
项目是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(......); }