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

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes (k8s) 是一个流行的容器编排和管理工具,它能够自动部署、扩展和管理容器化应用程序。在Kubernetes中,容器一般是通过服务发现的方式来进行通信,在这个过程中,域名解析是至关重要的一环。 容器中的应用程序通常会使用DNS进行域名解析来定位其他容器或外部服务。Nginx作为一个常用的容器化Web服务器,也需要通过DNS解析来将域名转换为IP地址,以便与其他容器或外部服务进行通信。 然而,有时候在Kubernetes集群中,容器的域名解析可能会出现不稳定性的问题。这可能导致Nginx无法解析需要的域名,使得容器间的网络通信出现故障或不可靠。 引起这种不稳定性的原因可能是多种多样的。首先,DNS解析问题可能与Kubernetes集群的配置有关。如果DNS服务配置不正确或不稳定,容器中的Nginx就无法准确地解析域名。 其次,网络问题也可能导致DNS解析不稳定。如果网络延迟高或者网络带宽不足,DNS解析可能会超时或失败,从而影响到Nginx的正常运行。 最后,应用程序本身的问题也可能导致DNS解析的不稳定性。如果应用程序没有正确地处理域名解析失败的情况,可能会导致Nginx无法正常工作。 要解决这个问题,我们可以采取以下措施: 1. 检查Kubernetes集群的DNS配置,确保DNS服务正常运行并配置正确。 2. 检查网络状况,确保网络延迟低、带宽充足,减少DNS解析超时的可能性。 3. 在应用程序中添加域名解析失败的错误处理机制,例如进行重试或回退到备用解析方案。 综上所述,k8s容器中的Nginx DNS解析不稳定的问题可能与Kubernetes集群的配置、网络问题或应用程序本身相关。通过检查和调整配置,优化网络状况以及合理处理解析失败,我们可以提高Nginx DNS解析的稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值