本文主要是介绍记一次 K8S 内部服务调用域名解析超时排坑经历,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
近期线上 k8s 时不时就会出现一些内部服务间的调用超时问题,通过日志可以得知超时的原因都是出现在域名解析
上,并且都是 k8s 内部的域名解析超时,于是直接先将内部域名替换成 k8s service 的 IP,观察一段时间发现没有超时的情况发生了,但是由于使用 service IP 不是长久之计,所以还要去找解决办法。
复现
一开始运维同事在调用方 pod 中使用ab
工具对目标服务进行了多次压测,并没有发现有超时的请求,我介入之后分析ab
这类 http 压测工具应该都会有 dns 缓存,而我们主要是要测试 dns 服务的性能,于是直接动手撸了一个压测工具只做域名解析,代码如下:
package mainimport ("context""flag""fmt""net""sync/atomic""time"
)var host string
var connections int
var duration int64
var limit int64
var timeoutCount int64func main() {// os.Args = append(os.Args, "-host", "www.baidu.com", "-c", "200", "-d", "30", "-l", "5000")flag.StringVar(&host, "host", "", "Resolve host")flag.IntVar(&connections, "c", 100, "Connections")flag.Int64Var(&duration, "d", 0, "Duration(s)")flag.Int64Var(&limit, "l", 0, "Limit(ms)")flag.Parse()var count int64 = 0var errCount int64 = 0pool := make(chan interface{}, connections)exit := make(chan bool)var (min int64 = 0max int64 = 0sum int64 = 0)go func() {time.Sleep(time.Second * time.Duration(duration))exit <- true}()
endD:for {select {case pool <- nil:go func() {defer func() {<-pool}()resolver := &net.Resolver{}now := time.Now()_, err := resolver.LookupIPAddr(context.Background(), host)use := time.Since(now).Nanoseconds() / int64(time.Millisecond)if min == 0 || use < min {min = use}if use > max {max = use}sum += useif limit > 0 && use >= limit {timeoutCount++}atomic.AddInt64(&count, 1)if err != nil {fmt.Println(err.Error())atomic.AddInt64(&errCount, 1)}}()case <-exit:break endD}}fmt.Printf("request count:%d\nerror count:%d\n", count, errCount)fmt.Printf("request time:min(%dms) max(%dms) avg(%dms) timeout(%dn)\n", min, max, sum/count, timeoutCount)
}
复制代码
编译好二进制程序直接丢到对应的 pod 容器中进行压测:
# 200个并发,持续30秒
./dns -host {service}.{namespace} -c 200 -d 30
复制代码
这次可以发现最大耗时有5s
多,多次测试结果都是类似:
而我们内部服务间 HTTP 调用的超时一般都是设置在3s
左右,以此推断出与线上的超时情况应该是同一种情况,在并发高的情况下会出现部分域名解析超时而导致 HTTP 请求失败。
原因
起初一直以为是coredns
的问题,于是找运维升级了下coredns
版本再进行压测,发现问题还是存在,说明不是版本的问题,难道是coredns
本身的性能就差导致的?想想也不太可能啊,才 200 的并发就顶不住了那性能也未免太弱了吧,结合之前的压测数据,平均响应都挺正常的(82ms),但是就有个别请求会延
这篇关于记一次 K8S 内部服务调用域名解析超时排坑经历的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!