diff --git a/src/main/java/org/csource/fastdfs/ClientGlobal.java b/src/main/java/org/csource/fastdfs/ClientGlobal.java index 382e2a5..0fc3450 100644 --- a/src/main/java/org/csource/fastdfs/ClientGlobal.java +++ b/src/main/java/org/csource/fastdfs/ClientGlobal.java @@ -48,6 +48,8 @@ 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 String PROP_KEY_FAIL_OVER_RETRY_COUNT = "fastdfs.fail_over_retry_count"; + public static final int DEFAULT_CONNECT_TIMEOUT = 5; //second public static final int DEFAULT_NETWORK_TIMEOUT = 30; //second @@ -61,6 +63,8 @@ public class ClientGlobal { public static final int DEFAULT_CONNECTION_POOL_MAX_IDLE_TIME = 3600 ;//second public static final int DEFAULT_CONNECTION_POOL_MAX_WAIT_TIME_IN_MS = 1000 ;//millisecond + public static final int DEFAULT_FAIL_OVER_RETRY_COUNT = 1; + public static int g_connect_timeout = DEFAULT_CONNECT_TIMEOUT * 1000; //millisecond public static int g_network_timeout = DEFAULT_NETWORK_TIMEOUT * 1000; //millisecond public static String g_charset = DEFAULT_CHARSET; @@ -73,6 +77,8 @@ public class ClientGlobal { public static int g_connection_pool_max_idle_time = DEFAULT_CONNECTION_POOL_MAX_IDLE_TIME * 1000; //millisecond public static int g_connection_pool_max_wait_time_in_ms = DEFAULT_CONNECTION_POOL_MAX_WAIT_TIME_IN_MS; //millisecond + public static int g_fail_over_retry_count = DEFAULT_FAIL_OVER_RETRY_COUNT ;//get connection retry count when fail + public static TrackerGroup g_tracker_group; private ClientGlobal() { @@ -139,6 +145,7 @@ 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; } + g_fail_over_retry_count = iniReader.getIntValue("fail_over_retry_count", DEFAULT_FAIL_OVER_RETRY_COUNT); } /** @@ -180,6 +187,7 @@ 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); + String failOverRetryCount = props.getProperty(PROP_KEY_FAIL_OVER_RETRY_COUNT); if (connectTimeoutInSecondsConf != null && connectTimeoutInSecondsConf.trim().length() != 0) { g_connect_timeout = Integer.parseInt(connectTimeoutInSecondsConf.trim()) * 1000; @@ -211,6 +219,9 @@ public class ClientGlobal { if (poolMaxWaitTimeInMS != null && poolMaxWaitTimeInMS.trim().length() != 0) { g_connection_pool_max_wait_time_in_ms = Integer.parseInt(poolMaxWaitTimeInMS); } + if (failOverRetryCount != null && failOverRetryCount.trim().length() != 0) { + g_fail_over_retry_count = Integer.parseInt(failOverRetryCount); + } } /** @@ -352,6 +363,7 @@ public class ClientGlobal { + "\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 + "\n g_connection_pool_max_wait_time_in_ms(ms) = " + g_connection_pool_max_wait_time_in_ms + + "\n g_fail_over_retry_count = " + g_fail_over_retry_count + "\n trackerServers = " + trackerServers + "\n}"; } diff --git a/src/main/java/org/csource/fastdfs/StorageClient.java b/src/main/java/org/csource/fastdfs/StorageClient.java index 89f2798..5e11726 100644 --- a/src/main/java/org/csource/fastdfs/StorageClient.java +++ b/src/main/java/org/csource/fastdfs/StorageClient.java @@ -28,6 +28,7 @@ public class StorageClient { public final static Base64 base64 = new Base64('-', '_', '.', 0); protected TrackerServer trackerServer; protected StorageServer storageServer; + protected TrackerClient trackerClient; protected byte errno; /** @@ -731,7 +732,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..5d4e4fe 100644 --- a/src/main/java/org/csource/fastdfs/TrackerClient.java +++ b/src/main/java/org/csource/fastdfs/TrackerClient.java @@ -71,6 +71,45 @@ public class TrackerClient { return this.getStoreStorage(trackerServer, groupName); } + public Connection getConnection(TrackerServer trackerServer) throws IOException, MyException { + if (ClientGlobal.g_fail_over_retry_count > 0) { + int retryCount = 0; + do { + try { + trackerServer = getTrackerServer(); + if (trackerServer == null) { + throw new MyException("tracker server is empty!"); + } + return trackerServer.getConnection(); + } catch (IOException e) { + if (retryCount <= ClientGlobal.g_fail_over_retry_count) { + //allow retry ignore exception + System.err.println("trackerServer get connection error, get connection from next tracker, emsg:" + e.getMessage()); + } else { + throw e; + } + } catch (MyException e) { + if (retryCount <= ClientGlobal.g_fail_over_retry_count) { + System.err.println("trackerServer get connection error, get connection from next tracker, emsg:" + e.getMessage()); + //allow retry ignore exception + } else { + throw e; + } + } + } while (retryCount++ <= ClientGlobal.g_fail_over_retry_count); + } else { + if (trackerServer == null) { + trackerServer = getTrackerServer(); + if (trackerServer == null) { + throw new MyException("tracker server is empty!"); + } + } + trackerServer.getConnection(); + } + return null; + } + + /** * query storage server to upload file * @@ -85,12 +124,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 +204,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 +368,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 +490,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 +556,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..d9ae475 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]); } - - 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/resources/fastdfs-client.properties.sample b/src/main/resources/fastdfs-client.properties.sample index dd33b50..32f5a87 100644 --- a/src/main/resources/fastdfs-client.properties.sample +++ b/src/main/resources/fastdfs-client.properties.sample @@ -21,4 +21,6 @@ fastdfs.connection_pool.max_count_per_entry = 500 fastdfs.connection_pool.max_idle_time = 3600 ## Maximum waiting time when the maximum number of connections is reached, unit: millisecond, default value is 1000 -fastdfs.connection_pool.max_wait_time_in_ms = 1000 \ No newline at end of file +fastdfs.connection_pool.max_wait_time_in_ms = 1000 + +fastdfs.fail_over_retry_count = 0 \ No newline at end of file diff --git a/src/main/resources/fdfs_client.conf.sample b/src/main/resources/fdfs_client.conf.sample index 741218c..7db129b 100644 --- a/src/main/resources/fdfs_client.conf.sample +++ b/src/main/resources/fdfs_client.conf.sample @@ -11,4 +11,6 @@ tracker_server = 10.0.11.244:22122 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 \ No newline at end of file +connection_pool.max_wait_time_in_ms = 1000 + +fail_over_retry_count = 1 \ No newline at end of file diff --git a/src/test/java/org/csource/fastdfs/FdfsTest.java b/src/test/java/org/csource/fastdfs/FdfsTest.java index 6a23441..4ad05f0 100644 --- a/src/test/java/org/csource/fastdfs/FdfsTest.java +++ b/src/test/java/org/csource/fastdfs/FdfsTest.java @@ -98,9 +98,9 @@ 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];