11 KiB
11 KiB
📋 最佳实践指南
开发最佳实践
1. 代码规范
# 格式化代码
gofmt -w .
goimports -w .
# 代码检查
golangci-lint run
# 生成文档
godoc -http=:6060
编码标准:
- 遵循 Go 官方编码规范
- 使用有意义的变量和函数名
- 保持函数简洁,单一职责
- 添加必要的注释和文档
2. Git 工作流
# 功能分支开发
git checkout -b feature/user-profile
git add .
git commit -m "feat: add user profile management"
git push origin feature/user-profile
# 代码审查后合并
git checkout main
git merge feature/user-profile
git push origin main
提交规范:
feat: 新功能fix: 修复问题docs: 文档更新style: 代码格式修改refactor: 代码重构test: 测试相关chore: 构建过程或辅助工具的变动
3. 测试策略
# 运行所有测试
make test
# 只运行单元测试
go test ./internal/domains/...
# 运行集成测试
go test -tags=integration ./test/integration/...
# 生成覆盖率报告
make test-coverage
open coverage.html
测试金字塔:
- 单元测试:70% - 测试单个函数/方法
- 集成测试:20% - 测试模块间交互
- 端到端测试:10% - 测试完整用户流程
4. 错误处理
// 统一错误处理
func (s *userService) CreateUser(ctx context.Context, req *dto.CreateUserRequest) (*dto.UserResponse, error) {
// 参数验证
if err := req.Validate(); err != nil {
return nil, errors.NewValidationError("invalid request", err)
}
// 业务逻辑
user, err := s.userRepo.Create(ctx, req.ToEntity())
if err != nil {
s.logger.Error("failed to create user", zap.Error(err))
return nil, errors.NewInternalError("failed to create user")
}
return dto.ToUserResponse(user), nil
}
5. 日志记录
// 结构化日志
logger.Info("user created successfully",
zap.String("user_id", user.ID),
zap.String("username", user.Username),
zap.Duration("duration", time.Since(start)))
// 错误日志
logger.Error("database connection failed",
zap.Error(err),
zap.String("host", dbHost),
zap.String("database", dbName))
日志级别使用:
DEBUG: 详细调试信息INFO: 一般信息记录WARN: 警告信息ERROR: 错误信息FATAL: 致命错误
安全最佳实践
1. 认证和授权
// JWT 令牌配置
type JWTConfig struct {
Secret string `yaml:"secret"`
AccessTokenTTL time.Duration `yaml:"access_token_ttl"`
RefreshTokenTTL time.Duration `yaml:"refresh_token_ttl"`
Issuer string `yaml:"issuer"`
}
// 密码加密
func HashPassword(password string) (string, error) {
bytes, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
return string(bytes), err
}
2. 输入验证
// 请求验证
type CreateUserRequest struct {
Username string `json:"username" validate:"required,min=3,max=20,alphanum"`
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=8,containsany=!@#$%^&*"`
}
func (r *CreateUserRequest) Validate() error {
validate := validator.New()
return validate.Struct(r)
}
3. SQL 注入防护
// 使用参数化查询
func (r *userRepository) FindByEmail(ctx context.Context, email string) (*entities.User, error) {
var user entities.User
err := r.db.WithContext(ctx).
Where("email = ?", email). // 参数化查询
First(&user).Error
return &user, err
}
4. HTTPS 配置
# 生产环境配置
server:
tls:
enabled: true
cert_file: "/etc/ssl/certs/server.crt"
key_file: "/etc/ssl/private/server.key"
min_version: "1.2"
性能最佳实践
1. 数据库优化
// 连接池配置
func setupDB(config *config.DatabaseConfig) (*gorm.DB, error) {
db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{})
if err != nil {
return nil, err
}
sqlDB, err := db.DB()
if err != nil {
return nil, err
}
// 连接池设置
sqlDB.SetMaxOpenConns(config.MaxOpenConns) // 最大连接数
sqlDB.SetMaxIdleConns(config.MaxIdleConns) // 最大空闲连接
sqlDB.SetConnMaxLifetime(config.ConnMaxLifetime) // 连接最大生命周期
return db, nil
}
查询优化:
-- 添加索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_created_at ON users(created_at);
-- 复合索引
CREATE INDEX idx_users_status_created ON users(status, created_at);
2. 缓存策略
// 多级缓存
type CacheService struct {
localCache cache.Cache
redisCache redis.Client
ttl time.Duration
}
func (c *CacheService) Get(ctx context.Context, key string) (string, error) {
// L1: 本地缓存
if value, ok := c.localCache.Get(key); ok {
return value.(string), nil
}
// L2: Redis 缓存
value, err := c.redisCache.Get(ctx, key).Result()
if err == nil {
c.localCache.Set(key, value, c.ttl)
return value, nil
}
return "", cache.ErrCacheMiss
}
3. 异步处理
// 使用工作池处理任务
type WorkerPool struct {
workers int
jobQueue chan Job
wg sync.WaitGroup
}
func (wp *WorkerPool) Start() {
for i := 0; i < wp.workers; i++ {
wp.wg.Add(1)
go wp.worker()
}
}
func (wp *WorkerPool) Submit(job Job) {
wp.jobQueue <- job
}
4. 内存管理
// 对象池减少GC压力
var bufferPool = sync.Pool{
New: func() interface{} {
return make([]byte, 4096)
},
}
func processData(data []byte) error {
buffer := bufferPool.Get().([]byte)
defer bufferPool.Put(buffer)
// 使用buffer处理数据
return nil
}
运维最佳实践
1. 监控告警
关键指标监控:
# Prometheus 告警规则
groups:
- name: tyapi-server
rules:
- alert: HighErrorRate
expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.01
labels:
severity: critical
annotations:
summary: "High error rate detected"
- alert: HighResponseTime
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 0.5
labels:
severity: warning
annotations:
summary: "High response time detected"
2. 备份策略
#!/bin/bash
# 数据库备份脚本
BACKUP_DIR="/backups/tyapi"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/tyapi_backup_$DATE.sql"
# 创建备份
pg_dump -h localhost -U postgres tyapi_prod > $BACKUP_FILE
# 压缩备份文件
gzip $BACKUP_FILE
# 保留最近7天的备份
find $BACKUP_DIR -name "*.sql.gz" -mtime +7 -delete
# 上传到云存储
aws s3 cp $BACKUP_FILE.gz s3://tyapi-backups/
3. 配置管理
# 生产环境配置模板
server:
port: 8080
mode: release
read_timeout: 30s
write_timeout: 30s
database:
host: ${DB_HOST}
port: ${DB_PORT}
user: ${DB_USER}
password: ${DB_PASSWORD}
name: ${DB_NAME}
max_open_conns: 100
max_idle_conns: 10
redis:
host: ${REDIS_HOST}
port: ${REDIS_PORT}
password: ${REDIS_PASSWORD}
pool_size: 10
security:
jwt_secret: ${JWT_SECRET}
bcrypt_cost: 12
logging:
level: info
format: json
output: stdout
4. 容器化最佳实践
# 多阶段构建 Dockerfile
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./cmd/api
FROM alpine:3.18
# 安全加固
RUN adduser -D -s /bin/sh appuser
RUN apk --no-cache add ca-certificates tzdata
WORKDIR /root/
COPY --from=builder /app/main .
COPY --from=builder /app/config.yaml .
USER appuser
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/api/v1/health || exit 1
CMD ["./main"]
团队协作最佳实践
1. 代码审查
审查检查清单:
- 代码符合项目规范
- 测试覆盖率充足
- 错误处理正确
- 性能影响评估
- 安全漏洞检查
- 文档更新
2. CI/CD 流程
# GitHub Actions 示例
name: CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v3
with:
go-version: 1.21
- name: Run tests
run: |
go test -v -race -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
- name: Upload coverage
uses: codecov/codecov-action@v3
deploy:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Deploy to production
run: |
echo "Deploying to production..."
3. 文档维护
- API 文档:使用 Swagger/OpenAPI 自动生成
- 架构文档:定期更新系统架构图
- 运维手册:记录部署和运维流程
- 故障手册:记录常见问题和解决方案
4. 版本管理
# 语义化版本控制
git tag v1.2.3
# 版本发布流程
git checkout main
git pull origin main
git tag v1.2.3
git push origin v1.2.3
版本号规则:
- MAJOR:不兼容的 API 修改
- MINOR:向下兼容的功能性新增
- PATCH:向下兼容的问题修正
扩展性最佳实践
1. 微服务拆分
拆分原则:
- 按业务边界拆分
- 保持服务自治
- 数据库分离
- 独立部署
2. 事件驱动架构
// 事件发布
type EventBus interface {
Publish(ctx context.Context, event Event) error
Subscribe(eventType string, handler EventHandler) error
}
// 事件处理
func (h *UserEventHandler) HandleUserCreated(ctx context.Context, event *UserCreatedEvent) error {
// 发送欢迎邮件
return h.emailService.SendWelcomeEmail(ctx, event.UserID)
}
3. 配置外部化
// 配置热重载
type ConfigManager struct {
config *Config
watchers []ConfigWatcher
}
func (cm *ConfigManager) Watch() {
for {
if changed := cm.checkConfigChange(); changed {
cm.reloadConfig()
cm.notifyWatchers()
}
time.Sleep(time.Second * 10)
}
}
4. 服务治理
- 服务注册与发现
- 负载均衡
- 熔断器
- 限流器
- 链路追踪
通过遵循这些最佳实践,可以确保 TYAPI Server 项目的高质量、高性能和高可维护性。