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