golang使用cgo dns resolver
golang在Linux下在nsswitch.conf允许的情况下,默认会使用自己的pure go resolver,parse了/etc/resolv.conf
的内容。
但在部分安装了nscd的机器上,如果刚好resolv.conf
中配置了无效的dns服务器,则ping和curl命令都可以通过nscd的缓存获取到解析结果,而golang的程序则会报错解析失败。
按照golang的官方文档,可以通过设置GODEBUG=netdns=cgo
来强制使用libc的resolver,go代码中则可以通过以下代码开启
Update:
上面其实不是最好的办法,最标准的姿势,应该是go build
中指定-tags 'netcgo'
,按照src/net/conf_netcgo.go中的指定,就会在编译期就使用cgo resolver。
但这会带来另外一个问题,公司里用的是魔改RHEL5,内核上到2.6.32了,但默认的gcc还停留在4.1,按照golang/go#9520的描述,会导致编译错误,解决方法有两个:
- 修改golang的源代码,将src/cmd/go/build.go的
disableBuildID
方法内容,按上面的注释,从"-Wl,--build-id=none"
修改为"-r"
,然后重新编译出go
可执行文件并替换,注意根据文档指示设定$GOROOT_FINAL
变量并使用RHEL5平台进行编译,否则syscall可能无法对齐。 - 或者直接使用DevTools 2,里面针对RHEL5的平台提供了GCC 4.8.2,同样也可以解决这个问题,这也是我最终选择的方案,这样每次都能用官方的golang二进制。