Java內部DNS查詢實現和參數設置

1、Java內部DNS查詢

Java使用域名查詢時,用的本身內部的域名實現機制,最後都是交給InetAddress去作DNS解析。html

源碼分析參考:http://blog.arganzheng.me/posts/java-dns-lookup-internal.htmljava

//域名查詢
String dottedQuadIpAddress = InetAddress.getByName( "blog.arganzheng.me" ).getHostAddress();

//IP對應域名
InetAddress[] addresses = InetAddress.getAllByName("8.8.8.8"); // ip or DNS name
for (int i = 0; i < addresses.length; i++) {
    String hostname = addresses[i].getHostName();
    System.out.println(hostname);
}

 

 

2、JNDI DNS服務提供者設置(JNDI DNS service provider settings)

http://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.htmllinux

sun.net.spi.nameservice.provider.<n>=<default|dns,sun|...>Specifies the name service provider that you can use. By default, Java will use the system configured name lookup mechanism, such as file, nis, etc. You can specify your own by setting this option. <n> takes the value of a positive number, it indicates the precedence order with a small number takes higher precendence over a bigger number. Aside from the default provider, the JDK includes a DNS provider named "dns,sun".nginx

Prior to JDK 7, the first provider that was successfully loaded was used. In JDK 7, providers are chained, which means that if a lookup on a provider fails, the next provider in the list is consulted to resolve the name.緩存

重點是這個參數,區分jdk版本,jdk7以前,只有第一個設置的provier生效;jdk7及其以後,provider鏈都生效,從第一個開始,指導解析成功。服務器

Java有兩個實現:oracle

  Default:至關於設置System.setProperty("sun.net.spi.nameservice.provider.1", "default"); 具體解析過程是系統調用(getaddrinfo),依賴系統的DNS解析方式。app

      getaddrinfo:https://linux.die.net/man/3/getaddrinfodom

        Linux 系統如何處理名稱解析: https://blog.arstercz.com/linux-%E7%B3%BB%E7%BB%9F%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E5%90%8D%E7%A7%B0%E8%A7%A3%E6%9E%90/ide

        getaddrinfo工做原理分析: http://www.javashuo.com/article/p-xwkmdawc-hz.html 

        resolv.conf文件更新了,getaddrinfo系統調用感知不到,它只會加載一次: https://stackoverflow.com/questions/19930037/an-issue-of-getaddrinfo-function-call-on-linux-platform  

    linux 默認的DNS方式是讀取/etc/resolv.conf進行DNS解析。

      resolv.conf文件變動了,java進程感知不到,必須得程序重啓才能生效

      Linux 系統如何處理名稱解析: https://blog.arstercz.com/linux-%E7%B3%BB%E7%BB%9F%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E5%90%8D%E7%A7%B0%E8%A7%A3%E6%9E%90/

        修改 resolv.conf 裏的 dns server, 多數運行的程序不會當即生效. Centos 7 系統中, glibc-2.17-202 版本合併了官方 glibc-2.25.90-18 的功能, 增長了自動檢測 resolv.conf 修改功能, 以下:

