1. 程式人生 > >dns解析超時故障分析

dns解析超時故障分析

XX傳送介面超時問題排查

一句話總結

XX傳送介面邏輯中呼叫了YY的http介面,在http client中dns解析沒有超時控制,導致http呼叫偶發超時。

現象

XX上線後,發現線上監控顯示傳送訊息的介面響應時間會有偶發的高峰,檢視日誌,超時的響應時間多為3-5s,並且在同一時間點出現,最高有9s的超時時間,一臺機器每天約有10次左右慢請求(單機send介面qps約1)。

排查

1.    通過業務程式碼中的分步耗時日誌,定位到超時原因是呼叫反垃圾介面的http請求慢。

2.    檢視http client配置,cotimeout為100ms,sotimeout為100ms,遠低於5s。

3.    檢視http client原始碼,http client的超時配置沒有問題。

4.    在一臺機器上開啟http client的debug日誌,觀察超時時的日誌,出問題的請求都列印了

5.  [DEBUG] HttpConnection Open connection to safe.i.t.sina.com.cn:80

日誌位置在HttpConnection.java:692

6.    進一步檢視程式碼,發現在socket建連前,解析dns的函式沒有傳入超時時間:

7.   ReflectionSocketFactory:124
8.   Object remoteaddr = INETSOCKETADDRESS_CONSTRUCTOR.newInstance(
9.           new Object[] { InetAddress.getByName(host), new Integer(port)});

10.  進一步追查程式碼,最後會走到Inet6AddressImpl.lookupAllHostAddr(Stringhostname),對應實現是native的

11.jdk/src/solaris/native/java/net/Inet6AddressImpl.c:139
12.JNIEXPORT jobjectArray JNICALLJava_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this,
13.                                         jstring host) {
14.   ....
15.   error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res);
16.   ....
17. }
18.
19.net_util_md.c:392
20.getaddrinfo_ptr = (getaddrinfo_f)
21. JVM_FindLibraryEntry(RTLD_DEFAULT, "getaddrinfo");

22.  getaddrinfo的超時時間由作業系統決定,預設5s,重試2次。

23.$man resolv.conf
24....
25.timeout:n
26.sets the amount of time the resolver will wait for a response from a remote name server before retrying the  query via  a different name server.  Measured in seconds, the default is RES_TIMEOUT (currently 5, see <resolv.h>).  The  maximum value for this option is silently capped to 30.
27.
28.attempts:n
29.sets the number of times the resolver will send a query to its name servers before  giving  up  and  returning  an error  to  the calling application.  The default is RES_DFLRETRY (currently 2, see <resolv.h>).  The maximum value for this option is silently capped to 5.

30.  檢視XX機器線上配置,dns配置為遠端伺服器,沒有修改超時時間,並且配置的dns伺服器各不相同,對比發現,使用172網段dns的機器超時請求略多一些。

31.  灰度了一臺機器,修改hosts指定dns後,沒有再出現超時請求。

解決

1.    使用dnsmasq本地快取dns。

2.    修改/etc/resolv.conf,調整dns解析最大超時時間。

3.    業務方使用Feature方式呼叫http介面。

4.    http client4.x似乎有非native dns的實現方式,可以控制超時時間(當前client版本為3.x)。