Initial commit: Basic project structure and dependencies
This commit is contained in:
316
docs/API使用指南.md
Normal file
316
docs/API使用指南.md
Normal file
@@ -0,0 +1,316 @@
|
||||
# 🌐 API 使用指南
|
||||
|
||||
## 认证机制
|
||||
|
||||
### 1. 用户注册
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/auth/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"email": "test@example.com",
|
||||
"password": "Test123!@#"
|
||||
}'
|
||||
```
|
||||
|
||||
### 2. 用户登录
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "testuser",
|
||||
"password": "Test123!@#"
|
||||
}'
|
||||
```
|
||||
|
||||
响应示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"access_token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"refresh_token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"expires_in": 86400,
|
||||
"user": {
|
||||
"id": 1,
|
||||
"username": "testuser",
|
||||
"email": "test@example.com"
|
||||
}
|
||||
},
|
||||
"request_id": "req_123456789",
|
||||
"timestamp": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 使用访问令牌
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/users/profile \
|
||||
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
|
||||
```
|
||||
|
||||
## 用户管理 API
|
||||
|
||||
### 获取用户列表
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/api/v1/users?page=1&limit=10&search=test" \
|
||||
-H "Authorization: Bearer <access_token>"
|
||||
```
|
||||
|
||||
### 获取用户详情
|
||||
|
||||
```bash
|
||||
curl -X GET http://localhost:8080/api/v1/users/1 \
|
||||
-H "Authorization: Bearer <access_token>"
|
||||
```
|
||||
|
||||
### 更新用户信息
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/api/v1/users/1 \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"username": "newusername",
|
||||
"email": "newemail@example.com"
|
||||
}'
|
||||
```
|
||||
|
||||
### 修改密码
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/api/v1/users/change-password \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"current_password": "oldpassword",
|
||||
"new_password": "newpassword123"
|
||||
}'
|
||||
```
|
||||
|
||||
### 删除用户
|
||||
|
||||
```bash
|
||||
curl -X DELETE http://localhost:8080/api/v1/users/1 \
|
||||
-H "Authorization: Bearer <access_token>"
|
||||
```
|
||||
|
||||
## 响应格式
|
||||
|
||||
### 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
// 响应数据
|
||||
},
|
||||
"request_id": "req_123456789",
|
||||
"timestamp": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 分页响应
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "success",
|
||||
"data": {
|
||||
"items": [...],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
"total": 100,
|
||||
"total_pages": 10
|
||||
}
|
||||
},
|
||||
"request_id": "req_123456789",
|
||||
"timestamp": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "error",
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "请求参数无效",
|
||||
"details": {
|
||||
"username": ["用户名不能为空"],
|
||||
"email": ["邮箱格式不正确"]
|
||||
}
|
||||
},
|
||||
"request_id": "req_123456789",
|
||||
"timestamp": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 常用查询参数
|
||||
|
||||
### 分页参数
|
||||
|
||||
- `page`: 页码,从 1 开始
|
||||
- `limit`: 每页数量,默认 10,最大 100
|
||||
- `sort`: 排序字段,如 `created_at`
|
||||
- `order`: 排序方向,`asc` 或 `desc`
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
GET /api/v1/users?page=2&limit=20&sort=created_at&order=desc
|
||||
```
|
||||
|
||||
### 搜索参数
|
||||
|
||||
- `search`: 关键词搜索
|
||||
- `filter`: 字段过滤
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
GET /api/v1/users?search=john&filter=status:active
|
||||
```
|
||||
|
||||
### 时间范围参数
|
||||
|
||||
- `start_date`: 开始时间,ISO 8601 格式
|
||||
- `end_date`: 结束时间,ISO 8601 格式
|
||||
|
||||
示例:
|
||||
|
||||
```bash
|
||||
GET /api/v1/users?start_date=2024-01-01T00:00:00Z&end_date=2024-01-31T23:59:59Z
|
||||
```
|
||||
|
||||
## HTTP 状态码
|
||||
|
||||
### 成功状态码
|
||||
|
||||
- `200 OK`: 请求成功
|
||||
- `201 Created`: 创建成功
|
||||
- `202 Accepted`: 请求已接受,正在处理
|
||||
- `204 No Content`: 成功,无返回内容
|
||||
|
||||
### 客户端错误
|
||||
|
||||
- `400 Bad Request`: 请求参数错误
|
||||
- `401 Unauthorized`: 未认证
|
||||
- `403 Forbidden`: 无权限
|
||||
- `404 Not Found`: 资源不存在
|
||||
- `409 Conflict`: 资源冲突
|
||||
- `422 Unprocessable Entity`: 请求格式正确但语义错误
|
||||
- `429 Too Many Requests`: 请求过于频繁
|
||||
|
||||
### 服务器错误
|
||||
|
||||
- `500 Internal Server Error`: 服务器内部错误
|
||||
- `502 Bad Gateway`: 网关错误
|
||||
- `503 Service Unavailable`: 服务不可用
|
||||
- `504 Gateway Timeout`: 网关超时
|
||||
|
||||
## API 测试
|
||||
|
||||
### 使用 Postman
|
||||
|
||||
1. 导入 API 集合文件(如果有)
|
||||
2. 设置环境变量:
|
||||
- `base_url`: http://localhost:8080
|
||||
- `access_token`: 从登录接口获取
|
||||
|
||||
### 使用 curl 脚本
|
||||
|
||||
创建测试脚本 `test_api.sh`:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
BASE_URL="http://localhost:8080"
|
||||
ACCESS_TOKEN=""
|
||||
|
||||
# 登录获取token
|
||||
login() {
|
||||
response=$(curl -s -X POST "$BASE_URL/api/v1/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"admin123"}')
|
||||
|
||||
ACCESS_TOKEN=$(echo $response | jq -r '.data.access_token')
|
||||
echo "Token: $ACCESS_TOKEN"
|
||||
}
|
||||
|
||||
# 测试用户API
|
||||
test_users() {
|
||||
echo "Testing Users API..."
|
||||
|
||||
# 获取用户列表
|
||||
curl -s -X GET "$BASE_URL/api/v1/users" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" | jq
|
||||
|
||||
# 创建用户
|
||||
curl -s -X POST "$BASE_URL/api/v1/users" \
|
||||
-H "Authorization: Bearer $ACCESS_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"testuser","email":"test@example.com","password":"test123"}' | jq
|
||||
}
|
||||
|
||||
# 执行测试
|
||||
login
|
||||
test_users
|
||||
```
|
||||
|
||||
## API 文档
|
||||
|
||||
启动服务后,访问以下地址获取完整 API 文档:
|
||||
|
||||
- **Swagger UI**: http://localhost:8080/swagger/
|
||||
- **API 规范**: http://localhost:8080/api/docs
|
||||
- **健康检查**: http://localhost:8080/api/v1/health
|
||||
|
||||
## 限流和配额
|
||||
|
||||
### 请求限制
|
||||
|
||||
- 默认每分钟 100 个请求
|
||||
- 突发请求限制 50 个
|
||||
- 超出限制返回 429 状态码
|
||||
|
||||
### 提高限制
|
||||
|
||||
如需提高限制,请联系管理员或在配置文件中调整:
|
||||
|
||||
```yaml
|
||||
rate_limit:
|
||||
enabled: true
|
||||
requests_per_minute: 200
|
||||
burst: 100
|
||||
```
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 常见错误及解决方案
|
||||
|
||||
1. **401 Unauthorized**
|
||||
|
||||
- 检查 Token 是否有效
|
||||
- 确认 Token 格式正确
|
||||
- 验证 Token 是否过期
|
||||
|
||||
2. **403 Forbidden**
|
||||
|
||||
- 检查用户权限
|
||||
- 确认访问的资源是否允许
|
||||
|
||||
3. **429 Too Many Requests**
|
||||
|
||||
- 降低请求频率
|
||||
- 实现指数退避重试
|
||||
|
||||
4. **500 Internal Server Error**
|
||||
- 检查服务器日志
|
||||
- 确认请求参数格式
|
||||
- 联系技术支持
|
||||
469
docs/ARCHITECTURE.md
Normal file
469
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,469 @@
|
||||
# TYAPI Server 架构设计文档
|
||||
|
||||
## 📖 概述
|
||||
|
||||
TYAPI Server 是一个基于现代化软件工程实践构建的企业级 Go Web 应用架构。本架构综合了领域驱动设计(DDD)、CQRS、事件驱动架构、微服务设计模式等先进理念,旨在提供一个高性能、可扩展、易维护的 Web 服务基础框架。
|
||||
|
||||
## 🏗️ 核心设计理念
|
||||
|
||||
### 1. 领域驱动设计 (Domain-Driven Design)
|
||||
|
||||
**理念**:将复杂的业务逻辑组织成清晰的业务域,每个域负责特定的业务职责。
|
||||
|
||||
**实现方式**:
|
||||
|
||||
- **实体(Entities)**:包含业务逻辑的核心对象
|
||||
- **值对象(Value Objects)**:不可变的数据对象
|
||||
- **聚合根(Aggregate Root)**:实体集合的统一入口
|
||||
- **仓储(Repository)**:数据访问的抽象层
|
||||
- **域服务(Domain Service)**:跨实体的业务逻辑
|
||||
- **域事件(Domain Event)**:业务状态变化的通知机制
|
||||
|
||||
**优势**:
|
||||
|
||||
- 业务逻辑与技术实现分离
|
||||
- 代码组织清晰,易于理解和维护
|
||||
- 支持复杂业务场景的建模
|
||||
|
||||
### 2. CQRS (Command Query Responsibility Segregation)
|
||||
|
||||
**理念**:将数据的读操作和写操作分离,优化不同场景下的性能需求。
|
||||
|
||||
**实现方式**:
|
||||
|
||||
- **命令端**:处理数据修改操作(Create、Update、Delete)
|
||||
- **查询端**:处理数据读取操作(Read、List、Search)
|
||||
- **读写模型分离**:不同的数据结构优化不同的操作
|
||||
|
||||
**优势**:
|
||||
|
||||
- 读写性能独立优化
|
||||
- 支持复杂查询需求
|
||||
- 易于实现缓存策略
|
||||
|
||||
### 3. 事件驱动架构 (Event-Driven Architecture)
|
||||
|
||||
**理念**:通过事件实现系统组件间的松耦合通信。
|
||||
|
||||
**实现方式**:
|
||||
|
||||
- **事件总线**:异步消息分发机制
|
||||
- **事件处理器**:响应特定事件的业务逻辑
|
||||
- **事件溯源**:通过事件重建系统状态
|
||||
|
||||
**优势**:
|
||||
|
||||
- 系统组件解耦
|
||||
- 支持异步处理
|
||||
- 易于扩展和集成
|
||||
|
||||
### 4. 六边形架构 (Hexagonal Architecture)
|
||||
|
||||
**理念**:将应用程序的核心逻辑与外部系统隔离,通过端口和适配器进行交互。
|
||||
|
||||
**实现方式**:
|
||||
|
||||
- **内层**:业务逻辑和域模型
|
||||
- **中层**:应用服务和用例
|
||||
- **外层**:适配器和基础设施
|
||||
|
||||
**优势**:
|
||||
|
||||
- 核心逻辑与技术实现解耦
|
||||
- 易于测试和替换组件
|
||||
- 支持多种接口类型
|
||||
|
||||
## 🛠️ 技术栈详解
|
||||
|
||||
### Web 框架层
|
||||
|
||||
#### Gin Framework
|
||||
|
||||
- **选择理由**:高性能、轻量级、丰富的中间件生态
|
||||
- **核心特性**:快速路由、中间件支持、JSON 绑定
|
||||
- **性能优势**:比其他 Go 框架快 40 倍,内存占用低
|
||||
|
||||
#### 中间件系统
|
||||
|
||||
- **CORS 中间件**:跨域资源共享控制
|
||||
- **认证中间件**:JWT token 验证和用户身份识别
|
||||
- **限流中间件**:API 调用频率控制,防止滥用
|
||||
- **日志中间件**:请求追踪和性能监控
|
||||
- **安全中间件**:HTTP 安全头部设置
|
||||
|
||||
### 数据层
|
||||
|
||||
#### PostgreSQL
|
||||
|
||||
- **选择理由**:强一致性、复杂查询支持、JSON 文档存储
|
||||
- **特性使用**:
|
||||
- JSONB 字段存储灵活数据
|
||||
- 全文搜索功能
|
||||
- 事务支持
|
||||
- 扩展生态(UUID、pg_trgm 等)
|
||||
|
||||
#### GORM
|
||||
|
||||
- **选择理由**:功能强大、活跃维护、Go 生态最佳
|
||||
- **核心特性**:
|
||||
- 自动迁移
|
||||
- 关联查询
|
||||
- 钩子函数
|
||||
- 事务支持
|
||||
- 连接池管理
|
||||
|
||||
#### Redis
|
||||
|
||||
- **使用场景**:
|
||||
- 应用缓存:查询结果缓存
|
||||
- 会话存储:用户登录状态
|
||||
- 限流计数:API 调用频率统计
|
||||
- 分布式锁:并发控制
|
||||
|
||||
### 基础设施层
|
||||
|
||||
#### 依赖注入 - Uber FX
|
||||
|
||||
- **优势**:
|
||||
- 编译时依赖检查
|
||||
- 生命周期管理
|
||||
- 模块化设计
|
||||
- 测试友好
|
||||
|
||||
#### 日志系统 - Zap
|
||||
|
||||
- **特性**:
|
||||
- 高性能结构化日志
|
||||
- 多级别日志控制
|
||||
- 灵活的输出格式
|
||||
- 生产环境优化
|
||||
|
||||
#### 配置管理 - Viper
|
||||
|
||||
- **支持格式**:YAML、JSON、ENV 等
|
||||
- **特性**:
|
||||
- 环境变量替换
|
||||
- 配置热重载
|
||||
- 多层级配置合并
|
||||
|
||||
### 监控和观测性
|
||||
|
||||
#### Prometheus + Grafana
|
||||
|
||||
- **Prometheus**:指标收集和存储
|
||||
- **Grafana**:数据可视化和告警
|
||||
- **监控指标**:
|
||||
- HTTP 请求量和延迟
|
||||
- 数据库连接池状态
|
||||
- 缓存命中率
|
||||
- 系统资源使用率
|
||||
|
||||
#### Jaeger
|
||||
|
||||
- **分布式链路追踪**:请求在系统中的完整路径
|
||||
- **性能分析**:识别性能瓶颈
|
||||
- **依赖图谱**:服务间依赖关系可视化
|
||||
|
||||
## 📁 架构分层
|
||||
|
||||
### 1. 表现层 (Presentation Layer)
|
||||
|
||||
```
|
||||
cmd/api/ # 应用程序入口
|
||||
├── main.go # 主程序启动
|
||||
└── handlers/ # HTTP处理器
|
||||
```
|
||||
|
||||
**职责**:
|
||||
|
||||
- HTTP 请求处理
|
||||
- 请求验证和响应格式化
|
||||
- 路由定义和中间件配置
|
||||
|
||||
### 2. 应用层 (Application Layer)
|
||||
|
||||
```
|
||||
internal/app/ # 应用协调
|
||||
├── app.go # 应用启动器
|
||||
└── container/ # 依赖注入容器
|
||||
```
|
||||
|
||||
**职责**:
|
||||
|
||||
- 应用程序生命周期管理
|
||||
- 依赖关系配置
|
||||
- 跨领域服务协调
|
||||
|
||||
### 3. 领域层 (Domain Layer)
|
||||
|
||||
```
|
||||
internal/domains/ # 业务领域
|
||||
├── user/ # 用户领域
|
||||
│ ├── entities/ # 实体
|
||||
│ ├── services/ # 领域服务
|
||||
│ ├── repositories/ # 仓储接口
|
||||
│ ├── events/ # 领域事件
|
||||
│ └── dto/ # 数据传输对象
|
||||
```
|
||||
|
||||
**职责**:
|
||||
|
||||
- 业务逻辑实现
|
||||
- 领域模型定义
|
||||
- 业务规则验证
|
||||
|
||||
### 4. 基础设施层 (Infrastructure Layer)
|
||||
|
||||
```
|
||||
internal/shared/ # 共享基础设施
|
||||
├── database/ # 数据库连接
|
||||
├── cache/ # 缓存服务
|
||||
├── events/ # 事件总线
|
||||
├── logger/ # 日志服务
|
||||
└── middleware/ # 中间件
|
||||
```
|
||||
|
||||
**职责**:
|
||||
|
||||
- 外部系统集成
|
||||
- 技术基础设施
|
||||
- 通用工具和服务
|
||||
|
||||
## 🔄 数据流向
|
||||
|
||||
### 请求处理流程
|
||||
|
||||
1. **HTTP 请求** → **路由器**
|
||||
2. **中间件链** → **认证/限流/日志**
|
||||
3. **处理器** → **请求验证**
|
||||
4. **应用服务** → **业务逻辑协调**
|
||||
5. **领域服务** → **业务规则执行**
|
||||
6. **仓储层** → **数据持久化**
|
||||
7. **事件总线** → **异步事件处理**
|
||||
8. **响应构建** → **HTTP 响应**
|
||||
|
||||
### 事件驱动流程
|
||||
|
||||
1. **业务操作** → **触发领域事件**
|
||||
2. **事件总线** → **异步分发事件**
|
||||
3. **事件处理器** → **响应事件处理**
|
||||
4. **副作用执行** → **缓存更新/通知发送**
|
||||
|
||||
## 🔒 安全设计
|
||||
|
||||
### 认证和授权
|
||||
|
||||
#### JWT Token 机制
|
||||
|
||||
- **访问令牌**:短期有效(24 小时)
|
||||
- **刷新令牌**:长期有效(7 天)
|
||||
- **无状态设计**:服务端无需存储会话
|
||||
|
||||
#### 安全中间件
|
||||
|
||||
- **CORS 保护**:跨域请求控制
|
||||
- **安全头部**:XSS、CSRF、点击劫持防护
|
||||
- **输入验证**:防止 SQL 注入和 XSS 攻击
|
||||
- **限流保护**:防止暴力破解和 DDoS
|
||||
|
||||
### 数据安全
|
||||
|
||||
#### 密码安全
|
||||
|
||||
- **Bcrypt 加密**:不可逆密码存储
|
||||
- **盐值随机**:防止彩虹表攻击
|
||||
- **密码策略**:强密码要求
|
||||
|
||||
#### 数据传输
|
||||
|
||||
- **HTTPS 强制**:加密数据传输
|
||||
- **API 版本控制**:向后兼容性
|
||||
- **敏感信息过滤**:日志脱敏
|
||||
|
||||
## 🚀 性能优化
|
||||
|
||||
### 缓存策略
|
||||
|
||||
#### 多级缓存
|
||||
|
||||
- **应用缓存**:查询结果缓存
|
||||
- **数据库缓存**:连接池和查询缓存
|
||||
- **CDN 缓存**:静态资源分发
|
||||
|
||||
#### 缓存模式
|
||||
|
||||
- **Cache-Aside**:应用控制缓存
|
||||
- **Write-Through**:同步写入缓存
|
||||
- **Write-Behind**:异步写入数据库
|
||||
|
||||
### 数据库优化
|
||||
|
||||
#### 连接池管理
|
||||
|
||||
- **最大连接数**:控制资源消耗
|
||||
- **空闲连接**:保持最小连接数
|
||||
- **连接超时**:防止连接泄露
|
||||
|
||||
#### 查询优化
|
||||
|
||||
- **索引策略**:覆盖常用查询
|
||||
- **分页查询**:避免大结果集
|
||||
- **预加载**:减少 N+1 查询问题
|
||||
|
||||
### 并发处理
|
||||
|
||||
#### Goroutine 池
|
||||
|
||||
- **有界队列**:控制并发数量
|
||||
- **优雅降级**:过载保护机制
|
||||
- **超时控制**:防止资源泄露
|
||||
|
||||
## 🧪 可测试性
|
||||
|
||||
### 测试策略
|
||||
|
||||
#### 单元测试
|
||||
|
||||
- **Mock 接口**:隔离外部依赖
|
||||
- **测试覆盖**:核心业务逻辑 100%覆盖
|
||||
- **快速反馈**:毫秒级测试执行
|
||||
|
||||
#### 集成测试
|
||||
|
||||
- **Testcontainers**:真实数据库环境
|
||||
- **API 测试**:端到端功能验证
|
||||
- **并发测试**:竞态条件检测
|
||||
|
||||
#### 测试工具
|
||||
|
||||
- **Testify**:断言和 Mock 框架
|
||||
- **GoConvey**:BDD 风格测试
|
||||
- **Ginkgo**:规范化测试结构
|
||||
|
||||
## 🔧 可维护性
|
||||
|
||||
### 代码组织
|
||||
|
||||
#### 包结构设计
|
||||
|
||||
- **按功能分包**:清晰的职责边界
|
||||
- **依赖方向**:依赖倒置原则
|
||||
- **接口隔离**:最小化接口暴露
|
||||
|
||||
#### 编码规范
|
||||
|
||||
- **Go 官方规范**:gofmt、golint 标准
|
||||
- **命名约定**:一致的命名风格
|
||||
- **注释文档**:完整的 API 文档
|
||||
|
||||
### 配置管理
|
||||
|
||||
#### 环境分离
|
||||
|
||||
- **开发环境**:详细日志、调试工具
|
||||
- **测试环境**:稳定配置、自动化测试
|
||||
- **生产环境**:性能优化、安全加固
|
||||
|
||||
#### 配置热更新
|
||||
|
||||
- **文件监控**:配置文件变化检测
|
||||
- **优雅重启**:无停机配置更新
|
||||
- **回滚机制**:配置错误恢复
|
||||
|
||||
## 🌐 可扩展性
|
||||
|
||||
### 水平扩展
|
||||
|
||||
#### 无状态设计
|
||||
|
||||
- **会话外置**:Redis 存储用户状态
|
||||
- **负载均衡**:多实例部署
|
||||
- **自动伸缩**:基于指标的扩缩容
|
||||
|
||||
#### 数据库扩展
|
||||
|
||||
- **读写分离**:主从复制架构
|
||||
- **分库分表**:水平分片策略
|
||||
- **缓存预热**:减少数据库压力
|
||||
|
||||
### 服务拆分
|
||||
|
||||
#### 微服务就绪
|
||||
|
||||
- **领域边界**:清晰的服务边界
|
||||
- **API 网关**:统一入口和路由
|
||||
- **服务发现**:动态服务注册
|
||||
|
||||
#### 通信机制
|
||||
|
||||
- **REST API**:同步通信标准
|
||||
- **消息队列**:异步解耦通信
|
||||
- **事件溯源**:状态重建机制
|
||||
|
||||
## 📈 监控和运维
|
||||
|
||||
### 可观测性三大支柱
|
||||
|
||||
#### 日志 (Logging)
|
||||
|
||||
- **结构化日志**:JSON 格式便于检索
|
||||
- **日志级别**:灵活的详细程度控制
|
||||
- **日志聚合**:集中式日志管理
|
||||
|
||||
#### 指标 (Metrics)
|
||||
|
||||
- **业务指标**:用户行为和业务 KPI
|
||||
- **技术指标**:系统性能和资源使用
|
||||
- **SLI/SLO**:服务水平指标和目标
|
||||
|
||||
#### 链路追踪 (Tracing)
|
||||
|
||||
- **请求追踪**:完整的请求处理路径
|
||||
- **性能分析**:识别瓶颈和优化点
|
||||
- **依赖分析**:服务间调用关系
|
||||
|
||||
### 运维自动化
|
||||
|
||||
#### 健康检查
|
||||
|
||||
- **多层级检查**:应用、数据库、缓存
|
||||
- **智能告警**:基于阈值的自动通知
|
||||
- **故障恢复**:自动重启和故障转移
|
||||
|
||||
#### 部署策略
|
||||
|
||||
- **蓝绿部署**:零停机更新
|
||||
- **滚动更新**:渐进式版本发布
|
||||
- **回滚机制**:快速恢复到稳定版本
|
||||
|
||||
## 🚀 未来演进方向
|
||||
|
||||
### 技术演进
|
||||
|
||||
#### 云原生
|
||||
|
||||
- **容器化**:Docker 标准化部署
|
||||
- **编排平台**:Kubernetes 集群管理
|
||||
- **服务网格**:Istio 流量治理
|
||||
|
||||
#### 新技术集成
|
||||
|
||||
- **GraphQL**:灵活的 API 查询语言
|
||||
- **gRPC**:高性能 RPC 通信
|
||||
- **WebAssembly**:高性能计算扩展
|
||||
|
||||
### 架构演进
|
||||
|
||||
#### 事件溯源
|
||||
|
||||
- **完整事件历史**:业务状态重建
|
||||
- **审计日志**:合规性和追溯性
|
||||
- **时间旅行**:历史状态查询
|
||||
|
||||
#### CQRS 进阶
|
||||
|
||||
- **独立数据存储**:读写数据库分离
|
||||
- **最终一致性**:分布式数据同步
|
||||
- **投影视图**:优化的查询模型
|
||||
|
||||
这个架构设计文档展示了 TYAPI Server 的完整技术架构和设计理念,为开发团队提供了全面的技术指导和最佳实践参考。
|
||||
279
docs/开发指南.md
Normal file
279
docs/开发指南.md
Normal file
@@ -0,0 +1,279 @@
|
||||
# 👨💻 开发指南
|
||||
|
||||
## 项目结构理解
|
||||
|
||||
```
|
||||
tyapi-server-gin/
|
||||
├── cmd/api/ # 应用入口
|
||||
├── internal/ # 内部代码
|
||||
│ ├── app/ # 应用层
|
||||
│ ├── config/ # 配置管理
|
||||
│ ├── container/ # 依赖注入
|
||||
│ ├── domains/ # 业务域
|
||||
│ │ └── user/ # 用户域示例
|
||||
│ └── shared/ # 共享基础设施
|
||||
├── pkg/ # 外部包
|
||||
├── scripts/ # 脚本文件
|
||||
├── test/ # 测试文件
|
||||
└── docs/ # 文档目录
|
||||
```
|
||||
|
||||
## 开发流程
|
||||
|
||||
### 1. 创建新的业务域
|
||||
|
||||
```bash
|
||||
# 使用Makefile创建新域
|
||||
make new-domain DOMAIN=product
|
||||
|
||||
# 手动创建目录结构
|
||||
mkdir -p internal/domains/product/{entities,dto,services,repositories,handlers,routes,events}
|
||||
```
|
||||
|
||||
### 2. 实现业务实体
|
||||
|
||||
创建 `internal/domains/product/entities/product.go`:
|
||||
|
||||
```go
|
||||
type Product struct {
|
||||
BaseEntity
|
||||
Name string `gorm:"not null;size:100"`
|
||||
Description string `gorm:"size:500"`
|
||||
Price float64 `gorm:"not null"`
|
||||
CategoryID uint `gorm:"not null"`
|
||||
}
|
||||
|
||||
func (p *Product) Validate() error {
|
||||
if p.Name == "" {
|
||||
return errors.New("产品名称不能为空")
|
||||
}
|
||||
if p.Price <= 0 {
|
||||
return errors.New("产品价格必须大于0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 定义仓储接口
|
||||
|
||||
创建 `internal/domains/product/repositories/product_repository.go`:
|
||||
|
||||
```go
|
||||
type ProductRepository interface {
|
||||
shared.BaseRepository[entities.Product]
|
||||
FindByCategory(ctx context.Context, categoryID uint) ([]*entities.Product, error)
|
||||
FindByPriceRange(ctx context.Context, min, max float64) ([]*entities.Product, error)
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 实现业务服务
|
||||
|
||||
创建 `internal/domains/product/services/product_service.go`:
|
||||
|
||||
```go
|
||||
type ProductService interface {
|
||||
CreateProduct(ctx context.Context, req *dto.CreateProductRequest) (*dto.ProductResponse, error)
|
||||
GetProduct(ctx context.Context, id uint) (*dto.ProductResponse, error)
|
||||
UpdateProduct(ctx context.Context, id uint, req *dto.UpdateProductRequest) (*dto.ProductResponse, error)
|
||||
DeleteProduct(ctx context.Context, id uint) error
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 实现 HTTP 处理器
|
||||
|
||||
创建 `internal/domains/product/handlers/product_handler.go`:
|
||||
|
||||
```go
|
||||
func (h *ProductHandler) CreateProduct(c *gin.Context) {
|
||||
var req dto.CreateProductRequest
|
||||
if err := c.ShouldBindJSON(&req); err != nil {
|
||||
response.Error(c, http.StatusBadRequest, "请求参数无效", err)
|
||||
return
|
||||
}
|
||||
|
||||
product, err := h.productService.CreateProduct(c.Request.Context(), &req)
|
||||
if err != nil {
|
||||
response.Error(c, http.StatusInternalServerError, "创建产品失败", err)
|
||||
return
|
||||
}
|
||||
|
||||
response.Success(c, product)
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 配置路由
|
||||
|
||||
创建 `internal/domains/product/routes/product_routes.go`:
|
||||
|
||||
```go
|
||||
func RegisterProductRoutes(router shared.Router, handler *handlers.ProductHandler) {
|
||||
v1 := router.Group("/api/v1")
|
||||
{
|
||||
products := v1.Group("/products")
|
||||
{
|
||||
products.POST("", handler.CreateProduct)
|
||||
products.GET("/:id", handler.GetProduct)
|
||||
products.PUT("/:id", handler.UpdateProduct)
|
||||
products.DELETE("/:id", handler.DeleteProduct)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 常用开发命令
|
||||
|
||||
```bash
|
||||
# 代码格式化
|
||||
make fmt
|
||||
|
||||
# 代码检查
|
||||
make lint
|
||||
|
||||
# 运行测试
|
||||
make test
|
||||
|
||||
# 测试覆盖率
|
||||
make test-coverage
|
||||
|
||||
# 生成API文档
|
||||
make docs
|
||||
|
||||
# 热重载开发
|
||||
make dev
|
||||
|
||||
# 构建二进制文件
|
||||
make build
|
||||
|
||||
# 清理临时文件
|
||||
make clean
|
||||
```
|
||||
|
||||
## 测试编写
|
||||
|
||||
### 单元测试示例
|
||||
|
||||
```go
|
||||
func TestProductService_CreateProduct(t *testing.T) {
|
||||
// 设置测试数据
|
||||
mockRepo := mocks.NewProductRepository(t)
|
||||
service := services.NewProductService(mockRepo, nil)
|
||||
|
||||
req := &dto.CreateProductRequest{
|
||||
Name: "测试产品",
|
||||
Description: "测试描述",
|
||||
Price: 99.99,
|
||||
CategoryID: 1,
|
||||
}
|
||||
|
||||
// 设置Mock期望
|
||||
mockRepo.On("Create", mock.Anything, mock.AnythingOfType("*entities.Product")).
|
||||
Return(&entities.Product{}, nil)
|
||||
|
||||
// 执行测试
|
||||
result, err := service.CreateProduct(context.Background(), req)
|
||||
|
||||
// 断言结果
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, result)
|
||||
assert.Equal(t, req.Name, result.Name)
|
||||
}
|
||||
```
|
||||
|
||||
### 集成测试示例
|
||||
|
||||
```go
|
||||
func TestProductAPI_Integration(t *testing.T) {
|
||||
// 启动测试服务器
|
||||
testApp := setupTestApp(t)
|
||||
defer testApp.Cleanup()
|
||||
|
||||
// 创建测试请求
|
||||
reqBody := `{"name":"测试产品","price":99.99,"category_id":1}`
|
||||
req := httptest.NewRequest("POST", "/api/v1/products", strings.NewReader(reqBody))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
// 执行请求
|
||||
w := httptest.NewRecorder()
|
||||
testApp.ServeHTTP(w, req)
|
||||
|
||||
// 验证响应
|
||||
assert.Equal(t, http.StatusCreated, w.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(w.Body.Bytes(), &response)
|
||||
assert.Equal(t, "success", response["status"])
|
||||
}
|
||||
```
|
||||
|
||||
## 开发规范
|
||||
|
||||
### 代码风格
|
||||
|
||||
- 使用 `gofmt` 格式化代码
|
||||
- 遵循 Go 命名规范
|
||||
- 添加必要的注释和文档
|
||||
- 函数长度不超过 50 行
|
||||
|
||||
### Git 提交规范
|
||||
|
||||
```bash
|
||||
# 功能开发
|
||||
git commit -m "feat: 添加用户注册功能"
|
||||
|
||||
# 问题修复
|
||||
git commit -m "fix: 修复登录验证问题"
|
||||
|
||||
# 文档更新
|
||||
git commit -m "docs: 更新API文档"
|
||||
|
||||
# 重构代码
|
||||
git commit -m "refactor: 重构用户服务层"
|
||||
```
|
||||
|
||||
### 分支管理
|
||||
|
||||
- `main`: 主分支,用于生产发布
|
||||
- `develop`: 开发分支,用于集成测试
|
||||
- `feature/xxx`: 功能分支,用于新功能开发
|
||||
- `hotfix/xxx`: 热修复分支,用于紧急修复
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 使用 Delve 调试器
|
||||
|
||||
```bash
|
||||
# 安装 Delve
|
||||
go install github.com/go-delve/delve/cmd/dlv@latest
|
||||
|
||||
# 启动调试
|
||||
dlv debug ./cmd/api/main.go
|
||||
|
||||
# 设置断点
|
||||
(dlv) break main.main
|
||||
(dlv) continue
|
||||
```
|
||||
|
||||
### 日志调试
|
||||
|
||||
```go
|
||||
// 添加调试日志
|
||||
logger.Debug("Processing user request",
|
||||
zap.String("user_id", userID),
|
||||
zap.String("action", "create_product"))
|
||||
|
||||
// 临时调试信息
|
||||
fmt.Printf("Debug: %+v\n", debugData)
|
||||
```
|
||||
|
||||
### 性能分析
|
||||
|
||||
```bash
|
||||
# 启用 pprof
|
||||
go tool pprof http://localhost:8080/debug/pprof/profile
|
||||
|
||||
# 内存分析
|
||||
go tool pprof http://localhost:8080/debug/pprof/heap
|
||||
|
||||
# 协程分析
|
||||
go tool pprof http://localhost:8080/debug/pprof/goroutine
|
||||
```
|
||||
56
docs/快速开始指南.md
Normal file
56
docs/快速开始指南.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# 🚀 快速开始指南
|
||||
|
||||
## 前置要求
|
||||
|
||||
确保您的开发环境中安装了以下工具:
|
||||
|
||||
- **Go 1.23.4+** - 编程语言环境
|
||||
- **Docker & Docker Compose** - 容器化环境
|
||||
- **Git** - 版本控制工具
|
||||
- **Make** - 构建工具(可选,推荐)
|
||||
|
||||
## 一键启动
|
||||
|
||||
```bash
|
||||
# 1. 克隆项目
|
||||
git clone <your-repo-url>
|
||||
cd tyapi-server-gin
|
||||
|
||||
# 2. 启动开发环境
|
||||
make dev-up
|
||||
|
||||
# 3. 运行应用
|
||||
make run
|
||||
```
|
||||
|
||||
访问 http://localhost:8080/api/v1/health 验证启动成功。
|
||||
|
||||
## 验证安装
|
||||
|
||||
### 检查服务状态
|
||||
|
||||
```bash
|
||||
# 检查所有容器是否正常运行
|
||||
docker-compose -f docker-compose.dev.yml ps
|
||||
|
||||
# 检查应用健康状态
|
||||
curl http://localhost:8080/api/v1/health
|
||||
```
|
||||
|
||||
### 访问管理界面
|
||||
|
||||
启动成功后,您可以访问以下管理界面:
|
||||
|
||||
- **API 文档**: http://localhost:8080/swagger/
|
||||
- **数据库管理**: http://localhost:5050 (pgAdmin)
|
||||
- **监控面板**: http://localhost:3000 (Grafana)
|
||||
- **链路追踪**: http://localhost:16686 (Jaeger)
|
||||
- **邮件测试**: http://localhost:8025 (MailHog)
|
||||
|
||||
## 下一步
|
||||
|
||||
快速启动完成后,建议您:
|
||||
|
||||
1. 阅读 [环境搭建指南](./环境搭建指南.md) 了解详细配置
|
||||
2. 查看 [开发指南](./开发指南.md) 开始开发
|
||||
3. 参考 [API 使用指南](./API使用指南.md) 了解 API 用法
|
||||
404
docs/故障排除指南.md
Normal file
404
docs/故障排除指南.md
Normal file
@@ -0,0 +1,404 @@
|
||||
# 🔍 故障排除指南
|
||||
|
||||
## 常见问题
|
||||
|
||||
### 1. 数据库连接失败
|
||||
|
||||
**问题**:`failed to connect to database`
|
||||
|
||||
**解决方案**:
|
||||
|
||||
```bash
|
||||
# 检查数据库配置
|
||||
cat config.yaml | grep -A 10 database
|
||||
|
||||
# 测试数据库连接
|
||||
psql -h localhost -U postgres -d tyapi_dev
|
||||
|
||||
# 检查环境变量
|
||||
env | grep DB_
|
||||
```
|
||||
|
||||
### 2. Redis 连接失败
|
||||
|
||||
**问题**:`failed to connect to redis`
|
||||
|
||||
**解决方案**:
|
||||
|
||||
```bash
|
||||
# 检查Redis状态
|
||||
redis-cli ping
|
||||
|
||||
# 检查配置
|
||||
cat config.yaml | grep -A 5 redis
|
||||
|
||||
# 重启Redis
|
||||
docker restart tyapi-redis
|
||||
```
|
||||
|
||||
### 3. JWT 令牌验证失败
|
||||
|
||||
**问题**:`invalid token`
|
||||
|
||||
**解决方案**:
|
||||
|
||||
```bash
|
||||
# 检查JWT密钥配置
|
||||
echo $JWT_SECRET
|
||||
|
||||
# 验证令牌格式
|
||||
echo "your-token" | cut -d. -f2 | base64 -d
|
||||
```
|
||||
|
||||
### 4. 内存使用过高
|
||||
|
||||
**问题**:应用内存占用持续增长
|
||||
|
||||
**解决方案**:
|
||||
|
||||
```bash
|
||||
# 启用pprof分析
|
||||
go tool pprof http://localhost:8080/debug/pprof/heap
|
||||
|
||||
# 检查Goroutine泄露
|
||||
go tool pprof http://localhost:8080/debug/pprof/goroutine
|
||||
|
||||
# 优化数据库连接池
|
||||
# 在config.yaml中调整max_open_conns和max_idle_conns
|
||||
```
|
||||
|
||||
### 5. 端口冲突
|
||||
|
||||
**问题**:`bind: address already in use`
|
||||
|
||||
**解决方案**:
|
||||
|
||||
```bash
|
||||
# 查找占用端口的进程
|
||||
netstat -tlnp | grep :8080
|
||||
lsof -i :8080
|
||||
|
||||
# 终止占用端口的进程
|
||||
kill -9 <PID>
|
||||
|
||||
# 修改配置使用其他端口
|
||||
```
|
||||
|
||||
### 6. 权限问题
|
||||
|
||||
**问题**:`permission denied`
|
||||
|
||||
**解决方案**:
|
||||
|
||||
```bash
|
||||
# 检查文件权限
|
||||
ls -la config.yaml
|
||||
ls -la logs/
|
||||
|
||||
# 修复权限
|
||||
chmod 644 config.yaml
|
||||
chmod 755 logs/
|
||||
chown -R $(whoami) logs/
|
||||
```
|
||||
|
||||
## 日志分析
|
||||
|
||||
### 1. 应用日志
|
||||
|
||||
```bash
|
||||
# 查看应用日志
|
||||
tail -f logs/app.log
|
||||
|
||||
# 过滤错误日志
|
||||
grep "ERROR" logs/app.log
|
||||
|
||||
# 分析请求延迟
|
||||
grep "request_duration" logs/app.log | awk '{print $NF}' | sort -n
|
||||
```
|
||||
|
||||
### 2. 数据库日志
|
||||
|
||||
```bash
|
||||
# PostgreSQL日志
|
||||
docker logs tyapi-postgres 2>&1 | grep ERROR
|
||||
|
||||
# 慢查询分析
|
||||
grep "duration:" logs/postgresql.log | awk '$3 > 1000'
|
||||
```
|
||||
|
||||
### 3. 性能监控
|
||||
|
||||
```bash
|
||||
# 查看系统指标
|
||||
curl http://localhost:8080/metrics
|
||||
|
||||
# Prometheus查询示例
|
||||
# HTTP请求QPS
|
||||
rate(http_requests_total[5m])
|
||||
|
||||
# 平均响应时间
|
||||
rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])
|
||||
```
|
||||
|
||||
## 容器相关问题
|
||||
|
||||
### 1. 容器启动失败
|
||||
|
||||
```bash
|
||||
# 查看容器状态
|
||||
docker-compose ps
|
||||
|
||||
# 查看容器日志
|
||||
docker-compose logs <service_name>
|
||||
|
||||
# 重新构建镜像
|
||||
docker-compose build --no-cache
|
||||
```
|
||||
|
||||
### 2. 网络连接问题
|
||||
|
||||
```bash
|
||||
# 检查网络配置
|
||||
docker network ls
|
||||
docker network inspect tyapi-network
|
||||
|
||||
# 测试容器间连接
|
||||
docker exec -it tyapi-server ping postgres
|
||||
```
|
||||
|
||||
### 3. 数据持久化问题
|
||||
|
||||
```bash
|
||||
# 检查数据卷
|
||||
docker volume ls
|
||||
docker volume inspect postgres_data
|
||||
|
||||
# 备份数据
|
||||
docker exec tyapi-postgres pg_dump -U postgres tyapi_dev > backup.sql
|
||||
```
|
||||
|
||||
## 性能问题
|
||||
|
||||
### 1. 响应时间过长
|
||||
|
||||
**诊断步骤**:
|
||||
|
||||
```bash
|
||||
# 启用详细日志
|
||||
export LOG_LEVEL=debug
|
||||
|
||||
# 分析慢查询
|
||||
grep "slow query" logs/app.log
|
||||
|
||||
# 检查数据库索引
|
||||
psql -h localhost -U postgres -d tyapi_dev -c "\di"
|
||||
```
|
||||
|
||||
### 2. 内存泄漏
|
||||
|
||||
**诊断步骤**:
|
||||
|
||||
```bash
|
||||
# 监控内存使用
|
||||
top -p $(pgrep tyapi-server)
|
||||
|
||||
# 生成内存分析报告
|
||||
go tool pprof -http=:6060 http://localhost:8080/debug/pprof/heap
|
||||
```
|
||||
|
||||
### 3. 高 CPU 使用率
|
||||
|
||||
**诊断步骤**:
|
||||
|
||||
```bash
|
||||
# CPU性能分析
|
||||
go tool pprof http://localhost:8080/debug/pprof/profile
|
||||
|
||||
# 检查系统负载
|
||||
uptime
|
||||
iostat 1 5
|
||||
```
|
||||
|
||||
## 开发环境问题
|
||||
|
||||
### 1. 热重载不工作
|
||||
|
||||
```bash
|
||||
# 检查文件监控
|
||||
ls -la .air.toml
|
||||
|
||||
# 重启开发服务器
|
||||
make dev-restart
|
||||
|
||||
# 检查文件权限
|
||||
chmod +x scripts/dev.sh
|
||||
```
|
||||
|
||||
### 2. 测试失败
|
||||
|
||||
```bash
|
||||
# 运行特定测试
|
||||
go test -v ./internal/domains/user/...
|
||||
|
||||
# 清理测试缓存
|
||||
go clean -testcache
|
||||
|
||||
# 运行集成测试
|
||||
go test -tags=integration ./test/...
|
||||
```
|
||||
|
||||
## 生产环境问题
|
||||
|
||||
### 1. 健康检查失败
|
||||
|
||||
```bash
|
||||
# 手动测试健康检查
|
||||
curl -f http://localhost:8080/api/v1/health
|
||||
|
||||
# 检查依赖服务
|
||||
curl -f http://localhost:8080/api/v1/health/ready
|
||||
|
||||
# 查看详细错误
|
||||
curl -v http://localhost:8080/api/v1/health
|
||||
```
|
||||
|
||||
### 2. 负载均衡问题
|
||||
|
||||
```bash
|
||||
# 检查上游服务器状态
|
||||
nginx -t
|
||||
systemctl status nginx
|
||||
|
||||
# 查看负载均衡日志
|
||||
tail -f /var/log/nginx/access.log
|
||||
tail -f /var/log/nginx/error.log
|
||||
```
|
||||
|
||||
### 3. 证书问题
|
||||
|
||||
```bash
|
||||
# 检查SSL证书
|
||||
openssl x509 -in /etc/ssl/certs/server.crt -text -noout
|
||||
|
||||
# 验证证书有效期
|
||||
openssl x509 -in /etc/ssl/certs/server.crt -checkend 86400
|
||||
|
||||
# 测试HTTPS连接
|
||||
curl -I https://api.yourdomain.com
|
||||
```
|
||||
|
||||
## 调试工具
|
||||
|
||||
### 1. 日志查看工具
|
||||
|
||||
```bash
|
||||
# 实时查看日志
|
||||
journalctl -u tyapi-server -f
|
||||
|
||||
# 过滤特定级别日志
|
||||
journalctl -u tyapi-server -p err
|
||||
|
||||
# 按时间范围查看日志
|
||||
journalctl -u tyapi-server --since "2024-01-01 00:00:00"
|
||||
```
|
||||
|
||||
### 2. 网络调试
|
||||
|
||||
```bash
|
||||
# 检查端口监听
|
||||
ss -tlnp | grep :8080
|
||||
|
||||
# 网络连接测试
|
||||
telnet localhost 8080
|
||||
nc -zv localhost 8080
|
||||
|
||||
# DNS解析测试
|
||||
nslookup api.yourdomain.com
|
||||
dig api.yourdomain.com
|
||||
```
|
||||
|
||||
### 3. 数据库调试
|
||||
|
||||
```bash
|
||||
# 连接数据库
|
||||
psql -h localhost -U postgres -d tyapi_dev
|
||||
|
||||
# 查看活动连接
|
||||
SELECT * FROM pg_stat_activity;
|
||||
|
||||
# 查看慢查询
|
||||
SELECT query, mean_time, calls FROM pg_stat_statements ORDER BY mean_time DESC LIMIT 5;
|
||||
```
|
||||
|
||||
## 紧急响应流程
|
||||
|
||||
### 1. 服务宕机
|
||||
|
||||
1. **快速恢复**:
|
||||
|
||||
```bash
|
||||
# 重启服务
|
||||
systemctl restart tyapi-server
|
||||
|
||||
# 或使用Docker
|
||||
docker-compose restart tyapi-server
|
||||
```
|
||||
|
||||
2. **回滚部署**:
|
||||
|
||||
```bash
|
||||
# K8s回滚
|
||||
kubectl rollout undo deployment/tyapi-server
|
||||
|
||||
# Docker回滚
|
||||
docker-compose down
|
||||
docker-compose up -d --scale tyapi-server=3
|
||||
```
|
||||
|
||||
### 2. 数据库问题
|
||||
|
||||
1. **主从切换**:
|
||||
|
||||
```bash
|
||||
# 提升从库为主库
|
||||
sudo -u postgres /usr/lib/postgresql/13/bin/pg_promote -D /var/lib/postgresql/13/main
|
||||
```
|
||||
|
||||
2. **数据恢复**:
|
||||
```bash
|
||||
# 从备份恢复
|
||||
psql -h localhost -U postgres -d tyapi_dev < backup_latest.sql
|
||||
```
|
||||
|
||||
### 3. 联系支持
|
||||
|
||||
当遇到无法解决的问题时:
|
||||
|
||||
1. 收集错误信息和日志
|
||||
2. 记录重现步骤
|
||||
3. 准备系统环境信息
|
||||
4. 联系技术支持团队
|
||||
|
||||
**支持信息收集脚本**:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
echo "=== TYAPI Server Debug Info ===" > debug_info.txt
|
||||
echo "Date: $(date)" >> debug_info.txt
|
||||
echo "Version: $(cat VERSION 2>/dev/null || echo 'unknown')" >> debug_info.txt
|
||||
echo "" >> debug_info.txt
|
||||
|
||||
echo "=== System Info ===" >> debug_info.txt
|
||||
uname -a >> debug_info.txt
|
||||
echo "" >> debug_info.txt
|
||||
|
||||
echo "=== Docker Status ===" >> debug_info.txt
|
||||
docker-compose ps >> debug_info.txt
|
||||
echo "" >> debug_info.txt
|
||||
|
||||
echo "=== Recent Logs ===" >> debug_info.txt
|
||||
tail -50 logs/app.log >> debug_info.txt
|
||||
echo "" >> debug_info.txt
|
||||
|
||||
echo "Debug info collected in debug_info.txt"
|
||||
```
|
||||
102
docs/文档索引.md
Normal file
102
docs/文档索引.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# 📚 TYAPI Server 文档中心
|
||||
|
||||
欢迎使用 TYAPI Server 文档中心!我们已将原本的使用指南拆分为多个专题文档,方便您按需查阅。
|
||||
|
||||
## 📋 文档导航
|
||||
|
||||
### 🚀 [快速开始指南](./快速开始指南.md)
|
||||
- 前置要求
|
||||
- 一键启动
|
||||
- 验证安装
|
||||
- 访问管理界面
|
||||
|
||||
### 🔧 [环境搭建指南](./环境搭建指南.md)
|
||||
- 开发环境配置
|
||||
- 生产环境配置
|
||||
- 服务配置说明
|
||||
- 常见配置问题
|
||||
|
||||
### 👨💻 [开发指南](./开发指南.md)
|
||||
- 项目结构理解
|
||||
- 开发流程
|
||||
- 测试编写
|
||||
- 调试技巧
|
||||
- 代码规范
|
||||
|
||||
### 🌐 [API使用指南](./API使用指南.md)
|
||||
- 认证机制
|
||||
- 用户管理 API
|
||||
- 响应格式
|
||||
- HTTP 状态码
|
||||
- API 测试
|
||||
|
||||
### 🚀 [部署指南](./部署指南.md)
|
||||
- Docker 部署
|
||||
- Kubernetes 部署
|
||||
- 云平台部署
|
||||
- 负载均衡配置
|
||||
- 监控部署
|
||||
|
||||
### 🔍 [故障排除指南](./故障排除指南.md)
|
||||
- 常见问题
|
||||
- 日志分析
|
||||
- 性能问题
|
||||
- 紧急响应流程
|
||||
|
||||
### 📋 [最佳实践指南](./最佳实践指南.md)
|
||||
- 开发最佳实践
|
||||
- 安全最佳实践
|
||||
- 性能最佳实践
|
||||
- 运维最佳实践
|
||||
- 团队协作
|
||||
|
||||
## 🎯 快速索引
|
||||
|
||||
### 新手入门
|
||||
1. [快速开始指南](./快速开始指南.md) - 5分钟快速体验
|
||||
2. [环境搭建指南](./环境搭建指南.md) - 配置开发环境
|
||||
3. [开发指南](./开发指南.md) - 开始第一个功能
|
||||
|
||||
### 日常开发
|
||||
- [API使用指南](./API使用指南.md) - API 调用参考
|
||||
- [开发指南](./开发指南.md) - 开发流程和规范
|
||||
- [故障排除指南](./故障排除指南.md) - 解决常见问题
|
||||
|
||||
### 生产部署
|
||||
- [部署指南](./部署指南.md) - 生产环境部署
|
||||
- [最佳实践指南](./最佳实践指南.md) - 运维最佳实践
|
||||
- [故障排除指南](./故障排除指南.md) - 生产问题排查
|
||||
|
||||
## 🔗 相关文档
|
||||
|
||||
### 技术文档
|
||||
- [架构文档](./ARCHITECTURE.md) - 系统架构设计
|
||||
- [API 规范](http://localhost:8080/swagger/) - 在线 API 文档
|
||||
|
||||
### 项目文档
|
||||
- [README](../README.md) - 项目介绍
|
||||
- [更新日志](../CHANGELOG.md) - 版本变更记录
|
||||
|
||||
## 📞 获取帮助
|
||||
|
||||
### 在线资源
|
||||
- **Swagger UI**: http://localhost:8080/swagger/
|
||||
- **健康检查**: http://localhost:8080/api/v1/health
|
||||
- **监控面板**: http://localhost:3000 (Grafana)
|
||||
|
||||
### 社区支持
|
||||
- **GitHub Issues**: 提交问题和建议
|
||||
- **Wiki**: 查看详细技术文档
|
||||
- **讨论区**: 参与技术讨论
|
||||
|
||||
## 🔄 文档更新
|
||||
|
||||
本文档会持续更新,如果您发现任何问题或有改进建议,请:
|
||||
|
||||
1. 提交 GitHub Issue
|
||||
2. 发起 Pull Request
|
||||
3. 联系维护团队
|
||||
|
||||
---
|
||||
|
||||
**提示**:建议将此页面加入书签,方便随时查阅相关文档。
|
||||
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 项目的高质量、高性能和高可维护性。
|
||||
127
docs/环境搭建指南.md
Normal file
127
docs/环境搭建指南.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# 🔧 环境搭建指南
|
||||
|
||||
## 开发环境配置
|
||||
|
||||
### 1. 配置环境变量
|
||||
|
||||
```bash
|
||||
# 复制环境变量模板
|
||||
cp env.example .env
|
||||
|
||||
# 编辑环境变量(根据需要修改)
|
||||
vim .env
|
||||
```
|
||||
|
||||
### 2. 启动基础服务
|
||||
|
||||
```bash
|
||||
# 启动 PostgreSQL 和 Redis
|
||||
docker-compose -f docker-compose.dev.yml up -d postgres redis
|
||||
|
||||
# 查看服务状态
|
||||
docker-compose -f docker-compose.dev.yml ps
|
||||
```
|
||||
|
||||
### 3. 数据库初始化
|
||||
|
||||
```bash
|
||||
# 创建数据库表
|
||||
make migrate
|
||||
|
||||
# 或手动执行SQL
|
||||
psql -h localhost -U postgres -d tyapi_dev -f scripts/init.sql
|
||||
```
|
||||
|
||||
### 4. 依赖安装
|
||||
|
||||
```bash
|
||||
# 安装Go依赖
|
||||
go mod download
|
||||
|
||||
# 验证依赖
|
||||
go mod verify
|
||||
```
|
||||
|
||||
## 生产环境配置
|
||||
|
||||
### 1. 配置文件准备
|
||||
|
||||
```bash
|
||||
# 复制生产配置模板
|
||||
cp config.prod.yaml config.yaml
|
||||
|
||||
# 修改生产配置
|
||||
vim config.yaml
|
||||
```
|
||||
|
||||
### 2. 环境变量设置
|
||||
|
||||
```bash
|
||||
export APP_ENV=production
|
||||
export DB_HOST=your-db-host
|
||||
export DB_PASSWORD=your-secure-password
|
||||
export JWT_SECRET=your-jwt-secret
|
||||
export REDIS_HOST=your-redis-host
|
||||
```
|
||||
|
||||
## 服务配置说明
|
||||
|
||||
### PostgreSQL 配置
|
||||
|
||||
默认配置:
|
||||
|
||||
- 端口:5432
|
||||
- 数据库:tyapi_dev
|
||||
- 用户名:postgres
|
||||
- 密码:Pg9mX4kL8nW2rT5y(开发环境)
|
||||
|
||||
### Redis 配置
|
||||
|
||||
默认配置:
|
||||
|
||||
- 端口:6379
|
||||
- 无密码(开发环境)
|
||||
- 数据库:0
|
||||
|
||||
### 监控服务配置
|
||||
|
||||
- **Prometheus**: http://localhost:9090
|
||||
- **Grafana**: http://localhost:3000 (admin/Gf7nB3xM9cV6pQ2w)
|
||||
- **Jaeger**: http://localhost:16686
|
||||
|
||||
### 存储服务配置
|
||||
|
||||
- **MinIO**: http://localhost:9000 (minioadmin/Mn5oH8yK3bR7vX1z)
|
||||
- **对象存储控制台**: http://localhost:9001
|
||||
|
||||
## 常见配置问题
|
||||
|
||||
### 端口冲突
|
||||
|
||||
如果遇到端口冲突,可以修改 `docker-compose.dev.yml` 中的端口映射:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "15432:5432" # 将 PostgreSQL 映射到本地 15432 端口
|
||||
```
|
||||
|
||||
### 权限问题
|
||||
|
||||
在 Linux/macOS 系统中,可能需要调整文件权限:
|
||||
|
||||
```bash
|
||||
# 给予脚本执行权限
|
||||
chmod +x scripts/*.sh
|
||||
|
||||
# 修复数据目录权限
|
||||
sudo chown -R $(whoami) ./data/
|
||||
```
|
||||
|
||||
### 内存不足
|
||||
|
||||
如果系统内存不足,可以减少启动的服务:
|
||||
|
||||
```bash
|
||||
# 只启动核心服务
|
||||
docker-compose -f docker-compose.dev.yml up -d postgres redis
|
||||
```
|
||||
476
docs/部署指南.md
Normal file
476
docs/部署指南.md
Normal file
@@ -0,0 +1,476 @@
|
||||
# 🚀 部署指南
|
||||
|
||||
## Docker 部署
|
||||
|
||||
### 1. 构建镜像
|
||||
|
||||
```bash
|
||||
# 构建生产镜像
|
||||
make docker-build
|
||||
|
||||
# 或使用Docker命令
|
||||
docker build -t tyapi-server:latest .
|
||||
```
|
||||
|
||||
### 2. 运行容器
|
||||
|
||||
```bash
|
||||
# 单容器运行
|
||||
docker run -d \
|
||||
--name tyapi-server \
|
||||
-p 8080:8080 \
|
||||
-e APP_ENV=production \
|
||||
-e DB_HOST=your-db-host \
|
||||
-e DB_PASSWORD=your-password \
|
||||
tyapi-server:latest
|
||||
|
||||
# 使用Docker Compose
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 3. 多环境部署
|
||||
|
||||
#### 开发环境
|
||||
|
||||
```bash
|
||||
# 启动完整开发环境
|
||||
docker-compose -f docker-compose.dev.yml up -d
|
||||
|
||||
# 仅启动依赖服务
|
||||
docker-compose -f docker-compose.dev.yml up -d postgres redis
|
||||
```
|
||||
|
||||
#### 测试环境
|
||||
|
||||
```bash
|
||||
# 使用测试配置
|
||||
docker-compose -f docker-compose.test.yml up -d
|
||||
```
|
||||
|
||||
#### 生产环境
|
||||
|
||||
```bash
|
||||
# 使用生产配置
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
## Kubernetes 部署
|
||||
|
||||
### 1. 配置清单文件
|
||||
|
||||
创建 `k8s/deployment.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: tyapi-server
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tyapi-server
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tyapi-server
|
||||
spec:
|
||||
containers:
|
||||
- name: tyapi-server
|
||||
image: tyapi-server:latest
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: APP_ENV
|
||||
value: "production"
|
||||
- name: DB_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: tyapi-secrets
|
||||
key: db-host
|
||||
```
|
||||
|
||||
### 2. 服务配置
|
||||
|
||||
创建 `k8s/service.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: tyapi-server-service
|
||||
spec:
|
||||
selector:
|
||||
app: tyapi-server
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
type: LoadBalancer
|
||||
```
|
||||
|
||||
### 3. 配置管理
|
||||
|
||||
创建 `k8s/configmap.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: tyapi-config
|
||||
data:
|
||||
config.yaml: |
|
||||
server:
|
||||
port: 8080
|
||||
mode: release
|
||||
database:
|
||||
host: postgres-service
|
||||
port: 5432
|
||||
```
|
||||
|
||||
### 4. 密钥管理
|
||||
|
||||
```bash
|
||||
# 创建密钥
|
||||
kubectl create secret generic tyapi-secrets \
|
||||
--from-literal=db-password=your-db-password \
|
||||
--from-literal=jwt-secret=your-jwt-secret
|
||||
```
|
||||
|
||||
### 5. 部署到集群
|
||||
|
||||
```bash
|
||||
# 应用所有配置
|
||||
kubectl apply -f k8s/
|
||||
|
||||
# 查看部署状态
|
||||
kubectl get pods -l app=tyapi-server
|
||||
|
||||
# 查看服务状态
|
||||
kubectl get services
|
||||
|
||||
# 查看服务日志
|
||||
kubectl logs -f deployment/tyapi-server
|
||||
```
|
||||
|
||||
## 云平台部署
|
||||
|
||||
### AWS ECS
|
||||
|
||||
#### 1. 推送镜像到 ECR
|
||||
|
||||
```bash
|
||||
# 登录 ECR
|
||||
aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin <account>.dkr.ecr.us-west-2.amazonaws.com
|
||||
|
||||
# 标记镜像
|
||||
docker tag tyapi-server:latest <account>.dkr.ecr.us-west-2.amazonaws.com/tyapi-server:latest
|
||||
|
||||
# 推送镜像
|
||||
docker push <account>.dkr.ecr.us-west-2.amazonaws.com/tyapi-server:latest
|
||||
```
|
||||
|
||||
#### 2. 创建任务定义
|
||||
|
||||
```json
|
||||
{
|
||||
"family": "tyapi-server",
|
||||
"networkMode": "awsvpc",
|
||||
"requiresCompatibilities": ["FARGATE"],
|
||||
"cpu": "256",
|
||||
"memory": "512",
|
||||
"executionRoleArn": "arn:aws:iam::account:role/ecsTaskExecutionRole",
|
||||
"containerDefinitions": [
|
||||
{
|
||||
"name": "tyapi-server",
|
||||
"image": "<account>.dkr.ecr.us-west-2.amazonaws.com/tyapi-server:latest",
|
||||
"portMappings": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"protocol": "tcp"
|
||||
}
|
||||
],
|
||||
"environment": [
|
||||
{
|
||||
"name": "APP_ENV",
|
||||
"value": "production"
|
||||
}
|
||||
],
|
||||
"secrets": [
|
||||
{
|
||||
"name": "DB_PASSWORD",
|
||||
"valueFrom": "arn:aws:secretsmanager:us-west-2:account:secret:db-password"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 部署服务
|
||||
|
||||
```bash
|
||||
# 更新ECS服务
|
||||
aws ecs update-service \
|
||||
--cluster tyapi-cluster \
|
||||
--service tyapi-service \
|
||||
--force-new-deployment
|
||||
```
|
||||
|
||||
### Google Cloud Run
|
||||
|
||||
```bash
|
||||
# 推送到 GCR
|
||||
docker tag tyapi-server:latest gcr.io/your-project/tyapi-server:latest
|
||||
docker push gcr.io/your-project/tyapi-server:latest
|
||||
|
||||
# 部署到 Cloud Run
|
||||
gcloud run deploy tyapi-server \
|
||||
--image gcr.io/your-project/tyapi-server:latest \
|
||||
--platform managed \
|
||||
--region us-central1 \
|
||||
--allow-unauthenticated \
|
||||
--set-env-vars APP_ENV=production \
|
||||
--set-secrets DB_PASSWORD=db-password:latest
|
||||
```
|
||||
|
||||
### Azure Container Instances
|
||||
|
||||
```bash
|
||||
# 推送到 ACR
|
||||
az acr login --name your-registry
|
||||
docker tag tyapi-server:latest your-registry.azurecr.io/tyapi-server:latest
|
||||
docker push your-registry.azurecr.io/tyapi-server:latest
|
||||
|
||||
# 部署容器实例
|
||||
az container create \
|
||||
--resource-group tyapi-rg \
|
||||
--name tyapi-server \
|
||||
--image your-registry.azurecr.io/tyapi-server:latest \
|
||||
--dns-name-label tyapi-server \
|
||||
--ports 8080 \
|
||||
--environment-variables APP_ENV=production \
|
||||
--secure-environment-variables DB_PASSWORD=your-password
|
||||
```
|
||||
|
||||
## 负载均衡配置
|
||||
|
||||
### Nginx 配置
|
||||
|
||||
创建 `/etc/nginx/sites-available/tyapi-server`:
|
||||
|
||||
```nginx
|
||||
upstream tyapi_backend {
|
||||
server 127.0.0.1:8080;
|
||||
server 127.0.0.1:8081;
|
||||
server 127.0.0.1:8082;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.yourdomain.com;
|
||||
|
||||
location / {
|
||||
proxy_pass http://tyapi_backend;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /health {
|
||||
proxy_pass http://tyapi_backend/api/v1/health;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### HAProxy 配置
|
||||
|
||||
```haproxy
|
||||
global
|
||||
daemon
|
||||
|
||||
defaults
|
||||
mode http
|
||||
timeout connect 5000ms
|
||||
timeout client 50000ms
|
||||
timeout server 50000ms
|
||||
|
||||
frontend tyapi_frontend
|
||||
bind *:80
|
||||
default_backend tyapi_backend
|
||||
|
||||
backend tyapi_backend
|
||||
balance roundrobin
|
||||
option httpchk GET /api/v1/health
|
||||
server app1 127.0.0.1:8080 check
|
||||
server app2 127.0.0.1:8081 check
|
||||
server app3 127.0.0.1:8082 check
|
||||
```
|
||||
|
||||
## 数据库部署
|
||||
|
||||
### PostgreSQL 高可用
|
||||
|
||||
#### 主从配置
|
||||
|
||||
主库配置 `/etc/postgresql/13/main/postgresql.conf`:
|
||||
|
||||
```conf
|
||||
# 复制设置
|
||||
wal_level = replica
|
||||
max_wal_senders = 3
|
||||
wal_keep_segments = 64
|
||||
```
|
||||
|
||||
从库配置:
|
||||
|
||||
```bash
|
||||
# 创建从库
|
||||
pg_basebackup -h master-host -D /var/lib/postgresql/13/main -U replicator -P -W
|
||||
|
||||
# 配置恢复
|
||||
echo "standby_mode = 'on'" >> /var/lib/postgresql/13/main/recovery.conf
|
||||
echo "primary_conninfo = 'host=master-host port=5432 user=replicator'" >> /var/lib/postgresql/13/main/recovery.conf
|
||||
```
|
||||
|
||||
#### 连接池配置
|
||||
|
||||
使用 PgBouncer:
|
||||
|
||||
```ini
|
||||
[databases]
|
||||
tyapi_prod = host=127.0.0.1 port=5432 dbname=tyapi_prod
|
||||
|
||||
[pgbouncer]
|
||||
listen_port = 6432
|
||||
listen_addr = 127.0.0.1
|
||||
auth_type = md5
|
||||
auth_file = /etc/pgbouncer/userlist.txt
|
||||
pool_mode = transaction
|
||||
max_client_conn = 1000
|
||||
default_pool_size = 25
|
||||
```
|
||||
|
||||
### Redis 集群
|
||||
|
||||
```bash
|
||||
# 启动 Redis 集群
|
||||
redis-server redis-7000.conf
|
||||
redis-server redis-7001.conf
|
||||
redis-server redis-7002.conf
|
||||
|
||||
# 创建集群
|
||||
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 --cluster-replicas 0
|
||||
```
|
||||
|
||||
## 监控部署
|
||||
|
||||
### Prometheus 配置
|
||||
|
||||
```yaml
|
||||
global:
|
||||
scrape_interval: 15s
|
||||
|
||||
scrape_configs:
|
||||
- job_name: "tyapi-server"
|
||||
static_configs:
|
||||
- targets: ["localhost:8080"]
|
||||
metrics_path: /metrics
|
||||
scrape_interval: 5s
|
||||
|
||||
- job_name: "postgres"
|
||||
static_configs:
|
||||
- targets: ["localhost:9187"]
|
||||
|
||||
- job_name: "redis"
|
||||
static_configs:
|
||||
- targets: ["localhost:9121"]
|
||||
```
|
||||
|
||||
### Grafana 仪表板
|
||||
|
||||
导入预配置的仪表板或创建自定义面板监控:
|
||||
|
||||
- 应用性能指标
|
||||
- 数据库性能
|
||||
- 系统资源使用
|
||||
- 错误率和响应时间
|
||||
|
||||
## SSL/TLS 配置
|
||||
|
||||
### Let's Encrypt 证书
|
||||
|
||||
```bash
|
||||
# 安装 Certbot
|
||||
sudo apt-get install certbot python3-certbot-nginx
|
||||
|
||||
# 获取证书
|
||||
sudo certbot --nginx -d api.yourdomain.com
|
||||
|
||||
# 自动续期
|
||||
sudo crontab -e
|
||||
0 12 * * * /usr/bin/certbot renew --quiet
|
||||
```
|
||||
|
||||
### 自签名证书(开发环境)
|
||||
|
||||
```bash
|
||||
# 生成私钥
|
||||
openssl genrsa -out server.key 2048
|
||||
|
||||
# 生成证书
|
||||
openssl req -new -x509 -key server.key -out server.crt -days 365
|
||||
```
|
||||
|
||||
## 部署检查清单
|
||||
|
||||
### 部署前检查
|
||||
|
||||
- [ ] 环境变量配置完整
|
||||
- [ ] 数据库连接正常
|
||||
- [ ] Redis 连接正常
|
||||
- [ ] SSL 证书有效
|
||||
- [ ] 防火墙规则配置
|
||||
- [ ] 监控告警设置
|
||||
|
||||
### 部署后验证
|
||||
|
||||
- [ ] 健康检查通过
|
||||
- [ ] API 响应正常
|
||||
- [ ] 日志输出正常
|
||||
- [ ] 监控指标采集
|
||||
- [ ] 负载均衡工作
|
||||
- [ ] 备份机制测试
|
||||
|
||||
## 回滚策略
|
||||
|
||||
### 蓝绿部署
|
||||
|
||||
```bash
|
||||
# 部署新版本到绿环境
|
||||
kubectl apply -f k8s/green/
|
||||
|
||||
# 切换流量到绿环境
|
||||
kubectl patch service tyapi-service -p '{"spec":{"selector":{"version":"green"}}}'
|
||||
|
||||
# 验证后删除蓝环境
|
||||
kubectl delete -f k8s/blue/
|
||||
```
|
||||
|
||||
### 金丝雀发布
|
||||
|
||||
```bash
|
||||
# 部署金丝雀版本(10%流量)
|
||||
kubectl apply -f k8s/canary/
|
||||
|
||||
# 逐步增加流量
|
||||
kubectl patch virtualservice tyapi-vs -p '{"spec":{"http":[{"match":[{"headers":{"canary":{"exact":"true"}}}],"route":[{"destination":{"host":"tyapi-canary"}}]},{"route":[{"destination":{"host":"tyapi-stable"},"weight":90},{"destination":{"host":"tyapi-canary"},"weight":10}]}]}}'
|
||||
```
|
||||
Reference in New Issue
Block a user