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);