【发布时间】:2018-01-23 22:47:02
【问题描述】:
我创建了一个简单的 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) 上本地构建时,执行请求所用的时间是合理的 (
$ 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
但是,在 VPN 状态下执行生成的二进制文件时,经过的时间总是 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 docker 容器重现。
我使用 Tunnelblick 连接到 OpenVPN 服务器。
【问题讨论】:
-
Go 可能在本地编译时使用系统内置的 DNS 解析代码,但在交叉编译时使用 Go 的内置解析器。如果使用传递给
go build的 CGO_ENABLED=0 构建本地构建也很慢,那么可能就是这样。 github.com/golang/go/issues/16345 有更多。我不确定你是如何让 cgo 原生解析器跨平台工作(可能至少需要安装一些编译器)或者让 Go 中的解析器在你的 Darwin VPN 设置下正常工作。 -
谢谢@twotwotwo,我想你搞定了。如果我设置 CGO_ENABLED=0 并在本机构建,它会将其减慢到与交叉编译版本相同的时间。
-
@twotwotwo,请随意复制并粘贴您的评论作为答案,以便我将其标记为已接受。谢谢你的解释!
-
调整工作,因为您实际尝试过并发布为答案。
标签: macos http go cross-compiling vpn