[Go 入门] 第二十三章 部署 Go 语言代码

Go 入门系列参考于互联网资料与 人民邮电出版社 《Go 语言入门经典》 与 《Effective Go》,编写目的在于学习交流,如有侵权,请联系删除

本文内容:

理解目标

Go 的优点之一就是可众多不同的操作系统和体系结构中运行。操作系统是 Windows 和 macOS 等系统,而体系结构指的是用于运行程序的计算机处理的体系结构。体系结构决定了处理器的计算速度以及支持的内存量。

使用 go env 查看当前的操作系统和体系结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
set GO111MODULE=on
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\Admin\AppData\Local\go-build
set GOENV=C:\Users\Admin\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=F:\Go
set GOPRIVATE=
set GOPROXY=https://goproxy.cn,direct
set GOROOT=c:\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=c:\go\pkg\tool\windows_amd64
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=NUL
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\Admin\AppData\Local\Temp\go-build961282946=/tmp/go-build -gno-record-gcc-switches

这个示例中,计算机是64位的,且安装的是 Windows 系统,默认情况下,编译器会针对当前操作系统的体系结构进行编译,如果要为不同的系统编译,则需要指出声明

GOOS=linux GOARCH=386 go build dirname.go

上诉的 GOOS 和 GOARCH 为环境变量,其意义是编译一个32位的Linux程序

Go 支持的平台和体系结构

平台 体系结构
android arm
darwin 386
darwin amd64
darwin arm
darwin arm64
dragonfly amd64
freebsd 386
freebsd amd64
freebsd arm
linux 386
linux amd64
linux arm
linux arm64
linux ppc64
linux ppc64le
linux mips
linux mipsle
linux mips64
linux mips64le
netbsd 386
netbsd amd64
netbsd arm
openbsd 386
openbsd amd64
openbsd arm
plan9 386
plan9 amd64
solaris amd64
Windows 386
Windows amd64

压缩二进制的大小

通过指定一些编译的标志,可压缩编译得到的二进制文件大小。这些标志指定了省略符号表、调试信息和DWRARF符号表

GOOS=linux go build -ldflags="-s -w" main.go

其次在一些硬件设备空间很小,如 Raspberry Pi、路由器或物联网(IoT)设备时,还可以使用类似 UPX 的工具再次压缩

使用 Docker

Docker 是一种在虚拟机中运行应用程序的主流方式,它提供了一种轻量级的方式,可确保无论计算机使用的是那种操作系统,应用程序都将在相同的环境中运行。Docker 使用容器来确保应用程序位于操作系统的沙盒环境中,开销比完整的虚拟机小

最近几年,Docker 和容器越来越受欢迎。它们提供了一些确保一致性的轻量级方式,由于它们能够以标准的方式运行,因此出现了一个以其为中心的丰富而生机勃勃的生态圈。“开发和运维”,是帮助软件小组快速、安全、平稳地发布代码,Docker 可帮助您完成这个过程

Docker 可用于 Linux、Windows 和 macOS

Dockerfile

1
2
3
4
5
FROM golang:1.13.6
COPY main.go /
RUN go build -o /main /main.go
EXPOSE 8000
ENTRYPOINT ["/main"]

main.go

1
2
3
4
5
6
7
8
9
10
11
12
package main

import "net/http"

func helloWorld(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello world"))
}

func main() {
http.HandleFunc("/", helloWorld)
http.ListenAndServe(":8000", nil)
}

上面是一个简单 HTTP 服务器的示例,随后终端执行 docker build -t main/go .

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Sending build context to Docker daemon 3.072 kB
Step 1/5 : FROM golang:1.13.6
---> 272e3f68338f
Step 2/5 : COPY main.go /
---> ce7ecdb20334
Removing intermediate container a6f4dd6224b1
Step 3/5 : RUN go build -o /main /main.go
---> Running in 4b2542a3b698

---> 79e021cde92c
Removing intermediate container 4b2542a3b698
Step 4/5 : EXPOSE 8000
---> Running in 2b6bf68fb610
---> 7ba76d309ea1
Removing intermediate container 2b6bf68fb610
Step 5/5 : ENTRYPOINT /main
---> Running in 6b1290f8b219
---> 550805a142a2
Removing intermediate container 6b1290f8b219
Successfully built 550805a142a2

在完成构建后,使用容器运行

docker run -p 8000:8000 main/go

访问 localhost:8000 即可看到 Hello world

问题列表

  • Go 二进制文件真的不需要依赖吗

    不需要。这是使用静态链接的二进制文件的优点之一

  • Docker 看起来很复杂,值得花时间去学习吗

    如果要创建服务器或将部署到其他应用环境中的软件,就需要学习 Docker;如果你是软件小组的一员,并要部署 Web 产品,就很可能需要用到 Docker。包括 Google 在内的很多大型软件公司都是用容器来管理基础设施