go-zero的代码, 同时更新架构go-zero, 今天只是更新的版本 https://github.com/zeromicro/go-zero
app下会有双层服务, 根目录下有pkg公用代码,比如配置中心获取, 然后是公共构建Dockerfile(所有服务)

Dockerfile使用双阶段构建, 然后构建的时候会传递参数SERVICE_PATH表示要构建的服务
docker build -t xxx:xx --build-arg SERVICE_PATH=${SERVICE_PATH} .FROM golang:alpine3.18 AS builder
LABEL stage=gobuilder
## 定义项目的根目录
ARG SERVICE_PATH
ENV CGO_ENABLED 0
RUN echo -e 'https://mirrors.aliyun.com/alpine/v3.18/main/\nhttps://mirrors.aliyun.com/alpine/v3.18/community/' > /etc/apk/repositories && apk update --no-cache && apk add --no-cache tzdata
WORKDIR /build
COPY . .
RUN go env -w GO111MODULE=on
RUN go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
RUN go mod download
RUN go build -ldflags="-s -w" -o /build/main /build/app/${SERVICE_PATH}
## 使用空镜像构建
FROM scratch
## 定义项目的根目录
ARG SERVICE_PATH
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai
WORKDIR /app
COPY --from=builder /build/main /app/main
ENTRYPOINT ["./main"]go-zero启动时使用这个生成的端口(而不是配置文件中的)func GetAvailablePort() (int, error) {
address, err := net.ResolveTCPAddr("tcp", "0.0.0.0:0")
if err != nil {
return 0, err
}
listener, err := net.ListenTCP("tcp", address)
if err != nil {
return 0, err
}
defer listener.Close()
return listener.Addr().(*net.TCPAddr).Port, nil
}etcd (只在启动的时候拉取), 然后配置管理使用的 https://github.com/evildecay/etcdkeeperetcdkeeper效果很不错, 内置支持json, yaml等配置
docker-compose用来搭建基础服务version: '3'
services:
etcd:
container_name: etcd
image: bitnami/etcd:3
restart: always
environment:
- ETCDCTL_API=3
- ALLOW_NONE_AUTHENTICATION=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://127.0.0.1:2379
volumes:
- "./data/etcd:/bitnami/etcd/data"
# ports:
# - "2379:2379"
# - "2380:2380"
network_mode: host
etcdkeeper:
hostname: etcdkeeper
image: evildecay/etcdkeeper:v0.7.6
# ports:
# - "8080:8080"
network_mode: host
restart: always10小时的构建额度, 基本上够用了SERVICE_PATH和SERVICE_NUMBER, 标识本次构建的服务和部署的服务数量SERVICE_PATH会在前面说的docker build参数使用SERVICE_NUMBER 就是启动多少个容器, 伪代码如下script {
def count = SERVICE_NUMBER.toInteger();
echo "部署: ${count} 个"
for (int i = 0; i < count; i++) {
sshCommand(
remote: remoteConfig,
command: "docker run -d --net=host --restart=always --name ${SERVICE_NAME}-${i} ${IMAGE_NAME}:${CI_BUILD_NUMBER}",
sudo: true,
)
echo "${SERVICE_NAME}-${i}..."
}
}
