diff --git a/.gitignore b/.gitignore
index 50962d5..278fdf7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,8 +12,8 @@ target
*.iws
*.log
.idea
-
*.conf
*.PNG
.vscode/
+*.class
diff --git a/HISTORY b/HISTORY
index 1d26881..b1a12b7 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,3 +1,8 @@
+Version 1.30 2023-01-29
+ * support tracker server fail over
+ If the tracker server is not specified, when the tracker server fails to
+ get the connection, it will try to get the connection from other tracker servers.
+ The maximum number of attempts is the number of tracker servers minus 1
Version 1.29 2020-01-03
* support active test for connection pool.
diff --git a/README.md b/README.md
index 21782b6..b69c30f 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ mvn install:install-file -DgroupId=org.csource -DartifactId=fastdfs-client-java
org.csource
fastdfs-client-java
- 1.29-SNAPSHOT
+ 1.30-SNAPSHOT
```
diff --git a/pom.xml b/pom.xml
index d9ab0ac..0885363 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
org.csource
fastdfs-client-java
- 1.29-SNAPSHOT
+ 1.30-SNAPSHOT
fastdfs-client-java
fastdfs client for java
jar
diff --git a/src/main/java/org/csource/common/IniFileReader.java b/src/main/java/org/csource/common/IniFileReader.java
index e1c609c..3146635 100644
--- a/src/main/java/org/csource/common/IniFileReader.java
+++ b/src/main/java/org/csource/common/IniFileReader.java
@@ -155,13 +155,13 @@ public class IniFileReader {
} finally {
try {
if (in != null) in.close();
- //System.out.println("loadFrom...finally...in.close(); done");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
+ @SuppressWarnings("unchecked")
private void readToParamTable(InputStream in) throws IOException {
this.paramTable = new Hashtable();
if (in == null) return;
@@ -206,7 +206,6 @@ public class IniFileReader {
try {
if (bufferedReader != null) bufferedReader.close();
if (inReader != null) inReader.close();
- //System.out.println("readToParamTable...finally...bufferedReader.close();inReader.close(); done");
} catch (Exception ex) {
ex.printStackTrace();
}
diff --git a/src/main/java/org/csource/fastdfs/ClientGlobal.java b/src/main/java/org/csource/fastdfs/ClientGlobal.java
index 382e2a5..98e763d 100644
--- a/src/main/java/org/csource/fastdfs/ClientGlobal.java
+++ b/src/main/java/org/csource/fastdfs/ClientGlobal.java
@@ -48,7 +48,6 @@ public class ClientGlobal {
public static final String PROP_KEY_CONNECTION_POOL_MAX_IDLE_TIME = "fastdfs.connection_pool.max_idle_time";
public static final String PROP_KEY_CONNECTION_POOL_MAX_WAIT_TIME_IN_MS = "fastdfs.connection_pool.max_wait_time_in_ms";
-
public static final int DEFAULT_CONNECT_TIMEOUT = 5; //second
public static final int DEFAULT_NETWORK_TIMEOUT = 30; //second
public static final String DEFAULT_CHARSET = "UTF-8";
@@ -180,7 +179,6 @@ public class ClientGlobal {
String poolMaxCountPerEntry = props.getProperty(PROP_KEY_CONNECTION_POOL_MAX_COUNT_PER_ENTRY);
String poolMaxIdleTime = props.getProperty(PROP_KEY_CONNECTION_POOL_MAX_IDLE_TIME);
String poolMaxWaitTimeInMS = props.getProperty(PROP_KEY_CONNECTION_POOL_MAX_WAIT_TIME_IN_MS);
-
if (connectTimeoutInSecondsConf != null && connectTimeoutInSecondsConf.trim().length() != 0) {
g_connect_timeout = Integer.parseInt(connectTimeoutInSecondsConf.trim()) * 1000;
}
@@ -221,7 +219,7 @@ public class ClientGlobal {
* server之间用逗号','分隔
*/
public static void initByTrackers(String trackerServers) throws IOException, MyException {
- List list = new ArrayList();
+ List list = new ArrayList();
String spr1 = ",";
String spr2 = ":";
String[] arr1 = trackerServers.trim().split(spr1);
diff --git a/src/main/java/org/csource/fastdfs/ProtoStructDecoder.java b/src/main/java/org/csource/fastdfs/ProtoStructDecoder.java
index f6b9d9f..07dec45 100644
--- a/src/main/java/org/csource/fastdfs/ProtoStructDecoder.java
+++ b/src/main/java/org/csource/fastdfs/ProtoStructDecoder.java
@@ -27,6 +27,7 @@ public class ProtoStructDecoder {
/**
* decode byte buffer
*/
+ @SuppressWarnings("unchecked")
public T[] decode(byte[] bs, Class clazz, int fieldsTotalSize) throws Exception {
if (bs.length % fieldsTotalSize != 0) {
throw new IOException("byte array length: " + bs.length + " is invalid!");
diff --git a/src/main/java/org/csource/fastdfs/StorageClient.java b/src/main/java/org/csource/fastdfs/StorageClient.java
index 89f2798..5f0d61e 100644
--- a/src/main/java/org/csource/fastdfs/StorageClient.java
+++ b/src/main/java/org/csource/fastdfs/StorageClient.java
@@ -731,7 +731,6 @@ public class StorageClient {
try {
connection = this.storageServer.getConnection();
-
ext_name_bs = new byte[ProtoCommon.FDFS_FILE_EXT_NAME_MAX_LEN];
Arrays.fill(ext_name_bs, (byte) 0);
if (file_ext_name != null && file_ext_name.length() > 0) {
diff --git a/src/main/java/org/csource/fastdfs/TrackerClient.java b/src/main/java/org/csource/fastdfs/TrackerClient.java
index 22c4bba..8b8bd56 100644
--- a/src/main/java/org/csource/fastdfs/TrackerClient.java
+++ b/src/main/java/org/csource/fastdfs/TrackerClient.java
@@ -71,6 +71,71 @@ public class TrackerClient {
return this.getStoreStorage(trackerServer, groupName);
}
+ public Connection getConnection(TrackerServer trackerServer) throws IOException, MyException {
+ Connection connection = null;
+ int length = this.tracker_group.tracker_servers.length;
+ boolean failOver = length > 1 && trackerServer == null;
+ try {
+ if (trackerServer == null) {
+ trackerServer = getTrackerServer();
+ if (trackerServer == null) {
+ throw new MyException("tracker server is empty!");
+ }
+ }
+ connection = trackerServer.getConnection();
+ } catch (IOException e) {
+ if (failOver) {
+ System.err.println("trackerServer get connection error, emsg:" + e.getMessage());
+ } else {
+ throw e;
+ }
+ } catch (MyException e) {
+ if (failOver) {
+ System.err.println("trackerServer get connection error, emsg:" + e.getMessage());
+ } else {
+ throw e;
+ }
+ }
+ if (connection != null || !failOver) {
+ return connection;
+ }
+ //do fail over
+ int currentIndex = 0;
+ if (trackerServer != null) {
+ currentIndex = trackerServer.getIndex();
+ }
+ int failOverCount = 0;
+ while (failOverCount < length - 1) {
+ failOverCount++;
+ currentIndex++;
+ if (currentIndex >= length) {
+ currentIndex = 0;
+ }
+ try {
+ trackerServer = this.tracker_group.getTrackerServer(currentIndex);
+ if (trackerServer == null) {
+ throw new MyException("tracker server is empty!");
+ }
+ return trackerServer.getConnection();
+ } catch (IOException e) {
+ System.err.println("fail over trackerServer get connection error, failOverCount:" + failOverCount + "," + e.getMessage());
+ if (failOverCount == length - 1) {
+ throw e;
+ }
+
+ } catch (MyException e) {
+ System.err.println("fail over trackerServer get connection error, failOverCount:" + failOverCount + ", " + e.getMessage());
+ if (failOverCount == length - 1) {
+ throw e;
+ }
+ }
+
+
+ }
+ return null;
+ }
+
+
/**
* query storage server to upload file
*
@@ -85,12 +150,7 @@ public class TrackerClient {
byte cmd;
int out_len;
byte store_path;
- Connection connection;
-
- if (trackerServer == null) {
- trackerServer = getTrackerServer();
- }
- connection = trackerServer.getConnection();
+ Connection connection = getConnection(trackerServer);
OutputStream out = connection.getOutputStream();
try {
@@ -170,16 +230,7 @@ public class TrackerClient {
int port;
byte cmd;
int out_len;
- Connection connection;
-
- if (trackerServer == null) {
- trackerServer = getTrackerServer();
- if (trackerServer == null) {
- return null;
- }
- }
-
- connection = trackerServer.getConnection();
+ Connection connection = getConnection(trackerServer);
OutputStream out = connection.getOutputStream();
try {
@@ -343,15 +394,7 @@ public class TrackerClient {
int len;
String ip_addr;
int port;
- Connection connection;
-
- if (trackerServer == null) {
- trackerServer = getTrackerServer();
- if (trackerServer == null) {
- return null;
- }
- }
- connection = trackerServer.getConnection();
+ Connection connection = getConnection(trackerServer);
OutputStream out = connection.getOutputStream();
try {
@@ -473,16 +516,7 @@ public class TrackerClient {
byte cmd;
int out_len;
byte store_path;
- Connection connection;
-
- if (trackerServer == null) {
- trackerServer = getTrackerServer();
- if (trackerServer == null) {
- return null;
- }
- }
-
- connection = trackerServer.getConnection();
+ Connection connection = getConnection(trackerServer);
OutputStream out = connection.getOutputStream();
try {
@@ -548,15 +582,7 @@ public class TrackerClient {
byte[] bGroupName;
byte[] bs;
int len;
- Connection connection;
-
- if (trackerServer == null) {
- trackerServer = getTrackerServer();
- if (trackerServer == null) {
- return null;
- }
- }
- connection = trackerServer.getConnection();
+ Connection connection = getConnection(trackerServer);
OutputStream out = connection.getOutputStream();
try {
diff --git a/src/main/java/org/csource/fastdfs/TrackerGroup.java b/src/main/java/org/csource/fastdfs/TrackerGroup.java
index dfcfd74..b79f706 100644
--- a/src/main/java/org/csource/fastdfs/TrackerGroup.java
+++ b/src/main/java/org/csource/fastdfs/TrackerGroup.java
@@ -18,84 +18,83 @@ import java.net.InetSocketAddress;
* @version Version 1.17
*/
public class TrackerGroup {
- public int tracker_server_index;
- public InetSocketAddress[] tracker_servers;
- protected Integer lock;
+ public int tracker_server_index;
+ public InetSocketAddress[] tracker_servers;
+ protected Integer lock;
- /**
- * Constructor
- *
- * @param tracker_servers tracker servers
- */
- public TrackerGroup(InetSocketAddress[] tracker_servers) {
- this.tracker_servers = tracker_servers;
- this.lock = new Integer(0);
- this.tracker_server_index = 0;
- }
-
- /**
- * return connected tracker server
- *
- * @return connected tracker server, null for fail
- */
- public TrackerServer getTrackerServer(int serverIndex) throws IOException {
- return new TrackerServer(this.tracker_servers[serverIndex]);
- }
-
- /**
- * return connected tracker server
- *
- * @return connected tracker server, null for fail
- */
- public TrackerServer getTrackerServer() throws IOException {
- int current_index;
-
- synchronized (this.lock) {
- this.tracker_server_index++;
- if (this.tracker_server_index >= this.tracker_servers.length) {
+ /**
+ * Constructor
+ *
+ * @param tracker_servers tracker servers
+ */
+ public TrackerGroup(InetSocketAddress[] tracker_servers) {
+ this.tracker_servers = tracker_servers;
+ this.lock = new Integer(0);
this.tracker_server_index = 0;
- }
-
- current_index = this.tracker_server_index;
}
- try {
- return this.getTrackerServer(current_index);
- } catch (IOException ex) {
- System.err.println("connect to server " + this.tracker_servers[current_index].getAddress().getHostAddress() + ":" + this.tracker_servers[current_index].getPort() + " fail");
- ex.printStackTrace(System.err);
+ /**
+ * return connected tracker server
+ *
+ * @return connected tracker server, null for fail
+ */
+ public TrackerServer getTrackerServer(int serverIndex) throws IOException {
+ return new TrackerServer(this.tracker_servers[serverIndex], serverIndex);
}
-
- for (int i = 0; i < this.tracker_servers.length; i++) {
- if (i == current_index) {
- continue;
- }
-
- try {
- TrackerServer trackerServer = this.getTrackerServer(i);
+ /**
+ * return connected tracker server
+ *
+ * @return connected tracker server, null for fail
+ */
+ public TrackerServer getTrackerServer() throws IOException {
+ int current_index;
synchronized (this.lock) {
- if (this.tracker_server_index == current_index) {
- this.tracker_server_index = i;
- }
+ this.tracker_server_index++;
+ if (this.tracker_server_index >= this.tracker_servers.length) {
+ this.tracker_server_index = 0;
+ }
+
+ current_index = this.tracker_server_index;
}
- return trackerServer;
- } catch (IOException ex) {
- System.err.println("connect to server " + this.tracker_servers[i].getAddress().getHostAddress() + ":" + this.tracker_servers[i].getPort() + " fail");
- ex.printStackTrace(System.err);
- }
+ try {
+ return this.getTrackerServer(current_index);
+ } catch (IOException ex) {
+ System.err.println("connect to server " + this.tracker_servers[current_index].getAddress().getHostAddress() + ":" + this.tracker_servers[current_index].getPort() + " fail");
+ ex.printStackTrace(System.err);
+ }
+
+ for (int i = 0; i < this.tracker_servers.length; i++) {
+ if (i == current_index) {
+ continue;
+ }
+
+ try {
+ TrackerServer trackerServer = this.getTrackerServer(i);
+
+ synchronized (this.lock) {
+ if (this.tracker_server_index == current_index) {
+ this.tracker_server_index = i;
+ }
+ }
+
+ return trackerServer;
+ } catch (IOException ex) {
+ System.err.println("connect to server " + this.tracker_servers[i].getAddress().getHostAddress() + ":" + this.tracker_servers[i].getPort() + " fail");
+ ex.printStackTrace(System.err);
+ }
+ }
+
+ return null;
}
- return null;
- }
+ public Object clone() {
+ InetSocketAddress[] trackerServers = new InetSocketAddress[this.tracker_servers.length];
+ for (int i = 0; i < trackerServers.length; i++) {
+ trackerServers[i] = new InetSocketAddress(this.tracker_servers[i].getAddress().getHostAddress(), this.tracker_servers[i].getPort());
+ }
- public Object clone() {
- InetSocketAddress[] trackerServers = new InetSocketAddress[this.tracker_servers.length];
- for (int i = 0; i < trackerServers.length; i++) {
- trackerServers[i] = new InetSocketAddress(this.tracker_servers[i].getAddress().getHostAddress(), this.tracker_servers[i].getPort());
+ return new TrackerGroup(trackerServers);
}
-
- return new TrackerGroup(trackerServers);
- }
}
diff --git a/src/main/java/org/csource/fastdfs/TrackerServer.java b/src/main/java/org/csource/fastdfs/TrackerServer.java
index a9875ed..6ff7834 100644
--- a/src/main/java/org/csource/fastdfs/TrackerServer.java
+++ b/src/main/java/org/csource/fastdfs/TrackerServer.java
@@ -25,11 +25,18 @@ import java.net.InetSocketAddress;
public class TrackerServer {
protected InetSocketAddress inetSockAddr;
+ protected int index;
+
public TrackerServer(InetSocketAddress inetSockAddr) throws IOException {
this.inetSockAddr = inetSockAddr;
}
+ public TrackerServer(InetSocketAddress inetSockAddr, int index) {
+ this.inetSockAddr = inetSockAddr;
+ this.index = index;
+ }
+
public Connection getConnection() throws MyException, IOException {
Connection connection;
if (ClientGlobal.g_connection_pool_enabled) {
@@ -48,4 +55,11 @@ public class TrackerServer {
return this.inetSockAddr;
}
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
}
diff --git a/src/test/java/org/csource/fastdfs/FdfsTest.java b/src/test/java/org/csource/fastdfs/FdfsTest.java
index 6a23441..74f3e6e 100644
--- a/src/test/java/org/csource/fastdfs/FdfsTest.java
+++ b/src/test/java/org/csource/fastdfs/FdfsTest.java
@@ -87,9 +87,9 @@ public class FdfsTest {
@Test
public void download() throws Exception {
- String[] uploadresult = {"group1", "M00/00/00/wKgBZV0phl2ASV1nAACk1tFxwrM3814331"};
+ String[] uploadresult = {"group1", "M00/00/00/J2fL12PVypeAWiGcAAM_gDeWVyw5817085"};
byte[] result = storageClient.download_file(uploadresult[0], uploadresult[1]);
- String local_filename = "build.PNG";
+ String local_filename = "commitment.d2f57e10.jpg";
writeByteToFile(result, local_filename);
File file = new File(local_filename);
Assert.assertTrue(file.isFile());
@@ -98,17 +98,17 @@ public class FdfsTest {
@Test
public void testUploadDownload() throws Exception {
NameValuePair[] metaList = new NameValuePair[1];
- String local_filename = "build.PNG";
+ String local_filename = "commitment.d2f57e10 (2).jpg";
metaList[0] = new NameValuePair("fileName", local_filename);
- File file = new File("C:/Users/chengdu/Desktop/build.PNG");
+ File file = new File("/Users/iyw/Downloads/commitment.d2f57e10 (2).jpg");
InputStream inputStream = new FileInputStream(file);
int length = inputStream.available();
byte[] bytes = new byte[length];
inputStream.read(bytes);
String[] result = storageClient.upload_file(bytes, null, metaList);
- Assert.assertTrue(storageClient.isConnected());
+ //Assert.assertTrue(storageClient.isConnected());
// pool testOnborrow isAvaliable
- Assert.assertTrue(storageClient.isAvaliable());
+ // Assert.assertTrue(storageClient.isAvaliable());
LOGGER.info("result {}", Arrays.asList(result));
byte[] resultbytes = storageClient.download_file(result[0], result[1]);
writeByteToFile(resultbytes, local_filename);