2

Where check/set timeout when java.net.UnknownHostException is thrown?

Occasionally my code tries to connect to a non-existing location and throws java.net.UnknownHostException what is acceptable case in my app.

The problem I have is that it takes roughly about 20sec before the exception is thrown and it slows down the whole application.

The webserver version is Tomcat 7.0.37. I have tried change timeout settings (to 2sec) in the server.xml for following connectors:

Connector port="8009" protocol="AJP/1.3" redirectPort="8443" connectionTimeout="2000"
Connector port="8080" protocol="HTTP/1.1" connectionTimeout="2000" redirectPort="8443"

As I use HttpURLConnection I would expect the connection timeout setting for port 8080 to take effect, but it does not seem to be true.

I also tried to set the timeout within the code:

HttpURLConnection connection = (HttpURLConnection)url.openConnection();  
connection.setConnectTimeout(1000);  
Reader reader= new InputStreamReader((InputStream) connection.getContent());

But this did not work neither, any ideas? Am I missing something?

ta

ollo
  • 24,797
  • 14
  • 106
  • 155
LuckyAshnar
  • 355
  • 2
  • 12
  • are you generally working on a slow internet connection? If so, did you try increasing the timeout? Try testing it on a high speed connection. If the problem still persists, then there is some issue in your logic which might be spawning too many threads. – vasanth May 17 '13 at 09:36
  • 1
    You have a misconfigured DNS. Solve that. – user207421 May 17 '13 at 10:25
  • @user927258 How increasing the timeout would help me to decrease the time spent on waiting for the java.net.UnknownHostException to be thrown? – LuckyAshnar May 17 '13 at 11:03
  • @EJP that would be up to network administrator and not in my powers, i got to address it in my app, ta – LuckyAshnar May 17 '13 at 11:04

2 Answers2

1

The time is probably being spent looking up the host in DNS, which in your case seems to be timing out when trying to look up a host that can't be found. This happens if the DNS server you connect to forwards the request to another DNS server, and doesn't get a reply in a reasonable amount of time, perhaps because it's not well configured.

You can solve this problem in the operating system level by making the DNS lookup timeout earlier; for example in Linux you could add options timeout:2 to /etc/resolv.conf to make DNS lookups timeout in 2 seconds instead of the default. On Windows you have to edit a registry setting.

Alternatively you can solve this in your program by using a thread for the name resolution. If the thread doesn't return in a timeout you specify you assume that name resolution will throw an UnknownHostException.

A third option is using a different, better behaved DNS server, like the ones maintained by Google at 8.8.8.8 and 4.4.4.4.

Community
  • 1
  • 1
Joni
  • 108,737
  • 14
  • 143
  • 193
  • Thanks for the idea, It seems to me it indeed is problem with DNS. Summing up default times DNSQueryTimeouts (given in post "edit a registry setting" ) gives 17 seconds which would explain why I am waiting for about that time for the action if unavailable host called. – LuckyAshnar May 17 '13 at 11:26
  • Yet another option is using a different DNS servers if you can. 8.8.8.8 (maintained by Google) is pretty fast and won't make you wait to tell you if they can't resolve a name. Come to think of it, I'll add this to the answer. – Joni May 17 '13 at 13:17
0

The problem you are facing is a DNS resolution problem not a Java one, I guess that your program is blocked during the DNS query. Try to perform an nslookup on an unknown host inside a shell to see if you reproduce the problem. If you are, ask your system administrator to look at the DNS server logs and configuration if there's something wrong.

If the hosts are frequently the same, look at this post to configure the negative ttl to cache the Unknown host responses from the DNS : any-way-to-make-java-honor-the-dns-caching-timeout-ttl

Community
  • 1
  • 1
gma
  • 2,563
  • 15
  • 14