# rpm -q --changelog glibc-2.17-260
...
* Fri Sep 29 2017 Florian Weimer <fweimer@redhat.com> - 2.17-202
....
- Detect and apply /etc/resolv.conf changes in libresolv (#1432085)

    mac 默認的方式是向網關請求獲取DNS服務器,而後直接請求DNS服務器進行解析,沒有讀取/etc/resolv.conf。

  <dns,sun>:System.setProperty("sun.net.spi.nameservice.provider.1", "dns,sun"); 讀取/etc/resolv.conf進行DNS解析,不一樣於默認的用getaddrinfo系統調用

    不一樣於「default」, 使用"dns,sun",每5分鐘會讀取一次/etc/resolv.conf,更新內存中的dns nameserver


sun.net.spi.nameservice.nameservers=<server1_ipaddr,server2_ipaddr ...>You can specify a comma separated list of IP addresses that point to the DNS servers you want to use. If the sun.net.spi.nameservice.nameservers property is not defined, then the provider will use any name servers already configured in the platform DNS configuration.


sun.net.spi.nameservice.domain=<domainname>This property specifies the default DNS domain name, for instance, eng.example.com. If the sun.net.spi.nameservice.domain property is not defined then the provider will use any domain or domain search list configured in the platform DNS configuration.

 

使用dnsjava的provider:

1. 工程添加dnsjava包。

2. 設置provider:System.setProperty("sun.net.spi.nameservice.provider.1","dns,dnsjava");

dnsjava的provider功能強大:

There's no standard way to determine what the local nameserver or DNS search
path is at runtime from within the JVM.  dnsjava attempts several methods
until one succeeds.

 - The properties 'dns.server' and 'dns.search' (comma delimited lists) are
   checked.  The servers can either be IP addresses or hostnames (which are
   resolved using Java's built in DNS support).
 - The sun.net.dns.ResolverConfiguration class is queried.
 - On Unix, /etc/resolv.conf is parsed.
 - On Windows, ipconfig/winipcfg is called and its output parsed.  This may
   fail for non-English versions on Windows.
 - As a last resort, "localhost" is used as the nameserver, and the search
   path is empty.

參考:

http://www.xbill.org/dnsjava/dnsjava-current/README

http://stackoverflow.com/questions/5668058/how-to-change-the-java-dns-service-provider

 

3、JVM DNS緩存

若是啓動了security manager,則永久緩存,但通常狀況下你們是不會去啓動security manager的。

能夠再程序裏面設置不緩存,或者在啓動參數裏面設置

java.security.Security.setProperty("networkaddress.cache.ttl" , "0")

若是沒有啓動security manager,則要區分JDK版本:

1.5及其一下,java對DNS解析IP進行緩存,默認緩存超時時間爲-1(在重啓JVM前永久緩存)

1.6及其以上,緩存時間根據ttl。

參考:

http://docs.oracle.com/javase/1.5.0/docs/guide/net/properties.html

http://docs.oracle.com/javase/7/docs/technotes/guides/net/properties.html

設置ttl:在命令啓動JVM的時候設置參數"-Dnetworkaddress.cache.ttl=60 -Dsun.net.inetaddr.ttl=60"

 

4、Linux服務器是否會對dns緩存,ttl是否有用?

linux自己是沒有dns緩存的,想使用dns緩存的話須要本身安裝一個服務程序NSCD.

$ ps aux | grep nscd 能夠查看

相關問題:http://blogread.cn/it/article/7043?f=wb

 

5、nginx 本身實現了dns resolver,而且會對dns緩存

6、ping 未知域名的全過程(依賴於操做系統)

主機A,B(可再也不同一網段),主機B有域名假設爲www.baidu.com
首先:1. 本地主機A在命令行下執行"ipconfig/flushdns"命令來清空本地DNS高速緩存;
      2. 本地主機A在命令行下執行"arp -d"命令來清空arp緩存

而後,主機A執行ping www.baidu.com(即主機B的域名)

在此過程當中都發生了那些報文交互?

思路:

  1.要執行ping命令主機A必須將域名轉化爲IP地址,故而必定會有DNS解析過程;
      2.在DNS解析以前,主機A必定要知道本身默認網關的MAC地址,這就要涉及到ARP解析的問題;
      3.ping命令自己是ICMP回顯請求,故而確定要有ICMP協議的回顯請求交互。

如下是全過程:

(此處可參照「跨網段的ping過程」來看,此處假設DNS服務器和主機A不在同一網段,若兩者在同一網段那麼我想只需進行簡單arp就可獲得DNS服務器的mac不需通過網關)
1.主機A發送ARP請求報文目的mac爲FFFFFF-FFFFFF,目的IP爲網關的IP,要求得到網關的MAC地址;
2.路由器(主機A的默認網關)發送目的mac爲A的mac,目的IP爲A的IP的ARP回答報文,以告知A網關的mac地址;
3.A得到網關的mac地址後,就向網關發送一個DNS查詢報文,其目的mac地址爲網關的mac地址,目的IP爲DNS服務器的IP地址;
4.網關收到DNS查詢報文後,拆包檢查發現是DNS查詢因而將相應(查詢)信息封裝,向DNS服務器發送該報文,其目的IP地址爲DNS服務器的IP,目的mac爲下一跳的mac,解析域名IP地址此時就交給了DNS服務器;
5.通過DNS解析,主機A知道了所要ping的域名的ip地址;
6.剩下的ping過程就和ping一個特定的ip地址相同了,首先判斷ping命令的目的B的IP地址是否和A在同一網段,若在同一網段則至關於同網段內ping,若不在同一網段,就是不一樣網段的ping只不過此時主機不須要再解析網關的mac地址了。

參考:

http://blog.sina.com.cn/s/blog_7c35df9b0100vomk.html

相關文章
相關標籤/搜索