Repository: zookeeper Updated Branches: refs/heads/branch-3.4 3a5381499 -> 159ead6f1
ZOOKEEPER-2691: recreateSocketAddresses may recreate the unreachable ⦠â¦IP address Author: Jiang Jiafu <[email protected]> Author: JiangJiafu <[email protected]> Reviewers: Michael Han <[email protected]>, Abraham Fine <[email protected]>, Edward Ribeiro <[email protected]> Closes #173 from JiangJiafu/ZOOKEEPER-2691 Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/159ead6f Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/159ead6f Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/159ead6f Branch: refs/heads/branch-3.4 Commit: 159ead6f1d503c635957b7b92d122043321d8451 Parents: 3a53814 Author: Jiang Jiafu <[email protected]> Authored: Fri May 26 15:29:16 2017 -0700 Committer: Michael Han <[email protected]> Committed: Fri May 26 15:29:16 2017 -0700 ---------------------------------------------------------------------- .../content/xdocs/zookeeperAdmin.xml | 20 +++++++ .../zookeeper/server/quorum/QuorumPeer.java | 63 ++++++++++++++++---- 2 files changed, 73 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/zookeeper/blob/159ead6f/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml ---------------------------------------------------------------------- diff --git a/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml b/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml index 27060e0..1faa773 100644 --- a/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml +++ b/src/docs/src/documentation/content/xdocs/zookeeperAdmin.xml @@ -1076,6 +1076,26 @@ server.3=zoo3:2888:3888</programlisting> </listitem> </varlistentry> + <varlistentry> + <term>zookeeper.ipReachableTimeout</term> + + <listitem> + <para>(Java system property: <emphasis + role="bold">zookeeper.ipReachableTimeout</emphasis>)</para> + + <para><emphasis role="bold">New in 3.4.11:</emphasis> + Set this timeout value for IP addresses reachable checking when hostname is resolved, as mesured in + milliseconds. + By default, ZooKeeper will use the first IP address of the hostname(without any reachable checking). + When zookeeper.ipReachableTimeout is set(larger than 0), ZooKeeper will will try to pick up the first + IP address which is reachable. This is done by calling Java API InetAddress.isReachable(long timeout) + function, in which this timeout value is used. If none of such reachable IP address can be found, the + first IP address of the hostname will be used anyway. + </para> + + </listitem> + </varlistentry> + </variablelist> <para></para> </section> http://git-wip-us.apache.org/repos/asf/zookeeper/blob/159ead6f/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java ---------------------------------------------------------------------- diff --git a/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java b/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java index 05d0a1b..53f6077 100644 --- a/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java +++ b/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeer.java @@ -138,19 +138,19 @@ public class QuorumPeer extends ZooKeeperThread implements QuorumStats.Provider public QuorumServer(long id, String hostname, Integer port, Integer electionPort, LearnerType type) { - this.id = id; - this.hostname=hostname; - if (port!=null){ + this.id = id; + this.hostname=hostname; + if (port!=null){ this.port=port; - } - if (electionPort!=null){ + } + if (electionPort!=null){ this.electionPort=electionPort; - } - if (type!=null){ + } + if (type!=null){ this.type = type; - } - this.recreateSocketAddresses(); } + this.recreateSocketAddresses(); + } /** * Performs a DNS lookup of hostname and (re)creates the this.addr and @@ -164,7 +164,23 @@ public class QuorumPeer extends ZooKeeperThread implements QuorumStats.Provider public void recreateSocketAddresses() { InetAddress address = null; try { - address = InetAddress.getByName(this.hostname); + // the time, in milliseconds, before {@link InetAddress#isReachable} aborts + // in {@link #getReachableAddress}. + int ipReachableTimeout = 0; + String ipReachableValue = System.getProperty("zookeeper.ipReachableTimeout"); + if (ipReachableValue != null) { + try { + ipReachableTimeout = Integer.parseInt(ipReachableValue); + } catch (NumberFormatException e) { + LOG.error("{} is not a valid number", ipReachableValue); + } + } + // zookeeper.ipReachableTimeout is not defined + if (ipReachableTimeout <= 0) { + address = InetAddress.getByName(this.hostname); + } else { + address = getReachableAddress(this.hostname, ipReachableTimeout); + } LOG.info("Resolved hostname: {} to address: {}", this.hostname, address); this.addr = new InetSocketAddress(address, this.port); if (this.electionPort > 0){ @@ -186,6 +202,33 @@ public class QuorumPeer extends ZooKeeperThread implements QuorumStats.Provider } } + /** + * Resolve the hostname to IP addresses, and find one reachable address. + * + * @param hostname the name of the host + * @param timeout the time, in milliseconds, before {@link InetAddress#isReachable} + * aborts + * @return a reachable IP address. If no such IP address can be found, + * just return the first IP address of the hostname. + * + * @exception UnknownHostException + */ + public InetAddress getReachableAddress(String hostname, int timeout) + throws UnknownHostException { + InetAddress[] addresses = InetAddress.getAllByName(hostname); + for (InetAddress a : addresses) { + try { + if (a.isReachable(timeout)) { + return a; + } + } catch (IOException e) { + LOG.warn("IP address {} is unreachable", a); + } + } + // All the IP addresses are unreachable, just return the first one. + return addresses[0]; + } + public InetSocketAddress addr; public InetSocketAddress electionAddr;
