diff --git a/.gitignore b/.gitignore
index 76d9377..12cfc78 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@ target
*.conf
*.PNG
*.class
+*.swp
diff --git a/HISTORY b/HISTORY
index 64bd5a0..11fde87 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,7 +1,8 @@
-Version 1.31 2023-12-07
+Version 1.31 2023-12-13
* adapt to FastDFS server V6.11 for IPv6
you must upgrade your FastDFS server to V6.11 or higher version
+ * connect to storage server failover with multi IPs
Version 1.30 2023-01-29
* support tracker server fail over
diff --git a/fdfs_client.conf b/fdfs_client.conf
index 01debe5..b58567e 100644
--- a/fdfs_client.conf
+++ b/fdfs_client.conf
@@ -16,9 +16,13 @@ tracker_server = 10.0.11.247:22122
tracker_server = 10.0.11.248:22122
tracker_server = 10.0.11.249:22122
+# connect which ip address first for multi IPs of a storage server, value list:
+## tracker: connect to the ip address return by tracker server first
+## last-connected: connect to the ip address last connected first
+# default value is tracker
+connect_first_by = tracker
+
connection_pool.enabled = true
connection_pool.max_count_per_entry = 500
connection_pool.max_idle_time = 3600
connection_pool.max_wait_time_in_ms = 1000
-
-server_ipv6.enabled = false
\ No newline at end of file
diff --git a/src/main/java/org/csource/fastdfs/ClientGlobal.java b/src/main/java/org/csource/fastdfs/ClientGlobal.java
index 0cccf01..d454e22 100644
--- a/src/main/java/org/csource/fastdfs/ClientGlobal.java
+++ b/src/main/java/org/csource/fastdfs/ClientGlobal.java
@@ -42,7 +42,7 @@ public class ClientGlobal {
public static final String PROP_KEY_HTTP_SECRET_KEY = "fastdfs.http_secret_key";
public static final String PROP_KEY_HTTP_TRACKER_HTTP_PORT = "fastdfs.http_tracker_http_port";
public static final String PROP_KEY_TRACKER_SERVERS = "fastdfs.tracker_servers";
-
+ public static final String PROP_KEY_CONNECT_FIRST_BY = "fastdfs.connect_first_by";
public static final String PROP_KEY_CONNECTION_POOL_ENABLED = "fastdfs.connection_pool.enabled";
public static final String PROP_KEY_CONNECTION_POOL_MAX_COUNT_PER_ENTRY = "fastdfs.connection_pool.max_count_per_entry";
@@ -56,6 +56,9 @@ public class ClientGlobal {
public static final String DEFAULT_HTTP_SECRET_KEY = "FastDFS1234567890";
public static final int DEFAULT_HTTP_TRACKER_HTTP_PORT = 80;
+ public static final int CONNECT_FIRST_BY_TRACKER = 0;
+ public static final int CONNECT_FIRST_BY_LAST_CONNECTED = 1;
+
public static final boolean DEFAULT_CONNECTION_POOL_ENABLED = true;
public static final int DEFAULT_CONNECTION_POOL_MAX_COUNT_PER_ENTRY = 100;
public static final int DEFAULT_CONNECTION_POOL_MAX_IDLE_TIME = 3600 ;//second
@@ -67,6 +70,9 @@ public class ClientGlobal {
public static boolean g_anti_steal_token = DEFAULT_HTTP_ANTI_STEAL_TOKEN; //if anti-steal token
public static String g_secret_key = DEFAULT_HTTP_SECRET_KEY; //generage token secret key
public static int g_tracker_http_port = DEFAULT_HTTP_TRACKER_HTTP_PORT;
+ public static int g_connect_first_by = CONNECT_FIRST_BY_TRACKER;
+ public static boolean g_multi_storage_ips = false;
+ public static StorageAddressMap g_storages_address_map;
public static boolean g_connection_pool_enabled = DEFAULT_CONNECTION_POOL_ENABLED;
public static int g_connection_pool_max_count_per_entry = DEFAULT_CONNECTION_POOL_MAX_COUNT_PER_ENTRY;
@@ -78,6 +84,76 @@ public class ClientGlobal {
private ClientGlobal() {
}
+ private static void loadStoragsFromTracker() throws IOException, MyException {
+ TrackerClient tracker = new TrackerClient();
+ StringBuilder builder = tracker.fetchStorageIds();
+ if (builder.length() == 0) {
+ return;
+ }
+
+ System.out.println(builder.toString());
+
+ boolean without_port = true;
+ int count = 0;
+ String[] lines = builder.toString().split("\n");
+ String[] ipAddresses = new String[lines.length];
+ for (String line : lines) {
+ String[] cols = line.split(" ");
+ if (cols.length != 3) {
+ throw new MyException("invalid line: " + line);
+ }
+
+ String ipAddrs = cols[2];
+ if (ipAddrs.indexOf(',') > 0) {
+ ipAddresses[count++] = ipAddrs;
+ }
+ }
+
+ if (count == 0) {
+ return;
+ }
+
+ int startIndex;
+ if (ipAddresses[0].charAt(0) == '[') { //IPv6
+ if ((startIndex=ipAddresses[0].indexOf(']')) < 0) {
+ throw new MyException("invalid IPv6 address: " + ipAddresses[0]);
+ }
+ } else {
+ startIndex = 0;
+ }
+ if (ipAddresses[0].indexOf(':', startIndex) > 0) {
+ without_port = false;
+ }
+
+ g_multi_storage_ips = true;
+ g_storages_address_map = new StorageAddressMap(without_port);
+ if (without_port) {
+ for (String ipAddr: ipAddresses) {
+ if (ipAddr.charAt(0) == '[') { //IPv6
+ ipAddr = ipAddr.substring(1, ipAddr.length() - 1);
+ }
+ String[] cols = ipAddr.split(",");
+ g_storages_address_map.puts(cols[0], cols[1]);
+ }
+ } else {
+ for (String ipPort: ipAddresses) {
+ int colonIndex = ipPort.lastIndexOf(':');
+ if (colonIndex < 0) {
+ throw new MyException("invalid ip and port: " + ipPort);
+ }
+
+ String ipAddr = ipPort.substring(0, colonIndex);
+ int port = Integer.parseInt(ipPort.substring(colonIndex + 1));
+
+ if (ipAddr.charAt(0) == '[') { //IPv6
+ ipAddr = ipAddr.substring(1, ipAddr.length() - 1);
+ }
+ String[] cols = ipAddr.split(",");
+ g_storages_address_map.puts(cols[0], cols[1], port);
+ }
+ }
+ }
+
/**
* load global variables
*
@@ -114,11 +190,11 @@ public class ClientGlobal {
InetSocketAddress[] tracker_servers = new InetSocketAddress[szTrackerServers.length];
for (int i = 0; i < szTrackerServers.length; i++) {
- if(szTrackerServers[i].contains("[")){
+ if (szTrackerServers[i].contains("[")) {
parts = new String[2];
parts[0] = szTrackerServers[i].substring(1, szTrackerServers[i].indexOf("]"));
parts[1] = szTrackerServers[i].substring(szTrackerServers[i].lastIndexOf(":") + 1);
- }else {
+ } else {
parts = szTrackerServers[i].split("\\:", 2);
}
@@ -130,6 +206,11 @@ public class ClientGlobal {
}
g_tracker_group = new TrackerGroup(tracker_servers);
+ String connect_first_by = iniReader.getStrValue("connect_first_by");
+ if (connect_first_by != null && connect_first_by.equalsIgnoreCase("last-connected")) {
+ g_connect_first_by = CONNECT_FIRST_BY_LAST_CONNECTED;
+ }
+
g_tracker_http_port = iniReader.getIntValue("http.tracker_http_port", 80);
g_anti_steal_token = iniReader.getBoolValue("http.anti_steal_token", false);
if (g_anti_steal_token) {
@@ -146,6 +227,8 @@ public class ClientGlobal {
if (g_connection_pool_max_wait_time_in_ms < 0) {
g_connection_pool_max_wait_time_in_ms = DEFAULT_CONNECTION_POOL_MAX_WAIT_TIME_IN_MS;
}
+
+ loadStoragsFromTracker();
}
/**
@@ -183,6 +266,8 @@ public class ClientGlobal {
String httpAntiStealTokenConf = props.getProperty(PROP_KEY_HTTP_ANTI_STEAL_TOKEN);
String httpSecretKeyConf = props.getProperty(PROP_KEY_HTTP_SECRET_KEY);
String httpTrackerHttpPortConf = props.getProperty(PROP_KEY_HTTP_TRACKER_HTTP_PORT);
+
+ String connectFirstBy = props.getProperty(PROP_KEY_CONNECT_FIRST_BY);
String poolEnabled = props.getProperty(PROP_KEY_CONNECTION_POOL_ENABLED);
String poolMaxCountPerEntry = props.getProperty(PROP_KEY_CONNECTION_POOL_MAX_COUNT_PER_ENTRY);
String poolMaxIdleTime = props.getProperty(PROP_KEY_CONNECTION_POOL_MAX_IDLE_TIME);
@@ -205,6 +290,10 @@ public class ClientGlobal {
if (httpTrackerHttpPortConf != null && httpTrackerHttpPortConf.trim().length() != 0) {
g_tracker_http_port = Integer.parseInt(httpTrackerHttpPortConf);
}
+
+ if (connectFirstBy != null && connectFirstBy.equalsIgnoreCase("last-connected")) {
+ g_connect_first_by = CONNECT_FIRST_BY_LAST_CONNECTED;
+ }
if (poolEnabled != null && poolEnabled.trim().length() != 0) {
g_connection_pool_enabled = Boolean.parseBoolean(poolEnabled);
}
@@ -217,6 +306,8 @@ public class ClientGlobal {
if (poolMaxWaitTimeInMS != null && poolMaxWaitTimeInMS.trim().length() != 0) {
g_connection_pool_max_wait_time_in_ms = Integer.parseInt(poolMaxWaitTimeInMS);
}
+
+ loadStoragsFromTracker();
}
/**
@@ -360,6 +451,8 @@ public class ClientGlobal {
+ "\n g_anti_steal_token = " + g_anti_steal_token
+ "\n g_secret_key = " + g_secret_key
+ "\n g_tracker_http_port = " + g_tracker_http_port
+ + "\n g_multi_storage_ips = " + g_multi_storage_ips
+ + "\n g_connect_first_by = " + (g_connect_first_by == CONNECT_FIRST_BY_TRACKER ? "tracker" : "last-connected")
+ "\n g_connection_pool_enabled = " + g_connection_pool_enabled
+ "\n g_connection_pool_max_count_per_entry = " + g_connection_pool_max_count_per_entry
+ "\n g_connection_pool_max_idle_time(ms) = " + g_connection_pool_max_idle_time
diff --git a/src/main/java/org/csource/fastdfs/ProtoCommon.java b/src/main/java/org/csource/fastdfs/ProtoCommon.java
index a8a4de7..b13be40 100644
--- a/src/main/java/org/csource/fastdfs/ProtoCommon.java
+++ b/src/main/java/org/csource/fastdfs/ProtoCommon.java
@@ -26,6 +26,7 @@ import java.util.Arrays;
*/
public class ProtoCommon {
public static final byte FDFS_PROTO_CMD_QUIT = 82;
+ public static final byte TRACKER_PROTO_CMD_FETCH_STORAGE_IDS = 69;
public static final byte TRACKER_PROTO_CMD_SERVER_LIST_GROUP = 91;
public static final byte TRACKER_PROTO_CMD_SERVER_LIST_STORAGE = 92;
public static final byte TRACKER_PROTO_CMD_SERVER_DELETE_STORAGE = 93;
@@ -310,6 +311,23 @@ public class ProtoCommon {
return headerInfo.errno == 0 ? true : false;
}
+ /**
+ * int convert to buff (big-endian)
+ *
+ * @param n int number
+ * @return 4 bytes buff
+ */
+ public static byte[] int2buff(int n) {
+ byte[] bs;
+
+ bs = new byte[4];
+ bs[0] = (byte) ((n >> 24) & 0xFF);
+ bs[1] = (byte) ((n >> 16) & 0xFF);
+ bs[2] = (byte) ((n >> 8) & 0xFF);
+ bs[3] = (byte) (n & 0xFF);
+ return bs;
+ }
+
/**
* long convert to buff (big-endian)
*
@@ -317,19 +335,18 @@ public class ProtoCommon {
* @return 8 bytes buff
*/
public static byte[] long2buff(long n) {
- byte[] bs;
+ byte[] bs;
- bs = new byte[8];
- bs[0] = (byte) ((n >> 56) & 0xFF);
- bs[1] = (byte) ((n >> 48) & 0xFF);
- bs[2] = (byte) ((n >> 40) & 0xFF);
- bs[3] = (byte) ((n >> 32) & 0xFF);
- bs[4] = (byte) ((n >> 24) & 0xFF);
- bs[5] = (byte) ((n >> 16) & 0xFF);
- bs[6] = (byte) ((n >> 8) & 0xFF);
- bs[7] = (byte) (n & 0xFF);
-
- return bs;
+ bs = new byte[8];
+ bs[0] = (byte) ((n >> 56) & 0xFF);
+ bs[1] = (byte) ((n >> 48) & 0xFF);
+ bs[2] = (byte) ((n >> 40) & 0xFF);
+ bs[3] = (byte) ((n >> 32) & 0xFF);
+ bs[4] = (byte) ((n >> 24) & 0xFF);
+ bs[5] = (byte) ((n >> 16) & 0xFF);
+ bs[6] = (byte) ((n >> 8) & 0xFF);
+ bs[7] = (byte) (n & 0xFF);
+ return bs;
}
/**
diff --git a/src/main/java/org/csource/fastdfs/StorageAddressMap.java b/src/main/java/org/csource/fastdfs/StorageAddressMap.java
new file mode 100644
index 0000000..8c53370
--- /dev/null
+++ b/src/main/java/org/csource/fastdfs/StorageAddressMap.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (C) 2023 Happy Fish / YuQing
+ *
+ * FastDFS Java Client may be copied only under the terms of the GNU Lesser
+ * General Public License (LGPL).
+ * Please visit the FastDFS Home Page https://github.com/happyfish100/fastdfs for more detail.
+ */
+
+package org.csource.fastdfs;
+
+import java.util.HashMap;
+import java.net.InetSocketAddress;
+
+/**
+ * Storage Server Address Map
+ *
+ * @author Happy Fish / YuQing
+ * @version Version 1.31
+ */
+public class StorageAddressMap {
+
+ protected boolean without_port;
+ protected HashMap storages;
+
+ public StorageAddressMap(boolean without_port) {
+ this.without_port = without_port;
+ this.storages = new HashMap();
+ }
+
+ protected String getKey(String ipAddr, int port) {
+ return ipAddr + "@" + port;
+ }
+
+ public void puts(String srcIpAddr, String destIpAddr, int port) {
+ storages.put(this.getKey(srcIpAddr, port),
+ new InetSocketAddress(destIpAddr, port));
+ storages.put(this.getKey(destIpAddr, port),
+ new InetSocketAddress(srcIpAddr, port));
+ }
+
+ public void puts(String srcIpAddr, String destIpAddr) {
+ storages.put(srcIpAddr, new InetSocketAddress(destIpAddr, 0));
+ storages.put(destIpAddr, new InetSocketAddress(srcIpAddr, 0));
+ }
+
+ public InetSocketAddress get(String ipAddr, int port) {
+ if (this.without_port) {
+ InetSocketAddress sockAddr;
+ if ((sockAddr=storages.get(ipAddr)) == null) {
+ return null;
+ }
+
+ return new InetSocketAddress(sockAddr.getAddress(), port);
+ } else {
+ return storages.get(this.getKey(ipAddr, port));
+ }
+ }
+
+ public InetSocketAddress get(InetSocketAddress sockAddr) {
+ return this.get(sockAddr.getAddress().getHostAddress(), sockAddr.getPort());
+ }
+}
diff --git a/src/main/java/org/csource/fastdfs/StorageClient.java b/src/main/java/org/csource/fastdfs/StorageClient.java
index 5f0d61e..9c608ee 100644
--- a/src/main/java/org/csource/fastdfs/StorageClient.java
+++ b/src/main/java/org/csource/fastdfs/StorageClient.java
@@ -847,7 +847,6 @@ public class StorageClient {
throw ex;
} finally {
releaseConnection(connection, bNewStorageServer);
-
}
}
diff --git a/src/main/java/org/csource/fastdfs/StorageServer.java b/src/main/java/org/csource/fastdfs/StorageServer.java
index 1811c19..2233d10 100644
--- a/src/main/java/org/csource/fastdfs/StorageServer.java
+++ b/src/main/java/org/csource/fastdfs/StorageServer.java
@@ -9,6 +9,9 @@
package org.csource.fastdfs;
import java.io.IOException;
+import java.util.Hashtable;
+import org.csource.common.MyException;
+import org.csource.fastdfs.pool.Connection;
import java.net.InetSocketAddress;
/**
@@ -18,40 +21,112 @@ import java.net.InetSocketAddress;
* @version Version 1.11
*/
public class StorageServer extends TrackerServer {
- protected int store_path_index = 0;
+ protected int store_path_index = 0;
- /**
- * Constructor
- *
- * @param ip_addr the ip address of storage server
- * @param port the port of storage server
- * @param store_path the store path index on the storage server
- */
- public StorageServer(String ip_addr, int port, int store_path) throws IOException {
- super(new InetSocketAddress(ip_addr, port));
- this.store_path_index = store_path;
- }
+ protected static Hashtable sockAddressCache = new Hashtable();
- /**
- * Constructor
- *
- * @param ip_addr the ip address of storage server
- * @param port the port of storage server
- * @param store_path the store path index on the storage server
- */
- public StorageServer(String ip_addr, int port, byte store_path) throws IOException {
- super(new InetSocketAddress(ip_addr, port));
- if (store_path < 0) {
- this.store_path_index = 256 + store_path;
- } else {
- this.store_path_index = store_path;
+ /**
+ * Constructor
+ *
+ * @param ip_addr the ip address of storage server
+ * @param port the port of storage server
+ * @param store_path the store path index on the storage server
+ */
+ public StorageServer(String ip_addr, int port, int store_path) throws IOException {
+ super(new InetSocketAddress(ip_addr, port));
+ this.store_path_index = store_path;
}
- }
- /**
- * @return the store path index on the storage server
- */
- public int getStorePathIndex() {
- return this.store_path_index;
- }
+ /**
+ * Constructor
+ *
+ * @param ip_addr the ip address of storage server
+ * @param port the port of storage server
+ * @param store_path the store path index on the storage server
+ */
+ public StorageServer(String ip_addr, int port, byte store_path) throws IOException {
+ super(new InetSocketAddress(ip_addr, port));
+ if (store_path < 0) {
+ this.store_path_index = 256 + store_path;
+ } else {
+ this.store_path_index = store_path;
+ }
+ }
+
+ /**
+ * @return the store path index on the storage server
+ */
+ public int getStorePathIndex() {
+ return this.store_path_index;
+ }
+
+ public Connection getConnection() throws MyException, IOException {
+ Connection connection;
+ InetSocketAddress sockAddr;
+ MyException myException = null;
+ IOException ioException = null;
+
+ if (!ClientGlobal.g_multi_storage_ips) {
+ return super.getConnection();
+ }
+
+ if (ClientGlobal.g_connect_first_by == ClientGlobal.CONNECT_FIRST_BY_TRACKER) {
+ try {
+ if ((connection=super.getConnection()) != null) {
+ return connection;
+ }
+ } catch (MyException ex1) {
+ myException = ex1;
+ } catch (IOException ex2) {
+ ioException = ex2;
+ }
+
+ sockAddr = ClientGlobal.g_storages_address_map.get(this.inetSockAddr);
+ if (sockAddr != null) {
+ return super.getConnection(sockAddr);
+ } else if (myException != null) {
+ throw myException;
+ } else if (ioException != null) {
+ throw ioException;
+ }
+ } else {
+ String key = this.inetSockAddr.getAddress().getHostAddress() +
+ "@" + this.inetSockAddr.getPort();
+ sockAddr = sockAddressCache.get(key);
+ try {
+ if (sockAddr == null) {
+ sockAddr = this.inetSockAddr;
+ if ((connection=super.getConnection(sockAddr)) != null) {
+ sockAddressCache.put(key, sockAddr);
+ return connection;
+ }
+ } else {
+ if ((connection=super.getConnection(sockAddr)) != null) {
+ return connection;
+ }
+ }
+ } catch (MyException ex1) {
+ myException = ex1;
+ } catch (IOException ex2) {
+ ioException = ex2;
+ }
+
+ //retry another ip address
+ if ((sockAddr=ClientGlobal.g_storages_address_map.get(sockAddr)) == null) {
+ if (myException != null) {
+ throw myException;
+ } else if (ioException != null) {
+ throw ioException;
+ }
+ return null;
+ }
+
+ if ((connection=super.getConnection(sockAddr)) != null) {
+ sockAddressCache.put(key, sockAddr);
+ return connection;
+ }
+ }
+
+ return null;
+ }
}
diff --git a/src/main/java/org/csource/fastdfs/TrackerClient.java b/src/main/java/org/csource/fastdfs/TrackerClient.java
index 8b8bd56..29312cb 100644
--- a/src/main/java/org/csource/fastdfs/TrackerClient.java
+++ b/src/main/java/org/csource/fastdfs/TrackerClient.java
@@ -735,8 +735,9 @@ public class TrackerClient {
* @param storageIpAddr the storage server ip address
* @return true for success, false for fail
*/
- public boolean deleteStorage(TrackerGroup trackerGroup,
- String groupName, String storageIpAddr) throws IOException, MyException {
+ public boolean deleteStorage(TrackerGroup trackerGroup, String groupName,
+ String storageIpAddr) throws IOException, MyException
+ {
int serverIndex;
int notFoundCount;
TrackerServer trackerServer;
@@ -805,4 +806,78 @@ public class TrackerClient {
return this.errno == 0;
}
+
+ /**
+ * query storage server to upload file
+ *
+ * @param trackerServer the tracker server
+ * @param groupName the group name to upload file to, can be empty
+ * @return storage server object, return null if fail
+ */
+ public StringBuilder fetchStorageIds() throws IOException, MyException {
+ byte[] header;
+ int offset = 0;
+ int length;
+ int total_count;
+ int current_count;
+
+ Connection connection = getConnection(null);
+ try {
+ OutputStream out = connection.getOutputStream();
+ StringBuilder builder = new StringBuilder();
+
+ header = ProtoCommon.packHeader(ProtoCommon.TRACKER_PROTO_CMD_FETCH_STORAGE_IDS, 5, (byte)0);
+ byte[] wholePkg = new byte[header.length + 5];
+ System.arraycopy(header, 0, wholePkg, 0, header.length);
+ wholePkg[wholePkg.length - 1] = 1;
+ do {
+ byte[] bs = ProtoCommon.int2buff(offset);
+ System.arraycopy(bs, 0, wholePkg, header.length, bs.length);
+ out.write(wholePkg);
+
+ ProtoCommon.RecvPackageInfo pkgInfo = ProtoCommon.recvPackage(
+ connection.getInputStream(),
+ ProtoCommon.TRACKER_PROTO_CMD_RESP, -1);
+ this.errno = pkgInfo.errno;
+ if (pkgInfo.errno != 0) {
+ return null;
+ }
+
+ if (pkgInfo.body.length < 8) {
+ throw new MyException("invalid body length: " + pkgInfo.body.length);
+ }
+
+ total_count = ProtoCommon.buff2int(pkgInfo.body, 0);
+ current_count = ProtoCommon.buff2int(pkgInfo.body, 4);
+ if (current_count < 0) {
+ throw new MyException("invalid current count: " + current_count);
+ }
+
+ length = pkgInfo.body.length - 8;
+ if (length == 0) {
+ break;
+ }
+
+ bs = new byte[length];
+ System.arraycopy(pkgInfo.body, 8, bs, 0, length);
+ builder.append(new String(bs, ClientGlobal.g_charset));
+
+ offset += current_count;
+ } while (offset < total_count);
+
+ return builder;
+ } catch (IOException e) {
+ try {
+ connection.close();
+ } finally {
+ connection = null;
+ }
+ throw e;
+ } finally {
+ if (connection != null) {
+ connection.release();
+ }
+ }
+ }
+
}
diff --git a/src/main/java/org/csource/fastdfs/TrackerServer.java b/src/main/java/org/csource/fastdfs/TrackerServer.java
index 6ff7834..1754e03 100644
--- a/src/main/java/org/csource/fastdfs/TrackerServer.java
+++ b/src/main/java/org/csource/fastdfs/TrackerServer.java
@@ -37,15 +37,20 @@ public class TrackerServer {
this.index = index;
}
- public Connection getConnection() throws MyException, IOException {
+ protected Connection getConnection(InetSocketAddress sockAddr) throws MyException, IOException {
Connection connection;
if (ClientGlobal.g_connection_pool_enabled) {
- connection = ConnectionPool.getConnection(this.inetSockAddr);
+ connection = ConnectionPool.getConnection(sockAddr);
} else {
- connection = ConnectionFactory.create(this.inetSockAddr);
+ connection = ConnectionFactory.create(sockAddr);
}
return connection;
}
+
+ public Connection getConnection() throws MyException, IOException {
+ return this.getConnection(this.inetSockAddr);
+ }
+
/**
* get the server info
*
diff --git a/src/main/resources/fastdfs-client.properties.sample b/src/main/resources/fastdfs-client.properties.sample
index cd1fcf0..77e6d95 100644
--- a/src/main/resources/fastdfs-client.properties.sample
+++ b/src/main/resources/fastdfs-client.properties.sample
@@ -18,6 +18,14 @@ fastdfs.http_tracker_http_port = 80
#
fastdfs.tracker_servers = 185.245.40.70:22122
+
+# connect which ip address first for multi IPs of a storage server, value list:
+## tracker: connect to the ip address return by tracker server first
+## last-connected: connect to the ip address last connected first
+# default value is tracker
+fastdfs.connect_first_by = tracker
+
+
## Whether to open the connection pool, if not, create a new connection every time
fastdfs.connection_pool.enabled = true
diff --git a/src/main/resources/fdfs_client.conf.sample b/src/main/resources/fdfs_client.conf.sample
index cd90a5a..142f089 100644
--- a/src/main/resources/fdfs_client.conf.sample
+++ b/src/main/resources/fdfs_client.conf.sample
@@ -15,6 +15,14 @@ http.secret_key = FastDFS1234567890
tracker_server = 10.0.11.243:22122
tracker_server = 10.0.11.244:22122
+
+# connect which ip address first for multi IPs of a storage server, value list:
+## tracker: connect to the ip address return by tracker server first
+## last-connected: connect to the ip address last connected first
+# default value is tracker
+connect_first_by = tracker
+
+
connection_pool.enabled = true
connection_pool.max_count_per_entry = 500
connection_pool.max_idle_time = 3600