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