dns解析超时故障分析

来源:互联网 发布:激活淘宝店铺怎么激活 编辑:程序博客网 时间:2024/04/28 22:30

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)。

 

 

0 0