你正在使用的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秒。如果次要服务器不可达,它永远不会被触及,因为主服务器已经解析了名称,没有注意到超时。
5条答案
按热度按时间c9qzyr3d1#
在主机箱上,您是否尝试使用dig命令解析dns查询?同时检查服务器是否配置了ipv6地址。
dddzy1tm2#
感谢您提交这个问题@geofffranks!
请通知一些网络Maven@bradfitz@ianlancetaylor@mikioh
23c0lvtd3#
服务器没有配置IPv6地址。当第一个服务器可用,第二个不可用时,Dig工作正常。当我在/etc/resolv.conf中反转服务器的顺序时,Dig会在2秒后超时,然后查询下一个服务器并解析记录。
vhmi4jdf4#
这是GODEBUG,而不是GO_DEBUG,而且这个机制只有在cgo版本被编译到二进制文件中时才能让你在cgo和非cgo之间进行选择,如果从Mac上跨编译,并且没有在Mac上安装Linux工具链,那么默认情况下是不会包含cgo版本的。
我认为这次跨编译的部分是一个误导。你可能只用设置GODEBUG就可以在Linux上复现相同的结果。你能把你的测试结果(先设置
GODEBUG=netdns=cgo+1
,然后设置GODEBUG=netdns=go+1
)发出来吗?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 解析器,速度很快