如果DNS服务器无效,net:交叉编译的Go在解析名称时具有较长的超时时间,

ntjbwcob  于 6个月前  发布在  Go
关注(0)|答案(5)|浏览(48)

你正在使用的Go版本是什么(go version)?

go version go1.11 darwin/amd64

这个问题在最新版本的发布中是否重现?

是的

你正在使用什么操作系统和处理器架构(go env)?

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/gfrau/Library/Caches/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/gfrau/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/Cellar/go/1.11/libexec"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.11/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/jh/z59wc4wx5cz823x6l5f81qn463wn7j/T/go-build408544351=/tmp/go-build -gno-record-gcc-switches -fno-common"

你做了什么?

我们在Mac上交叉编译了一个应用程序,目标操作系统为linux。当在/etc/resolv.conf中有两台DNS解析器列出,但其中一台无法访问时,应用程序需要很长时间才能解析DNS(15秒?)。使用GO_DEBUG更改DNS解析机制似乎不起作用,无论选择的是go还是cgo DNS解析器,都会发生错误。一旦我们注解掉无法访问的DNS服务器,应用程序就可以正常工作。无论是第一个还是第二个DNS服务器不可用都没有关系。应用程序运行缓慢,strace显示它无论如何都会连接到这两台服务器。

你期望看到什么?

我期望Go首先使用主DNS服务器,然后在解析器列表中的下一个之前等待2秒,返回第一个成功服务器的响应。

你看到了什么?

超时和构建在darwin/amd64上的应用程序在linux/amd64的目标系统上运行缓慢。
如果直接在linux/amd64上进行go build并且不进行交叉编译(CGO_ENABLED=0和CGO_ENABLED=1都使用),这个问题就会消失。然而,如果在这个测试用例中主解析器不可达,DNS解析的超时时间会超过10秒,而不是预期的2秒。如果次要服务器不可达,它永远不会被触及,因为主服务器已经解析了名称,没有注意到超时。

c9qzyr3d

c9qzyr3d1#

在主机箱上,您是否尝试使用dig命令解析dns查询?同时检查服务器是否配置了ipv6地址。

dddzy1tm

dddzy1tm2#

感谢您提交这个问题@geofffranks!
请通知一些网络Maven@bradfitz@ianlancetaylor@mikioh

23c0lvtd

23c0lvtd3#

服务器没有配置IPv6地址。当第一个服务器可用,第二个不可用时,Dig工作正常。当我在/etc/resolv.conf中反转服务器的顺序时,Dig会在2秒后超时,然后查询下一个服务器并解析记录。

vhmi4jdf

vhmi4jdf4#

这是GODEBUG,而不是GO_DEBUG,而且这个机制只有在cgo版本被编译到二进制文件中时才能让你在cgo和非cgo之间进行选择,如果从Mac上跨编译,并且没有在Mac上安装Linux工具链,那么默认情况下是不会包含cgo版本的。

我认为这次跨编译的部分是一个误导。你可能只用设置GODEBUG就可以在Linux上复现相同的结果。你能把你的测试结果(先设置GODEBUG=netdns=cgo+1,然后设置GODEBUG=netdns=go+1)发出来吗?

fv2wmkja

fv2wmkja5#

我认为在创建问题时,GO_DEBUG 是一个拼写错误。再次运行测试:
使用 GODEBUG=netdns=cgo+1 交叉编译 - 显示它正在使用 Go 的 DNS 解析器,我们看到问题
使用 GODEBUG=netdns=go+1 交叉编译 - 显示它正在使用 Go 的 DNS 解析器,我们看到问题
从 Linux 静态编译 GODEBUG=netdns=cgo+1 - 显示它正在使用 Go 的 DNS 解析器,速度很快
从 Linux 静态编译 GODEBUG=netdns=go+1 - 显示它正在使用 Go 的 DNS 解析器,速度很快
从 Linux 动态编译 GODEBUG=netdns=cgo+1 - 显示它正在使用 cgo DNS 解析器,速度很快
从 Linux 动态编译 GODEBUG=netdns=go+1 - 显示它正在使用 Go 的 DNS 解析器,速度很快

相关问题