Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eureka Client doesn't respect DNS server change at runtime #1157

Merged
merged 3 commits into from
Dec 18, 2018

Conversation

krutsko
Copy link
Contributor

@krutsko krutsko commented Nov 14, 2018

Eureka Client doesn't respect DNS server change at runtime.

E.g. try to adjust DNS server at /etc/resolv.conf file , but Eureka Client keep communicate with old address.

The reason is that Eureka Client initializes InitialDirContext once and keep it in static variable , so it never re-read resolv.conf.

I didn't spent much time to write a proper unit test for this (let me know if it needed), but here the code which could help to check this with DnsResolver.

ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);

        executorService.scheduleAtFixedRate(
                () -> {
                    logger.info("running dns checker");

                    Hashtable env = new Hashtable();
                    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.dns.DnsContextFactory");
                    DirContext ictx = null;
                    try {
                        ictx = new InitialDirContext(env);
                        String dnsServers = (String) ictx.getEnvironment().get("java.naming.provider.url");

                        logger.info("DNS Servers: " + dnsServers );
                    } catch (NamingException e) {

                    }

                    try {
                        String dnsServers = (String) dirContext.getEnvironment().get("java.naming.provider.url");

                        logger.info("DNS Servers static : " + dnsServers );
                    } catch (NamingException e) {

                    }
                },
                10,
                10,
                TimeUnit.SECONDS
        );

/**
* Load up the DNS JNDI context provider.
*/
public static DirContext getDirContext() {
private DirContext getDirContext() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can see that this method can throw new RuntimeException. It's okay to throw this when application starts: this is a critical problem which has rights to prevent application startup. But did you check what are the consequences of this happening at some point in time when application is already operating and just wants to refresh list of Eureka nodes?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I have changed all invocations and ensure that this RuntimeException properly caught and logged.

/**
* Load up the DNS JNDI context provider.
*/
public static DirContext getDirContext() {
private DirContext getDirContext() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this is now called N+1 times, where N is number of zones. Are we okay with this? Isn't it time-consuming? (IMHO even if it is, it's not critical, but maybe somebody has another opinion).

Copy link
Contributor Author

@krutsko krutsko Nov 16, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not an expensive request, we don't make a network call, just initialize context where it re-check dns server on the local machine.

Here the implementation of dns server resolution for Linux on AdoptOpenJDK 11 (a first link i can found) https://github.com/AdoptOpenJDK/openjdk-jdk11/blob/master/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java
It caches "/etc/resolv.conf" parsing for 5 minutes.

@pparth
Copy link

pparth commented Nov 19, 2018

Shouldn't we open an issue first, linked to this PR?

@krutsko
Copy link
Contributor Author

krutsko commented Nov 20, 2018

@pparth I guess it doesn't matter, but here it's #1158

@pparth
Copy link

pparth commented Dec 7, 2018

Can someone check this PR please?

@krutsko
Copy link
Contributor Author

krutsko commented Dec 17, 2018

Can someone take a look at the PR, and re-run the tests (they all pass on my local machine) ?

@@ -58,15 +53,15 @@ public static DirContext getDirContext() {
*
* @return resolved host name
*/
public static String resolve(String originalHost) {
public String resolve(String originalHost) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DnsResolver was written as a utility class with only static methods. This PR changes an implementation detail of this class so there's no need to make it possible to instantiate DnsResolver directly. Also, I'm concerned about making such breaking changes to public methods. The PR can be greatly simplified if the static change were to be reverted.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elandau thanks for looking into this.
Yes, i have reverted to static DnsResolver, somehow missed this at first place.

@elandau elandau merged commit 1b60b49 into Netflix:master Dec 18, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants