feat(架构): 完善基础架构设计
This commit is contained in:
536
docs/开始指南/最佳实践指南.md
Normal file
536
docs/开始指南/最佳实践指南.md
Normal file
@@ -0,0 +1,536 @@
|
||||
# 📋 最佳实践指南
|
||||
|
||||
## 开发最佳实践
|
||||
|
||||
### 1. 代码规范
|
||||
|
||||
```bash
|
||||
# 格式化代码
|
||||
gofmt -w .
|
||||
goimports -w .
|
||||
|
||||
# 代码检查
|
||||
golangci-lint run
|
||||
|
||||
# 生成文档
|
||||
godoc -http=:6060
|
||||
```
|
||||
|
||||
**编码标准**:
|
||||
|
||||
- 遵循 Go 官方编码规范
|
||||
- 使用有意义的变量和函数名
|
||||
- 保持函数简洁,单一职责
|
||||
- 添加必要的注释和文档
|
||||
|
||||
### 2. Git 工作流
|
||||
|
||||
```bash
|
||||
# 功能分支开发
|
||||
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. 测试策略
|
||||
|
||||
```bash
|
||||
# 运行所有测试
|
||||
make test
|
||||
|
||||
# 只运行单元测试
|
||||
go test ./internal/domains/...
|
||||
|
||||
# 运行集成测试
|
||||
go test -tags=integration ./test/integration/...
|
||||
|
||||
# 生成覆盖率报告
|
||||
make test-coverage
|
||||
open coverage.html
|
||||
```
|
||||
|
||||
**测试金字塔**:
|
||||
|
||||
- **单元测试**:70% - 测试单个函数/方法
|
||||
- **集成测试**:20% - 测试模块间交互
|
||||
- **端到端测试**:10% - 测试完整用户流程
|
||||
|
||||
### 4. 错误处理
|
||||
|
||||
```go
|
||||
// 统一错误处理
|
||||
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. 日志记录
|
||||
|
||||
```go
|
||||
// 结构化日志
|
||||
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. 认证和授权
|
||||
|
||||
```go
|
||||
// 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. 输入验证
|
||||
|
||||
```go
|
||||
// 请求验证
|
||||
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 注入防护
|
||||
|
||||
```go
|
||||
// 使用参数化查询
|
||||
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 配置
|
||||
|
||||
```yaml
|
||||
# 生产环境配置
|
||||
server:
|
||||
tls:
|
||||
enabled: true
|
||||
cert_file: "/etc/ssl/certs/server.crt"
|
||||
key_file: "/etc/ssl/private/server.key"
|
||||
min_version: "1.2"
|
||||
```
|
||||
|
||||
## 性能最佳实践
|
||||
|
||||
### 1. 数据库优化
|
||||
|
||||
```go
|
||||
// 连接池配置
|
||||
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
|
||||
}
|
||||
```
|
||||
|
||||
**查询优化**:
|
||||
|
||||
```sql
|
||||
-- 添加索引
|
||||
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. 缓存策略
|
||||
|
||||
```go
|
||||
// 多级缓存
|
||||
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. 异步处理
|
||||
|
||||
```go
|
||||
// 使用工作池处理任务
|
||||
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. 内存管理
|
||||
|
||||
```go
|
||||
// 对象池减少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. 监控告警
|
||||
|
||||
**关键指标监控**:
|
||||
|
||||
```yaml
|
||||
# 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. 备份策略
|
||||
|
||||
```bash
|
||||
#!/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. 配置管理
|
||||
|
||||
```yaml
|
||||
# 生产环境配置模板
|
||||
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
|
||||
# 多阶段构建 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 流程
|
||||
|
||||
```yaml
|
||||
# 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. 版本管理
|
||||
|
||||
```bash
|
||||
# 语义化版本控制
|
||||
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. 事件驱动架构
|
||||
|
||||
```go
|
||||
// 事件发布
|
||||
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. 配置外部化
|
||||
|
||||
```go
|
||||
// 配置热重载
|
||||
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 项目的高质量、高性能和高可维护性。
|
||||
Reference in New Issue
Block a user