构建和部署

Table of Contents

1. 打包

Go 支持跨平台编译,这里假定服务名称为: hello ,构建 Docker 镜像:

FROM Ubuntu:18.04

COPY hello /hello
COPY config.yaml /etc/hello/config.yaml

EXPOSE 8080

CMD ["/hello", "-config-file", "/etc/hello/config.yaml"]

一个简单的 Makefile:

OUTPUT=hello
TAG=`git rev-parse --short HEAD`

build:
go build -o ${OUTPUT} cmd/main.go

build-linux:
GOOS=linux GOARCH=amd64 go build -o ${OUTPUT} cmd/main.go

build-docker:
GOOS=linux GOARCH=amd64 go build -o ${OUTPUT} cmd/main.go
docker build -t <your docker registry addr>/${OUTPUT}:${TAG} .

push-docker:
docker push <your docker registry addr>/${OUTPUT}:${TAG}

2. 部署

2.1. 直接部署到主机上

构建对应平台的二进制包,Ubuntu 15.04 之后,以及 CentOS7 之后都使用 systemd 作为默认的系统和服务管理器了。 他提供了一些的工具集合,使用起来比 Supervisor 这种工具爽多了。

配置比较简单,使用 systemd 管理的进程,都会在 /usr/lib/systemd/system 目录下有一个 service 文件,用来编排你的应用。

比如:

[Unit]
Description=Command Scheduler
After=auditd.service systemd-user-sessions.service time-sync.target

[Service]
EnvironmentFile=/etc/sysconfig/crond
ExecStart=/usr/sbin/crond -n $CRONDARGS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

[Install]
WantedBy=multi-user.target

这是 crond 的配置文件,里面囊括了服务的描述、依赖、启动命令、配置文件等。

使用 systemd 工具集,可以轻松的查看服务状态、查看日志、设置重启策略,开机启动等。具体可以看我之前梳理的文档: systemdjournalctl

2.2. 部署到容器环境下

在有容器运行时的情况下,建议使用容器部署。

2.3. 版本号

如果使用 Docker 部署时,版本号通常放到 docker tag 中。如果使用二进制文件直接部署的话,把版本号放在二进制名称上是一种办法, 但是很不优雅,这样每次发布都需要修改 systemd unit 的内容。最好的办法就是把版本信息打到二进制包中,通过执行某个参数时自动打印。

Go build -ldflags 支持注入变量,比如:

go build -ldflags -X main.Version=1.0.0 -X main.BuildTime=2020-06-29 15:29:45

将在模块 main 中寻找变量 VersionBuildTime ,然后动态赋值。可以这样写 makefile:

VERSION=`git rev-parse HEAD`
BUILD_TIME=`date +'%Y-%m-%d %H:%M:%S'`
LDFLAGS=-ldflags "-X 'main.Version=${VERSION}' -X 'main.BuildTime=${BUILD_TIME}'"

build:
    go build ${LDFLAGS} -o xxx *.go

然后在 main 中声明变量:

Version   string = ""
BuildTime string = ""

程序开始打印变量即可。

First created: 2020-03-17 16:32:37
Last updated: 2022-12-11 Sun 12:49
Power by Emacs 29.0.91 (Org mode 9.6.6)