zookeeper-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "ASF GitHub Bot (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (ZOOKEEPER-2184) Zookeeper Client should re-resolve hosts when connection attempts fail
Date Mon, 16 Jan 2017 06:29:26 GMT

    [ https://issues.apache.org/jira/browse/ZOOKEEPER-2184?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15823523#comment-15823523
] 

ASF GitHub Bot commented on ZOOKEEPER-2184:
-------------------------------------------

Github user hanm commented on a diff in the pull request:

    https://github.com/apache/zookeeper/pull/150#discussion_r96170041
  
    --- Diff: src/java/main/org/apache/zookeeper/client/StaticHostProvider.java ---
    @@ -87,15 +73,69 @@ public StaticHostProvider(Collection<InetSocketAddress> serverAddresses)
             Collections.shuffle(this.serverAddresses);
         }
     
    +    /**
    +     * In Java 7, we have a method getHostString, but earlier versions do not support
it.
    +     * This method is to provide a replacement for InetSocketAddress.getHostString().
    +     *
    +     * It evaluates to a hostname if one is available and otherwise it returns the
    +     * string representation of the IP address.
    +     *
    +     * @param addr
    +     * @return Hostname string of address parameter
    +     */
    +    private String getHostString(InetSocketAddress addr) {
    +        String hostString;
    +        InetAddress ia = addr.getAddress();
    +
    +        if (ia != null) {
    +            // If the string starts with '/', then it has no hostname
    +            // and we want to avoid the reverse lookup, so we return
    +            // the string representation of the address.
    +            if (ia.toString().startsWith("/")) {
    +                hostString = ia.getHostAddress();
    +            } else {
    +                hostString = addr.getHostName();
    +            }
    +        } else {
    +            // According to the Java 6 documentation, if the hostname is
    +            // unresolved, then the string before the colon is the hostname.
    +            String addrString = addr.toString();
    +            hostString = addrString.substring(0, addrString.lastIndexOf(':'));
    +        }
    +
    +        return hostString;
    +    }
    +
         public int size() {
             return serverAddresses.size();
         }
     
         public InetSocketAddress next(long spinDelay) {
    -        ++currentIndex;
    -        if (currentIndex == serverAddresses.size()) {
    -            currentIndex = 0;
    +        // Handle possible connection error by re-resolving hostname if possible
    +        if (!connectedSinceNext) {
    +            InetSocketAddress curAddr = serverAddresses.get(currentIndex);
    +            if (!curAddr.getHostString().equals(curAddr.getAddress().getHostAddress()))
{
    +                try {
    +                    int thePort = curAddr.getPort();
    +                    InetAddress resolvedAddresses[] = InetAddress.getAllByName(getHostString(curAddr));
    +                    if (resolvedAddresses.length == 1) {
    +                        serverAddresses.set(currentIndex, new InetSocketAddress(resolvedAddresses[0],
thePort));
    +                    } else {
    +                        serverAddresses.remove(currentIndex);
    +                        for (InetAddress resolvedAddress : resolvedAddresses) {
    +                            InetSocketAddress newAddr = new InetSocketAddress(resolvedAddress,
thePort);
    +                            if (!serverAddresses.contains(newAddr)) {
    +                                serverAddresses.add(newAddr);
    +                            }
    +                        }
    +                    }
    +                } catch (UnknownHostException e) {
    +                    LOG.warn("Cannot re-resolve server: " + curAddr + " UnknownHostException:
" + e);
    --- End diff --
    
    Should we create an unresolved address like what we did on server side `recreateSocketAddresses`
if we can't resolve the address? If the address is not resolvable but maybe it is still usable?


> Zookeeper Client should re-resolve hosts when connection attempts fail
> ----------------------------------------------------------------------
>
>                 Key: ZOOKEEPER-2184
>                 URL: https://issues.apache.org/jira/browse/ZOOKEEPER-2184
>             Project: ZooKeeper
>          Issue Type: Bug
>          Components: java client
>    Affects Versions: 3.4.6, 3.5.0
>         Environment: Ubuntu 14.04 host, Docker containers for Zookeeper & Kafka
>            Reporter: Robert P. Thille
>            Assignee: Robert P. Thille
>              Labels: easyfix, patch
>             Fix For: 3.4.10, 3.5.3
>
>         Attachments: ZOOKEEPER-2184.patch
>
>
> Testing in a Docker environment with a single Kafka instance using a single Zookeeper
instance. Restarting the Zookeeper container will cause it to receive a new IP address. Kafka
will never be able to reconnect to Zookeeper and will hang indefinitely. Updating DNS or /etc/hosts
with the new IP address will not help the client to reconnect as the zookeeper/client/StaticHostProvider
resolves the connection string hosts at creation time and never re-resolves.
> A solution would be for the client to notice that connection attempts fail and attempt
to re-resolve the hostnames in the connectString.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Mime
View raw message