Go Tips - 记录一些和Go语言研发相关Tips

AI 摘要: 本文介绍了在配置GOPROXY环境变量时支持多个代理地址的注意事项,以及如何处理各种错误情况。

1. GOPROXY 环境变量配置多个代理的问题

GOPROYX 支持多个代理地址配置,比如国内有多个地址:

  1. 七牛: Goproxy 中国 https://goproxy.cn
  2. 阿里: mirrors.aliyun.com/goproxy/
  3. 官方: 全球 CDN 加速 https://goproxy.io

这里有几点注意:

  1. 代理实际就是 HTTP 代理,响应 GET 请求,成功响应 200,支持重定向 3xx,当 status codes 为 4xx and 5xx 时候就是遇到错误。404 (Not Found) and 410 (Gone) 表示请求的模块和版本在代理上找不到,但可能从其他地方找到,这类情况支持通过,连接,方便继续从后续代理下载模块;
  2. 如果配置了多个代理是因为 DNS 等问题网络解析失败,这类情况应该用|分割多个代理,go comand 遇到失败后,会回退到用其他的代理地址,比如 DNS 解析失败、HTTP 网络超时、403 网络权限问题等

下面是我的配置:

1
2
3
4
export GOPATH=/private/data/go
export GOPROXY="https://goproxy.woa.com|https://proxy.golang.com.cn,https://goproxy.io,direct"
export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4"
export GONOSUMDB="git.code.oa.com"

说明:

  1. 这里 GOPATH 路径指定/data/go目录
  2. GOPROXY 优先走腾讯公司内网 woa 代理,同时如果在家没有开 ioa 时候(网络失败),会回退到后续https://proxy.golang.com.cn,如果https://proxy.golang.com.cn也失败(404,410)类错误,则会继续往后找,即https://goproxy.io,最后到direct,后面 3 个只要有任何一个有网络错误都会直接报错,类似:
1
2
3
go: golang.org/x/net@v0.7.0: Get "https://goproxy.woa.com/golang.org/x/net/@v/v0.7.0.info": dial tcp 175.27.22.2:443: i/o timeout
go: golang.org/x/term@v0.5.0: Get "https://goproxy.woa.com/golang.org/x/term/@v/v0.5.0.info": dial tcp 175.27.22.2:443: i/o timeout
go: golang.org/x/text@v0.7.0: Get "https://goproxy.woa.com/golang.org/x/text/@v/v0.7.0.info": dial tcp 175.27.22.2:443: i/o timeout

2. go get 私有库配置失败问题

换域名之前: 以下几个因素,导致在域名未改之前,go get [git.code.oa.com/ketang/bingo](http://git.code.oa.com/ketang/bingo) 包可以成功

  1. 原本 bingo 包之前做go module改造,只是配置了go.mod ,没有包含实际的go.sum 文件
  2. 通过配置了GOPROXY=https://goproxy.woa.com 可以做到私有代理
  3. 通过配置了GOPRIVATE=git.code.oa.com 可以不做go sum包签名校对

现象微服务 settle 服务,import “git.code.oa.com/ketang/bingo”基础包,但go get [git.code.oa.com/ketang/bingo](http://git.code.oa.com/ketang/bingo) 包失败

对应的Go Env配置:

1
2
3
4
5
6
7
# 配置GOPROXY,私有代理服务器可以服务于私有模块而不同时服务于公开可用的模块;
# 依次从代理服务器寻找,若服务器响应 404(未找到)或 410(消失),该go命令将依次向后,直至最后直接连接到存储库。
export GOPROXY="https://goproxy.woa.com,https://proxy.golang.com.cn,direct"
export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4"

# 配置为绕过公共代理并直接从版本控制服务器下载私有模块
export GOPRIVATE="git.code.oa.com"

换域名之后:

变更为 [git.woa.com](http://git.woa.com)后,导致git.code.oa.com内网无法解析

1
2
3
4
5
6
7
8
9
export GOPROXY="https://goproxy.woa.com,https://proxy.golang.com.cn,direct"
export GOSUMDB="sum.woa.com+643d7a06+Ac5f5VOC4N8NUXdmhbm8pZSXIWfhek5JSmWdWrq7pLX4G"

# 改为git.code.oa.com 私有库包,仍然走代理(因为goproxy.woa.com已缓存了对应的信息),所以从代理库能找到 [git.code.oa.com/ketang/bingo](http://git.code.oa.com/ketang/bingo)包
# 表示下面的包前缀不做mod签名校对
export GONOSUMDB="git.code.oa.com"

# 以下要注释,因为git.code.oa.com会绕过GOPORXY,但git.code.oa.com又无法解析,所以就会出现dns lookup失败的错误
#export GOPRIVATE="git.code.oa.com"

以上配置,表示 [git.code.oa.com/ketang/bingo](http://git.code.oa.com/ketang/bingo)包 私有库包,仍然先走代理寻找(因为goproxy.woa.com已缓存了对应的信息);下载完包后,bingo 包虽然go.mod没有go.sum签名配置,但仍然可以从代理库能找到,但因为GONOSUMDB="git.code.oa.com",因此可以不做签名校对;

3. go 在 linux 下 build 失败 - 因为 ld 版本过低

解决方式: 通过 yum install binutils 升级 ld 后重新编译就 OK 了

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ go build
#  git.code.oa.com/KETANG_GOLANG/go_ketang_timer_agency_settle
/data/src/download/go/pkg/tool/linux_amd64/link: running g++ failed: exit status 1
/usr/bin/ld: /tmp/go-link-842321623/000008.o: unrecognized relocation (0x2a) in section `.text'
/usr/bin/ld: final link failed: 错误的值
collect2: 错误:ld 返回 1

 老版本
$ ld --version
GNU ld version 2.23.52.0.1-55.el7 20130226
Copyright 2013 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

# 升级到新版本
yum install bash-completion yum-utils -y
yum porovider *bin/ld
yum upgrade binutils

# 更新好的版本
$ ld -v
GNU ld version 2.27-44.base.tl2.1