Appearance
配置管理与多环境部署
本篇讲解 go-zero 的配置管理体系和多环境部署实践。我们将介绍 YAML 配置文件、配置结构体、环境变量覆盖机制;详解 API 和 RPC 服务的配置项;讲解多环境(开发、测试、生产)的配置隔离方案;介绍配置中心(etcd)集成与热更新;最后演示 Docker 化部署和 Kubernetes 部署的完整流程。
一、go-zero 配置体系
go-zero 采用「YAML 配置文件 + Go 结构体」的配置模式,简洁直观且类型安全。
1. YAML 配置文件
go-zero 使用 YAML 作为配置文件格式。一个典型的 API 服务配置:
yaml
# etc/user-api.yaml
Name: user-api
Host: 0.0.0.0
Port: 8888
Auth:
AccessSecret: "your-secret-key"
AccessExpire: 86400
MySQL:
DataSource: root:123456@tcp(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=true&loc=Local
CacheRedis:
- Host: 127.0.0.1:6379
Type: node
UserRpc:
Etcd:
Hosts:
- 127.0.0.1:2379
Key: user.rpc
NonBlock: true
Timeout: 2000
Log:
ServiceName: user-api
Mode: file
Path: logs
Level: info
KeepDays: 7
Prometheus:
Host: 0.0.0.0
Port: 9100
Path: /metrics
Telemetry:
Name: user-api
Endpoint: http://127.0.0.1:14268/api/traces
Sampler: 1.0
Batcher: jaeger2. 配置结构体
YAML 文件对应一个 Go 结构体,通过 tag 声明字段映射:
go
// internal/config/config.go
package config
import (
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/redis"
"github.com/zeromicro/go-zero/rest"
"github.com/zeromicro/go-zero/zrpc"
)
type Config struct {
rest.RestConf // 嵌入 HTTP 服务配置
Auth struct {
AccessSecret string
AccessExpire int64
}
MySQL struct {
DataSource string
}
CacheRedis cache.ClusterConf
Redis redis.RedisConf
UserRpc zrpc.RpcClientConf
}rest.RestConf 和 zrpc.RpcServerConf 等是 go-zero 预定义的配置结构体,包含常用字段(Host、Port、Log、Prometheus、Telemetry 等),通过结构体嵌入复用。
3. 配置加载
通过 conf.MustLoad 加载配置:
go
// main.go
var configFile = flag.String("f", "etc/user-api.yaml", "the config file")
func main() {
flag.Parse()
var c config.Config
conf.MustLoad(*configFile, &c)
// 使用 c 初始化服务
}conf.MustLoad 的特点:
- 支持 YAML 和 JSON 格式(按文件扩展名判断)
- 支持环境变量覆盖
- 加载失败会 panic(适合启动时配置校验)
4. 环境变量覆盖
go-zero 支持用环境变量覆盖配置项,规则:
- 环境变量名 = 配置项路径,用
_连接,全大写 - 嵌套结构用
_分隔
例如配置:
yaml
MySQL:
DataSource: "local-dsn"对应环境变量:
bash
# 覆盖 MySQL.DataSource
export MYSQL_DATASOURCE="prod-dsn"多层嵌套:
yaml
UserRpc:
Etcd:
Hosts:
- 127.0.0.1:2379bash
# 覆盖 UserRpc.Etcd.Hosts(数组用逗号分隔)
export USERRPC_ETCD_HOSTS="10.0.0.1:2379,10.0.0.2:2379"这个机制在容器化部署时非常有用:用同一份配置文件,通过环境变量区分环境。
5. 配置校验
可以在结构体上加 tag 做校验(需要第三方库),或者在 NewServiceContext 里手动校验:
go
func NewServiceContext(c config.Config) *svc.ServiceContext {
// 校验必填项
if c.MySQL.DataSource == "" {
logx.Must(fmt.Errorf("MySQL.DataSource is required"))
}
if c.Auth.AccessSecret == "" {
logx.Must(fmt.Errorf("Auth.AccessSecret is required"))
}
// ...
}更优雅的方式是用 conf.LoadConfig 并配合校验库:
go
import "github.com/go-playground/validator/v10"
var validate = validator.New()
func main() {
var c config.Config
conf.MustLoad(*configFile, &c)
if err := validate.Struct(&c); err != nil {
logx.Must(fmt.Errorf("config invalid: %v", err))
}
}
// 在结构体上加校验 tag
type Config struct {
MySQL struct {
DataSource string `validate:"required"`
}
}二、API 服务配置
1. RestConf:HTTP 配置
rest.RestConf 是 API 服务的核心配置,定义在 core/rest/config.go:
go
type RestConf struct {
service.ServiceConf // 嵌入通用服务配置(Log、Prometheus、Telemetry 等)
Host string `json:",default=0.0.0.0"`
Port int
CertFile string `json:",optional"`
KeyFile string `json:",optional"`
Verbose bool `json:",optional"`
MaxConns int `json:",default=10000"`
MaxBytes int64 `json:",default=1048576"`
Timeout int64 `json:",default=3000"` // 毫秒
CpuThreshold int64 `json:",default=900,range=[0:1000]"`
HealthCheckPath string `json:",default=/health"`
Middlewares MiddlewaresConf
MaxWaitDuration time.Duration `json:",default=60s"`
}字段说明:
| 字段 | 说明 | 默认值 |
|---|---|---|
Host | 监听地址 | 0.0.0.0 |
Port | 监听端口 | 必填 |
CertFile/KeyFile | HTTPS 证书(可选) | 无 |
Verbose | 是否打印详细日志 | false |
MaxConns | 最大并发连接数 | 10000 |
MaxBytes | 请求体最大字节数 | 1MB |
Timeout | 请求超时(毫秒) | 3000 |
CpuThreshold | CPU 使用率阈值(千分位) | 900(90%) |
HealthCheckPath | 健康检查路径 | /health |
Middlewares 控制内置中间件开关:
go
type MiddlewaresConf struct {
Trace bool `json:",default=true"` // 链路追踪
Recover bool `json:",default=true"` // panic 恢复
Stat bool `json:",default=true"` // 统计
Prometheus bool `json:",default=true"` // Prometheus 指标
MaxCpu int `json:",default=0"` // CPU 限制
}2. 完整 API 配置示例
yaml
Name: user-api
Host: 0.0.0.0
Port: 8888
Verbose: false
MaxConns: 10000
MaxBytes: 1048576
Timeout: 3000
CpuThreshold: 900
HealthCheckPath: /health
Middlewares:
Trace: true
Recover: true
Stat: true
Prometheus: true
Auth:
AccessSecret: "your-256-bit-secret-key"
AccessExpire: 86400
MySQL:
DataSource: root:123456@tcp(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=true&loc=Local
CacheRedis:
- Host: 127.0.0.1:6379
Type: node
UserRpc:
Etcd:
Hosts:
- 127.0.0.1:2379
Key: user.rpc
NonBlock: true
Timeout: 2000
Log:
ServiceName: user-api
Mode: file
Path: logs
Level: info
KeepDays: 7
Compress: true
Prometheus:
Host: 0.0.0.0
Port: 9100
Path: /metrics
Telemetry:
Name: user-api
Endpoint: http://127.0.0.1:14268/api/traces
Sampler: 1.0
Batcher: jaeger三、RPC 服务配置
1. RpcServerConf
RPC 服务端配置:
go
type RpcServerConf struct {
service.ServiceConf
ListenOn string
Etcd discov.EtcdConf `json:",optional"`
Auth bool `json:",optional"`
Redis redis.RedisKeyConf `json:",optional"`
StrictCtrl bool `json:",optional"`
Timeout int64 `json:",default=2000"`
CpuThreshold int64 `json:",default=900,range=[0:1000]"`
Health bool `json:",default=true"`
Middlewares ServerMiddlewaresConf
}字段说明:
| 字段 | 说明 |
|---|---|
ListenOn | 服务监听地址(ip:port) |
Etcd | etcd 服务注册配置(可选,不配则直连模式) |
Auth | 是否启用 gRPC 认证 |
Redis | gRPC 认证用的 Redis(存储 token) |
Timeout | 调用超时(毫秒) |
Health | 是否启用健康检查 |
2. RpcClientConf
RPC 客户端配置:
go
type RpcClientConf struct {
Etcd discov.EtcdConf `json:",optional"`
Endpoints []string `json:",optional"`
Target string `json:",optional"`
App string `json:",optional"`
Token string `json:",optional"`
NonBlock bool `json:",optional"`
Timeout int64 `json:",default=2000"`
KeepaliveTime time.Duration `json:",default=20s"`
Middlewares ClientMiddlewaresConf
}三种服务发现方式(三选一):
Etcd:通过 etcd 服务发现(推荐)Endpoints:直连多个实例(goctl 自动负载均衡)Target:gRPC 标准 target(如dns:///user.rpc:8080)
3. 完整 RPC 配置示例
服务端 etc/user.yaml:
yaml
Name: user.rpc
ListenOn: 0.0.0.0:8080
Timeout: 2000
CpuThreshold: 900
Health: true
Etcd:
Hosts:
- 127.0.0.1:2379
Key: user.rpc
# gRPC 认证(可选)
Auth: true
Redis:
Host: 127.0.0.1:6379
Type: node
Key: rpc:auth
MySQL:
DataSource: root:123456@tcp(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=true&loc=Local
CacheRedis:
- Host: 127.0.0.1:6379
Type: node
Log:
ServiceName: user.rpc
Mode: file
Path: logs
Level: info
KeepDays: 7
Prometheus:
Host: 0.0.0.0
Port: 9101
Path: /metrics
Telemetry:
Name: user.rpc
Endpoint: http://127.0.0.1:14268/api/traces
Sampler: 1.0
Batcher: jaeger四、多环境配置
1. 配置隔离方案
常见做法:每个环境一份配置文件,启动时通过 -f 指定。
etc/
├── user-api-dev.yaml # 开发环境
├── user-api-test.yaml # 测试环境
├── user-api-pre.yaml # 预发环境
└── user-api-prod.yaml # 生产环境启动命令:
bash
# 开发环境
go run user.go -f etc/user-api-dev.yaml
# 生产环境
./user-api -f etc/user-api-prod.yaml2. 配置差异
不同环境的配置差异主要体现在:
yaml
# dev:本地调试,详细日志
Log:
Level: debug
Mode: console
MySQL:
DataSource: root:123456@tcp(127.0.0.1:3306)/demo_dev
CacheRedis:
- Host: 127.0.0.1:6379
Type: node
Etcd:
Hosts:
- 127.0.0.1:2379
# test:测试环境
Log:
Level: info
Mode: file
MySQL:
DataSource: test:test@tcp(10.0.0.1:3306)/demo_test
CacheRedis:
- Host: 10.0.0.2:6379
Type: node
Etcd:
Hosts:
- 10.0.0.3:2379
# prod:生产环境
Log:
Level: error
Mode: file
KeepDays: 30
MySQL:
DataSource: prod:strong-pass@tcp(mysql-master:3306)/demo?charset=utf8mb4&parseTime=true&loc=Local
CacheRedis:
- Host: redis-master:6379
Type: node
Pass: prod-redis-pass
Etcd:
Hosts:
- etcd-1:2379
- etcd-2:2379
- etcd-3:23793. 敏感信息管理
敏感信息(密码、密钥)不应放在配置文件中,建议:
- 用环境变量覆盖
- 用配置中心管理
- 用 K8s Secret
环境变量覆盖示例:
bash
# 启动时注入环境变量
export MYSQL_DATASOURCE="prod:strong-pass@tcp(mysql:3306)/demo"
export AUTH_ACCESSSECRET="prod-secret-key"
./user-api -f etc/user-api-prod.yaml4. 配置模板化
如果多环境差异较大,可以用模板生成配置:
bash
# 用 envsubst 替换占位符
envsubst < etc/user-api.yaml.tmpl > etc/user-api-prod.yaml模板文件 user-api.yaml.tmpl:
yaml
Name: user-api
Host: 0.0.0.0
Port: ${API_PORT}
MySQL:
DataSource: ${MYSQL_DSN}
Auth:
AccessSecret: ${JWT_SECRET}启动时:
bash
export API_PORT=8888
export MYSQL_DSN="prod:pass@tcp(mysql:3306)/demo"
export JWT_SECRET="prod-secret"
envsubst < etc/user-api.yaml.tmpl > /tmp/user-api.yaml
./user-api -f /tmp/user-api.yaml五、配置中心集成
1. 从 etcd 读取配置
go-zero 支持把配置存到 etcd,启动时从 etcd 拉取:
go
// main.go
import "github.com/zeromicro/go-zero/core/conf"
var (
configFile = flag.String("f", "etc/user-api.yaml", "local config")
configKey = flag.String("k", "", "etcd config key")
etcdHosts = flag.String("e", "", "etcd hosts, comma separated")
)
func main() {
flag.Parse()
var c config.Config
if *configKey != "" {
// 从 etcd 读取配置
conf.MustLoadFromEtcd(*etcdHosts, *configKey, &c)
} else {
// 从本地文件读取
conf.MustLoad(*configFile, &c)
}
// ...
}在 etcd 中存储配置:
bash
# 写入配置到 etcd
etcdctl --endpoints=127.0.0.1:2379 put /config/user-api/prod < etc/user-api-prod.yaml
# 读取验证
etcdctl --endpoints=127.0.0.1:2379 get /config/user-api/prod启动服务:
bash
./user-api -k /config/user-api/prod -e 127.0.0.1:23792. 热更新配置
go-zero 内置的配置加载是「一次性」的(启动时加载),不支持自动热更新。如果需要热更新,可以监听 etcd 变更:
go
import (
"github.com/zeromicro/go-zero/core/discov"
"github.com/zeromicro/go-zero/core/stores/etcd"
)
func watchConfig(etcdHosts []string, key string, onChange func(content string)) {
client := etcd.NewEtcd(etcdHosts)
ch := client.Watch(key)
go func() {
for event := range ch {
if event.Type == etcd.EventTypePut {
onChange(string(event.Kv.Value))
}
}
}()
}
// 使用
watchConfig([]string{"127.0.0.1:2379"}, "/config/user-api/prod", func(content string) {
logx.Info("config changed, reloading...")
var c config.Config
if err := conf.LoadFromYamlBytes([]byte(content), &c); err != nil {
logx.Errorf("reload config failed: %v", err)
return
}
// 更新运行时配置(需要服务支持)
// 注意:不是所有配置都支持热更新,如 Port、Host 等
})支持热更新的配置项通常有限,比如:
- 日志级别
- 限流阈值
- 功能开关
- 黑白名单
而端口、数据库连接、etcd 地址等不适合热更新(需要重启服务)。
3. 配置中心选型
除了 etcd,也可以用其他配置中心:
- Apollo(携程开源):功能丰富,支持灰度发布、权限管理
- Nacos(阿里开源):配置 + 注册中心一体
- Consul:服务发现 + 配置
- etcd:go-zero 原生支持,简单轻量
go-zero 与 etcd 集成最自然,推荐中小项目用 etcd;大型团队可以考虑 Apollo/Nacos。
六、Docker 化部署
1. Dockerfile
go-zero 服务的 Dockerfile 推荐用多阶段构建:
dockerfile
# 构建阶段
FROM golang:1.20-alpine AS builder
# 安装必要工具
RUN apk add --no-cache git
WORKDIR /app
# 缓存依赖
COPY go.mod go.sum ./
RUN go mod download
# 复制源码并构建
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /app/user-api user.go
# 运行阶段
FROM alpine:3.18
# 安装 CA 证书(HTTPS 调用需要)
RUN apk --no-cache add ca-certificates tzdata
ENV TZ=Asia/Shanghai
WORKDIR /app
# 复制二进制和配置
COPY --from=builder /app/user-api /app/user-api
COPY --from=builder /app/etc /app/etc
EXPOSE 8888
ENTRYPOINT ["/app/user-api", "-f", "/app/etc/user-api.yaml"]构建和运行:
bash
# 构建镜像
docker build -t user-api:v1 .
# 运行
docker run -d --name user-api \
-p 8888:8888 \
-e MYSQL_DATASOURCE="prod:pass@tcp(mysql:3306)/demo" \
user-api:v12. 用 goctl 生成 Dockerfile
goctl 可以自动生成 Dockerfile:
bash
goctl docker -go user.go -port 8888 -exe user-api生成的 Dockerfile 与上面的类似,可以根据需要调整。
3. docker-compose 编排
开发环境用 docker-compose 编排所有服务:
yaml
# docker-compose.yml
version: "3.8"
services:
# 基础设施
mysql:
image: mysql:8.0
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: "123456"
MYSQL_DATABASE: "demo"
volumes:
- mysql-data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
redis:
image: redis:7-alpine
ports:
- "6379:6379"
etcd:
image: bitnami/etcd:3.5
ports:
- "2379:2379"
environment:
- ALLOW_NONE_AUTHENTICATION=yes
- ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
jaeger:
image: jaegertracing/all-in-one:1.45
ports:
- "16686:16686"
- "4318:4318"
# 业务服务
user-rpc:
build: ./user-rpc
ports:
- "8080:8080"
depends_on:
- mysql
- redis
- etcd
environment:
- MYSQL_DATASOURCE=root:123456@tcp(mysql:3306)/demo?charset=utf8mb4&parseTime=true&loc=Local
restart: on-failure
user-api:
build: ./user-api
ports:
- "8888:8888"
depends_on:
- user-rpc
- redis
- etcd
environment:
- MYSQL_DATASOURCE=root:123456@tcp(mysql:3306)/demo?charset=utf8mb4&parseTime=true&loc=Local
restart: on-failure
volumes:
mysql-data:注意:docker-compose 中服务间用服务名互访(如 mysql:3306),配置文件中也要用服务名。
4. 镜像优化
减小镜像大小:
dockerfile
# 用 scratch 作为基础镜像(最小)
FROM scratch
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=builder /app/user-api /user-api
COPY --from=builder /app/etc /etc
ENTRYPOINT ["/user-api", "-f", "/etc/user-api.yaml"]scratch 镜像约 10-20MB,但缺少 shell,调试不便。生产环境可以用 alpine(约 5-10MB 基础 + 业务)。
构建参数优化:
bash
# 去除调试信息
go build -ldflags="-s -w" -o user-api user.go
# UPX 压缩(可选,进一步减小体积)
upx --best --lzma user-api七、Kubernetes 部署
1. Deployment
yaml
# k8s/user-api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-api
namespace: production
labels:
app: user-api
spec:
replicas: 3
selector:
matchLabels:
app: user-api
template:
metadata:
labels:
app: user-api
spec:
containers:
- name: user-api
image: registry.cn-hangzhou.aliyuncs.com/myrepo/user-api:v1
ports:
- containerPort: 8888
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "512Mi"
env:
- name: MYSQL_DATASOURCE
valueFrom:
secretKeyRef:
name: db-secret
key: mysql-dsn
- name: AUTH_ACCESSSECRET
valueFrom:
secretKeyRef:
name: jwt-secret
key: access-secret
volumeMounts:
- name: config
mountPath: /app/etc
readinessProbe:
httpGet:
path: /health
port: 8888
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /health
port: 8888
initialDelaySeconds: 30
periodSeconds: 30
volumes:
- name: config
configMap:
name: user-api-config2. ConfigMap
把非敏感配置放 ConfigMap:
yaml
# k8s/user-api-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: user-api-config
namespace: production
data:
user-api.yaml: |
Name: user-api
Host: 0.0.0.0
Port: 8888
Timeout: 3000
MySQL:
DataSource: root:123456@tcp(mysql:3306)/demo?charset=utf8mb4&parseTime=true&loc=Local
CacheRedis:
- Host: redis:6379
Type: node
UserRpc:
Etcd:
Hosts:
- etcd:2379
Key: user.rpc
NonBlock: true
Timeout: 2000
Log:
ServiceName: user-api
Mode: file
Path: logs
Level: info
KeepDays: 7
Prometheus:
Host: 0.0.0.0
Port: 9100
Path: /metrics敏感信息放 Secret:
yaml
# k8s/user-api-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-secret
namespace: production
type: Opaque
stringData:
mysql-dsn: "prod:strong-pass@tcp(mysql-master:3306)/demo"
---
apiVersion: v1
kind: Secret
metadata:
name: jwt-secret
namespace: production
type: Opaque
stringData:
access-secret: "prod-jwt-secret-key"3. Service
yaml
# k8s/user-api-service.yaml
apiVersion: v1
kind: Service
metadata:
name: user-api
namespace: production
spec:
selector:
app: user-api
ports:
- name: http
port: 80
targetPort: 8888
protocol: TCP
- name: metrics
port: 9100
targetPort: 9100
protocol: TCP
type: ClusterIP如果需要对外暴露,用 Ingress:
yaml
# k8s/user-api-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: user-api-ingress
namespace: production
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: user-api
port:
number: 804. HPA 自动扩缩容
yaml
# k8s/user-api-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: user-api
namespace: production
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: user-api
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 805. 用 goctl 生成 K8s 部署文件
goctl 可以一键生成 K8s 部署文件:
bash
goctl kube deploy -name user-api \
-namespace production \
-image registry.cn-hangzhou.aliyuncs.com/myrepo/user-api:v1 \
-secret db-secret \
-configMap user-api-config \
-port 8888 \
-replicas 3 \
-o k8s/user-api.yaml6. 完整部署流程
bash
# 1. 创建命名空间
kubectl create namespace production
# 2. 应用配置
kubectl apply -f k8s/user-api-configmap.yaml
kubectl apply -f k8s/user-api-secret.yaml
kubectl apply -f k8s/user-api-deployment.yaml
kubectl apply -f k8s/user-api-service.yaml
kubectl apply -f k8s/user-api-hpa.yaml
# 3. 查看状态
kubectl get pods -n production -l app=user-api
kubectl logs -f deployment/user-api -n production
# 4. 滚动更新
kubectl set image deployment/user-api user-api=registry.cn-hangzhou.aliyuncs.com/myrepo/user-api:v2 -n production
# 5. 回滚
kubectl rollout undo deployment/user-api -n production八、配置管理最佳实践
1. 配置分层
默认配置(代码内默认值)
↓ 覆盖
环境配置(YAML 文件)
↓ 覆盖
环境变量(容器/K8s)
↓ 覆盖
配置中心(动态配置)越上层越通用,越下层越具体。
2. 敏感信息保护
- 密码、密钥、token 不进 Git
- 用 Secret Manager 或 K8s Secret
- 配置文件用占位符,启动时注入
- 日志中不要打印敏感配置
3. 配置版本化
- 配置文件随代码一起版本管理
- 配置变更走 Code Review
- 配置中心支持历史版本回滚
4. 配置校验
- 启动时校验必填项
- 用单元测试覆盖配置解析
- CI 流程中校验配置语法
go
// config_test.go
func TestConfigLoad(t *testing.T) {
var c Config
err := conf.LoadConfig("etc/user-api.yaml", &c)
assert.NoError(t, err)
assert.NotEmpty(t, c.MySQL.DataSource)
assert.NotEmpty(t, c.Auth.AccessSecret)
}5. 配置文档
为每个配置项写文档,可以用 struct 注释:
go
type Config struct {
rest.RestConf
MySQL struct {
// DataSource 是 MySQL 连接串,格式:user:pass@tcp(host:port)/db
DataSource string
}
Auth struct {
// AccessSecret 是 JWT 签名密钥,至少 32 字符
AccessSecret string
// AccessExpire 是 token 过期时间(秒)
AccessExpire int64
}
}九、小结
本篇讲解了 go-zero 的配置管理与多环境部署。要点回顾:
- 配置采用 YAML 文件 + Go 结构体,支持环境变量覆盖
rest.RestConf和zrpc.RpcServerConf是核心配置结构,包含内置中间件、监控、链路追踪等开关- 多环境配置隔离:每个环境一份 YAML,启动时
-f指定 - 配置中心集成:etcd 存储 + 热更新监听(部分配置项支持)
- Docker 化部署:多阶段构建,镜像优化(alpine/scratch)
- K8s 部署:Deployment + ConfigMap + Secret + Service + HPA
- goctl 可自动生成 Dockerfile 和 K8s 部署文件
- 敏感信息用 Secret 管理,配置文件用占位符
- 配置分层、版本化、校验、文档化是最佳实践
下一篇我们将进入日志、监控与链路追踪,讲解 go-zero 的可观测性体系。