我创建了一个简单的go程序,它执行HTTP GET请求并打印执行请求所用的时间:
package main
import (
"log"
"net/http"
"time"
)
func main() {
start := time.Now()
http.Get("https://google.com")
log.Printf("Elapsed: %v", time.Since(start))
}
在OSX上本地构建(Sierra 10.12.1)时,执行请求所用的时间是合理的(<500ms)。
$ for i in `seq 1 10`; do ./httpgettest ; done
2017/08/15 14:20:44 Elapsed: 525.989928ms
2017/08/15 14:20:45 Elapsed: 479.785494ms
2017/08/15 14:20:45 Elapsed: 477.800294ms
2017/08/15 14:20:46 Elapsed: 494.060461ms
2017/08/15 14:20:46 Elapsed: 477.368627ms
2017/08/15 14:20:47 Elapsed: 454.152783ms
2017/08/15 14:20:47 Elapsed: 463.760254ms
2017/08/15 14:20:48 Elapsed: 470.52473ms
2017/08/15 14:20:48 Elapsed: 461.632058ms
2017/08/15 14:20:49 Elapsed: 465.769262ms
然后我从golang Linux docker容器中交叉编译相同的程序:
GOOS=darwin GOARCH=amd64 go build -v -o httpgettest-xcompiled
但是,在VPNed执行生成的二进制文件时,经过的时间总是10秒以上:
$ for i in `seq 1 10`; do ./httpgettest-xcompiled ; done
2017/08/15 14:19:43 Elapsed: 10.532037349s
2017/08/15 14:19:54 Elapsed: 10.525551121s
2017/08/15 14:20:04 Elapsed: 10.572715005s
2017/08/15 14:20:15 Elapsed: 10.532407157s
2017/08/15 14:20:25 Elapsed: 10.54083169s
2017/08/15 14:20:36 Elapsed: 10.625399239s
2017/08/15 14:20:46 Elapsed: 10.539333467s
2017/08/15 14:20:57 Elapsed: 10.533211943s
2017/08/15 14:21:07 Elapsed: 10.539430574s
2017/08/15 14:21:18 Elapsed: 10.527510134s
一旦我从VPN断开连接,数字就会下降。
有人可以解释交叉编译二进制文件如何在VPN上运行缓慢但是mac本机编译版本始终是高性能的吗?这可以使用golang 1.7.6,1.8.3和1.9泊坞容器重现。
我使用Tunnelblick连接到OpenVPN服务器。
答案 0 :(得分:0)
在本地编译时,看起来Go正在使用系统的本机DNS解析代码(通过C库),但是当交叉编译时,Go自己的解析器用Go编写。作为确认,在CGO_ENABLED=0
时听起来很慢。虽然没有具体说明您在此处遇到的问题,但https://github.com/golang/go/issues/16345出现在快速搜索中,并指出CGO_ENABLED如何确定哪个解析器运行。
我不确定你是如何编译你想要使用cgo本机解析器跨平台的二进制文件(可能需要至少安装C交叉编译器)或者让Go中的解析器在您的Darwin VPN设置。