dongyun6003 2017-08-15 22:39
浏览 58
已采纳

net / http.Get()中的VPN连接时,Golang交叉编译的OSX二进制文件挂起

I created a simple go program which performs a HTTP GET request and prints the elapsed time taken to perform the request:

package main

import (
    "log"
    "net/http"
    "time"
)

func main() {
    start := time.Now()
    http.Get("https://google.com")
    log.Printf("Elapsed: %v", time.Since(start))
}

When building this natively on OSX (Sierra 10.12.1), the elapsed time to perform the request is reasonable (<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

I then cross-compile the same program from the golang Linux docker container:

GOOS=darwin GOARCH=amd64 go build -v -o httpgettest-xcompiled

However when executing the resulting binary while VPNed, the elapsed time is always 10+ seconds:

$ 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

As soon as I disconnect from the VPN, the numbers drop down.

Can someone explain how the cross compiled binary is slow while VPNed but the mac native compiled version is always performant? This is reproducible using the golang 1.7.6, 1.8.3 and 1.9 docker containers.

I use Tunnelblick to connect to a OpenVPN server.

  • 写回答

1条回答 默认 最新

  • dqalnwuci494308 2017-08-15 23:33
    关注

    It looks like Go is using system's native DNS resolution code (via a C library) when compiling locally, but Go's own resolver written in Go when cross-compiled. As confirmation, sounds like it's slow when CGO_ENABLED=0. Although it isn't specifically about what you're experiencing here, https://github.com/golang/go/issues/16345 came up in a quick search and refers to how CGO_ENABLED determines which resolver runs.

    I'm not sure, though, how you either compile a binary you want to use the cgo native resolver cross-platform (probably need to at least install C cross-compilers) or get the resolver in Go to work well under your Darwin VPN setup.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Stata链式中介效应代码修改
  • ¥15 latex投稿显示click download
  • ¥15 请问读取环境变量文件失败是什么原因?
  • ¥15 在若依框架下实现人脸识别
  • ¥15 添加组件无法加载页面,某块加载卡住
  • ¥15 网络科学导论,网络控制
  • ¥100 安卓tv程序连接SQLSERVER2008问题
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用