feat(架构): 完善基础架构设计
This commit is contained in:
668
docs/Makefile使用指南.md
Normal file
668
docs/Makefile使用指南.md
Normal file
@@ -0,0 +1,668 @@
|
||||
# 📋 Makefile 命令详细执行逻辑指南
|
||||
|
||||
本文档详细说明了 TYAPI 项目中每个 Make 命令的**执行逻辑、具体步骤和背后原理**。
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
```bash
|
||||
# 查看所有可用命令
|
||||
make help
|
||||
|
||||
# 设置开发环境
|
||||
make setup
|
||||
|
||||
# 启动开发依赖服务
|
||||
make dev-up
|
||||
|
||||
# 开发模式运行应用
|
||||
make dev
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📖 命令详细执行逻辑
|
||||
|
||||
### 🔍 **信息查看命令**
|
||||
|
||||
#### `make help`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 1. 检测操作系统类型
|
||||
# 2. 输出预定义的帮助信息
|
||||
@echo "TYAPI Server Makefile"
|
||||
@echo "Usage: make [target]"
|
||||
@echo "Main targets:"
|
||||
@echo " help Show this help message"
|
||||
# ... 更多帮助信息
|
||||
```
|
||||
|
||||
**实际效果**:
|
||||
|
||||
- 📄 直接打印硬编码的帮助文本
|
||||
- 🚫 不执行任何文件操作
|
||||
- ⚡ 瞬间完成,无依赖
|
||||
|
||||
#### `make version`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 自动执行 make build (依赖检查)
|
||||
# 步骤2: 执行构建好的二进制文件
|
||||
./bin/tyapi-server -version
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **依赖检查**: 检查是否需要重新构建 (通过 make build)
|
||||
2. **参数传递**: 向应用程序传递 `-version` 标志
|
||||
3. **读取构建信息**: 应用程序输出编译时注入的版本信息
|
||||
- `main.version` (来自 Makefile 的 VERSION 变量)
|
||||
- `main.commit` (来自 git rev-parse --short HEAD)
|
||||
- `main.date` (来自构建时间)
|
||||
|
||||
**相关文件**: `bin/tyapi-server`, `cmd/api/main.go`
|
||||
|
||||
---
|
||||
|
||||
### 🏗️ **构建相关命令**
|
||||
|
||||
#### `make build`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 检测操作系统
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# Windows: 创建bin目录 (如果不存在)
|
||||
@if not exist "bin" mkdir "bin"
|
||||
else
|
||||
# Unix: 创建bin目录
|
||||
@mkdir -p bin
|
||||
endif
|
||||
|
||||
# 步骤2: 构建Go应用程序
|
||||
go build -ldflags "-X main.version=1.0.0 -X main.commit=abc123 -X main.date=2025-01-01T00:00:00Z" -o bin/tyapi-server cmd/api/main.go
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **环境检测**: 通过 `$(OS)` 变量检测操作系统
|
||||
2. **目录创建**:
|
||||
- Windows: `if not exist "bin" mkdir "bin"`
|
||||
- Unix: `mkdir -p bin`
|
||||
3. **版本信息收集**:
|
||||
- `BUILD_TIME`: PowerShell/date 命令获取当前时间
|
||||
- `GIT_COMMIT`: git 命令获取当前 commit hash
|
||||
- `VERSION`: 硬编码版本号 1.0.0
|
||||
4. **编译执行**:
|
||||
- 使用 `go build` 命令
|
||||
- `-ldflags` 注入版本信息到可执行文件
|
||||
- 输出文件到 `bin/tyapi-server`
|
||||
|
||||
**生成文件**: `bin/tyapi-server` (Windows 下为 `.exe`)
|
||||
|
||||
#### `make build-prod`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 创建bin目录 (同build)
|
||||
# 步骤2: 生产环境构建
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "..." -a -installsuffix cgo -o bin/tyapi-server-linux-amd64 cmd/api/main.go
|
||||
```
|
||||
|
||||
**关键参数解析**:
|
||||
|
||||
- `CGO_ENABLED=0`: 禁用 CGO,生成纯静态二进制
|
||||
- `GOOS=linux GOARCH=amd64`: 强制 Linux 64 位平台
|
||||
- `-a`: 重新构建所有包
|
||||
- `-installsuffix cgo`: 避免缓存冲突
|
||||
- **结果**: 生成可在任何 Linux x64 环境运行的静态二进制文件
|
||||
|
||||
#### `make build-all`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 创建bin目录
|
||||
# 步骤2: 循环构建5个平台
|
||||
# Linux AMD64
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build ... -o bin/tyapi-server-linux-amd64
|
||||
# Linux ARM64
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build ... -o bin/tyapi-server-linux-arm64
|
||||
# macOS Intel
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build ... -o bin/tyapi-server-darwin-amd64
|
||||
# macOS Apple Silicon
|
||||
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build ... -o bin/tyapi-server-darwin-arm64
|
||||
# Windows
|
||||
CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build ... -o bin/tyapi-server-windows-amd64.exe
|
||||
```
|
||||
|
||||
**生成的 5 个文件**:
|
||||
|
||||
- `bin/tyapi-server-linux-amd64`
|
||||
- `bin/tyapi-server-linux-arm64`
|
||||
- `bin/tyapi-server-darwin-amd64`
|
||||
- `bin/tyapi-server-darwin-arm64`
|
||||
- `bin/tyapi-server-windows-amd64.exe`
|
||||
|
||||
---
|
||||
|
||||
### ▶️ **运行相关命令**
|
||||
|
||||
#### `make run`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 执行make build (依赖)
|
||||
# 步骤2: 直接运行构建好的二进制文件
|
||||
./bin/tyapi-server
|
||||
```
|
||||
|
||||
**详细流程**:
|
||||
|
||||
1. **依赖检查**: Make 自动检查 build 目标是否需要重新执行
|
||||
2. **文件存在性检查**: 确认 `bin/tyapi-server` 存在
|
||||
3. **权限检查**: Unix 系统检查执行权限
|
||||
4. **进程启动**: 启动 Gin HTTP 服务器
|
||||
5. **端口监听**: 默认监听 8080 端口
|
||||
|
||||
**运行环境**: 需要 PostgreSQL 和 Redis 服务可用
|
||||
|
||||
#### `make dev`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 直接执行 (已去掉air检查)
|
||||
go run cmd/api/main.go
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **源码编译**: Go 编译器实时编译 main.go 及其依赖
|
||||
2. **内存运行**: 不生成磁盘文件,直接在内存中运行
|
||||
3. **依赖加载**: 自动下载并编译所有 import 的包
|
||||
4. **服务启动**: 启动 HTTP 服务器监听 8080 端口
|
||||
|
||||
**与 build 的区别**:
|
||||
|
||||
- ✅ 无需预先构建
|
||||
- ✅ 代码变更后需手动重启
|
||||
- ❌ 每次启动都需要重新编译
|
||||
|
||||
---
|
||||
|
||||
### 🛠️ **开发工具命令**
|
||||
|
||||
#### `make deps`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 下载依赖
|
||||
go mod download
|
||||
# 步骤2: 整理依赖
|
||||
go mod tidy
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **go mod download**:
|
||||
- 读取 `go.mod` 文件
|
||||
- 下载所有依赖包到 `$GOPATH/pkg/mod/`
|
||||
- 验证包的 checksum (通过 go.sum)
|
||||
- 不修改 go.mod 文件
|
||||
2. **go mod tidy**:
|
||||
- 扫描所有.go 文件中的 import 语句
|
||||
- 添加缺失的依赖到 go.mod
|
||||
- 移除未使用的依赖
|
||||
- 更新 go.sum 文件
|
||||
|
||||
**影响的文件**: `go.mod`, `go.sum`, `$GOPATH/pkg/mod/`
|
||||
|
||||
#### `make fmt`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
go fmt ./...
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **递归扫描**: 扫描当前目录及所有子目录的.go 文件
|
||||
2. **格式化规则应用**:
|
||||
- 统一缩进 (tab)
|
||||
- 统一换行
|
||||
- 移除行尾空格
|
||||
- 规范化大括号位置
|
||||
3. **文件修改**: 直接修改源文件 (in-place)
|
||||
4. **报告**: 输出被修改的文件列表
|
||||
|
||||
**影响的文件**: 所有.go 源码文件
|
||||
|
||||
#### `make lint`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 检查golangci-lint是否安装
|
||||
@if command -v golangci-lint >/dev/null 2>&1; then \
|
||||
golangci-lint run; \
|
||||
else \
|
||||
echo "golangci-lint not installed, skipping lint check"; \
|
||||
fi
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **工具检查**: 使用 `command -v` 检查 golangci-lint 是否在 PATH 中
|
||||
2. **如果已安装**:
|
||||
- 读取 `.golangci.yml` 配置 (如果存在)
|
||||
- 运行多个 linter 检查 (默认包括: errcheck, gosimple, govet, ineffassign 等)
|
||||
- 分析所有.go 文件
|
||||
- 输出问题报告
|
||||
3. **如果未安装**: 显示提示信息并跳过
|
||||
|
||||
**检查项目**: 代码质量、潜在 bug、性能问题、安全问题等
|
||||
|
||||
---
|
||||
|
||||
### 🧪 **测试相关命令**
|
||||
|
||||
#### `make test`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
go test -v -race -coverprofile=coverage.out ./...
|
||||
```
|
||||
|
||||
**参数详解**:
|
||||
|
||||
- `-v`: 详细输出,显示每个测试的名称和结果
|
||||
- `-race`: 启用竞态条件检测器
|
||||
- `-coverprofile=coverage.out`: 生成覆盖率数据文件
|
||||
- `./...`: 递归测试所有包
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **包发现**: 递归扫描所有包含\*\_test.go 的目录
|
||||
2. **编译测试**: 为每个包编译测试二进制文件
|
||||
3. **竞态检测**: 启用 Go race detector
|
||||
4. **执行测试**: 逐个运行 Test\*函数
|
||||
5. **覆盖率收集**: 记录每行代码是否被执行
|
||||
6. **生成报告**: 输出到 coverage.out 文件
|
||||
|
||||
**生成文件**: `coverage.out`
|
||||
|
||||
#### `make coverage`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 执行make test (依赖)
|
||||
# 步骤2: 生成HTML报告
|
||||
go tool cover -html=coverage.out -o coverage.html
|
||||
# 步骤3: 提示用户
|
||||
@echo "Coverage report generated: coverage.html"
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **依赖检查**: 确保 coverage.out 文件存在
|
||||
2. **HTML 生成**:
|
||||
- 读取 coverage.out 二进制数据
|
||||
- 生成带颜色标记的 HTML 页面
|
||||
- 绿色 = 已覆盖,红色 = 未覆盖
|
||||
3. **文件输出**: 生成 coverage.html 文件
|
||||
|
||||
**生成文件**: `coverage.html` (可在浏览器中打开)
|
||||
|
||||
---
|
||||
|
||||
### 🗂️ **环境管理命令**
|
||||
|
||||
#### `make env`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# Windows环境
|
||||
ifeq ($(OS),Windows_NT)
|
||||
@if not exist ".env" ( \
|
||||
echo Creating .env file... && \
|
||||
copy env.example .env && \
|
||||
echo .env file created, please modify configuration as needed \
|
||||
) else ( \
|
||||
echo .env file already exists \
|
||||
)
|
||||
# Unix环境
|
||||
else
|
||||
@if [ ! -f .env ]; then \
|
||||
echo "Creating .env file..."; \
|
||||
cp env.example .env; \
|
||||
echo ".env file created, please modify configuration as needed"; \
|
||||
else \
|
||||
echo ".env file already exists"; \
|
||||
fi
|
||||
endif
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **文件检查**: 检查.env 文件是否已存在
|
||||
2. **如果不存在**:
|
||||
- Windows: 使用 `copy` 命令复制
|
||||
- Unix: 使用 `cp` 命令复制
|
||||
- 复制 `env.example` → `.env`
|
||||
3. **如果已存在**: 显示提示信息,不覆盖现有文件
|
||||
|
||||
**相关文件**: `env.example` → `.env`
|
||||
|
||||
#### `make setup`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 依赖: make deps env
|
||||
# 然后执行:
|
||||
@echo "Setting up development environment..."
|
||||
@echo "1. Dependencies installed"
|
||||
@echo "2. .env file created"
|
||||
@echo "3. Please ensure PostgreSQL and Redis are running"
|
||||
@echo "4. Run 'make migrate' to create database tables"
|
||||
@echo "5. Run 'make dev' to start development server"
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **执行 make deps**: 安装 Go 依赖
|
||||
2. **执行 make env**: 创建环境配置文件
|
||||
3. **输出设置指南**: 显示后续步骤提示
|
||||
|
||||
**完成后状态**: 开发环境基本就绪,需要手动启动数据库服务
|
||||
|
||||
---
|
||||
|
||||
### 🐳 **Docker 相关命令**
|
||||
|
||||
#### `make docker-build`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
docker build -t tyapi-server:1.0.0 -t tyapi-server:latest .
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **读取 Dockerfile**: 从当前目录读取 Dockerfile
|
||||
2. **构建上下文**: 将当前目录作为构建上下文发送给 Docker daemon
|
||||
3. **镜像构建**:
|
||||
- 执行 Dockerfile 中的每个指令
|
||||
- 逐层构建镜像
|
||||
- 缓存中间层以提高构建速度
|
||||
4. **标签应用**: 同时打上版本标签和 latest 标签
|
||||
|
||||
**生成镜像**: `tyapi-server:1.0.0`, `tyapi-server:latest`
|
||||
|
||||
#### `make docker-run`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
docker run -d --name tyapi-server -p 8080:8080 --env-file .env tyapi-server:latest
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **环境检查**: 确认.env 文件存在
|
||||
2. **容器创建**: 基于 latest 镜像创建容器
|
||||
3. **参数应用**:
|
||||
- `-d`: 后台运行 (detached mode)
|
||||
- `--name tyapi-server`: 设置容器名称
|
||||
- `-p 8080:8080`: 端口映射 (主机:容器)
|
||||
- `--env-file .env`: 加载环境变量文件
|
||||
4. **容器启动**: 启动应用程序进程
|
||||
|
||||
**结果**: 后台运行的 Docker 容器,端口 8080 可访问
|
||||
|
||||
---
|
||||
|
||||
### 🔧 **服务管理命令**
|
||||
|
||||
#### `make services-up` / `make dev-up`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 检查docker-compose.dev.yml文件
|
||||
# Windows:
|
||||
@if exist "docker-compose.dev.yml" ( \
|
||||
docker-compose -f docker-compose.dev.yml up -d \
|
||||
) else ( \
|
||||
echo docker-compose.dev.yml not found \
|
||||
)
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **文件检查**: 验证 docker-compose.dev.yml 文件存在
|
||||
2. **Docker Compose 启动**:
|
||||
- 读取 docker-compose.dev.yml 配置
|
||||
- 拉取所需的 Docker 镜像 (如果本地不存在)
|
||||
- 创建 Docker 网络 (tyapi-network)
|
||||
- 创建数据卷 (postgres_data, redis_data 等)
|
||||
- 按依赖顺序启动服务:
|
||||
- PostgreSQL (端口 5432)
|
||||
- Redis (端口 6379)
|
||||
- pgAdmin (端口 5050)
|
||||
- Prometheus (端口 9090)
|
||||
- Grafana (端口 3000)
|
||||
- Jaeger (端口 16686)
|
||||
- MinIO (端口 9000/9001)
|
||||
- MailHog (端口 8025)
|
||||
|
||||
**启动的 8 个服务**: 数据库、缓存、监控、管理工具等完整开发环境
|
||||
|
||||
#### `make services-down` / `make dev-down`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
docker-compose -f docker-compose.dev.yml down
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **容器停止**: 优雅停止所有服务容器 (发送 SIGTERM)
|
||||
2. **容器删除**: 删除所有相关容器
|
||||
3. **网络清理**: 删除自定义网络
|
||||
4. **数据保留**: 保留数据卷 (数据不丢失)
|
||||
|
||||
**保留的资源**: 数据卷、镜像
|
||||
**删除的资源**: 容器、网络
|
||||
|
||||
---
|
||||
|
||||
### 🗃️ **数据库相关命令**
|
||||
|
||||
#### `make migrate`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 执行make build (依赖)
|
||||
# 步骤2: 运行迁移
|
||||
./bin/tyapi-server -migrate
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **应用程序启动**: 以迁移模式启动应用
|
||||
2. **数据库连接**: 连接到 PostgreSQL 数据库
|
||||
3. **迁移文件扫描**: 扫描 migrations 目录下的 SQL 文件
|
||||
4. **版本检查**: 检查数据库中的迁移版本表
|
||||
5. **增量执行**: 只执行未应用的迁移文件
|
||||
6. **版本更新**: 更新迁移版本记录
|
||||
7. **应用退出**: 迁移完成后程序退出
|
||||
|
||||
**相关文件**: `internal/domains/user/migrations/`, PostgreSQL 数据库
|
||||
|
||||
#### `make health`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: 执行make build (依赖)
|
||||
# 步骤2: 运行健康检查
|
||||
./bin/tyapi-server -health
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **健康检查启动**: 以健康检查模式启动应用
|
||||
2. **组件检查**:
|
||||
- PostgreSQL 数据库连接
|
||||
- Redis 缓存连接
|
||||
- 关键配置项验证
|
||||
- 必要文件存在性检查
|
||||
3. **状态报告**: 输出每个组件的健康状态
|
||||
4. **退出码**: 成功返回 0,失败返回非零
|
||||
|
||||
**检查项目**: 数据库、缓存、配置、权限等
|
||||
|
||||
---
|
||||
|
||||
### 🧹 **清理命令**
|
||||
|
||||
#### `make clean`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 步骤1: Go缓存清理
|
||||
go clean
|
||||
# 步骤2: 文件删除 (根据操作系统)
|
||||
# Windows:
|
||||
@if exist "bin" rmdir /s /q "bin" 2>nul || echo ""
|
||||
@if exist "coverage.out" del /f /q "coverage.out" 2>nul || echo ""
|
||||
@if exist "coverage.html" del /f /q "coverage.html" 2>nul || echo ""
|
||||
```
|
||||
|
||||
**详细步骤**:
|
||||
|
||||
1. **Go 清理**:
|
||||
- 清理编译缓存
|
||||
- 删除临时构建文件
|
||||
- 清理测试缓存
|
||||
2. **目录删除**:
|
||||
- 删除整个 bin 目录及内容
|
||||
- Windows: `rmdir /s /q`
|
||||
- Unix: `rm -rf`
|
||||
3. **文件删除**:
|
||||
- 删除 coverage.out 测试覆盖率文件
|
||||
- 删除 coverage.html 覆盖率报告
|
||||
4. **错误抑制**: 使用 `2>nul` 或 `2>/dev/null` 忽略"文件不存在"错误
|
||||
|
||||
**删除的内容**: `bin/`, `coverage.out`, `coverage.html`, Go 构建缓存
|
||||
|
||||
---
|
||||
|
||||
### 🚀 **流水线命令**
|
||||
|
||||
#### `make ci`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 顺序执行5个步骤:
|
||||
make deps # 安装依赖
|
||||
make fmt # 代码格式化
|
||||
make lint # 代码检查
|
||||
make test # 运行测试
|
||||
make build # 构建应用
|
||||
```
|
||||
|
||||
**详细流程**:
|
||||
|
||||
1. **deps**: 确保所有依赖最新且完整
|
||||
2. **fmt**: 统一代码格式,确保可读性
|
||||
3. **lint**: 静态代码分析,发现潜在问题
|
||||
4. **test**: 运行所有测试,确保功能正确
|
||||
5. **build**: 验证代码可以成功编译
|
||||
|
||||
**失败策略**: 任何一步失败,立即停止后续步骤
|
||||
|
||||
#### `make release`
|
||||
|
||||
**执行逻辑**:
|
||||
|
||||
```bash
|
||||
# 顺序执行3个步骤:
|
||||
make ci # 完整CI检查
|
||||
make build-all # 交叉编译所有平台
|
||||
make docker-build # 构建Docker镜像
|
||||
```
|
||||
|
||||
**详细流程**:
|
||||
|
||||
1. **CI 检查**: 确保代码质量和功能正确性
|
||||
2. **多平台构建**: 生成 5 个平台的可执行文件
|
||||
3. **Docker 镜像**: 构建容器化版本
|
||||
|
||||
**输出产物**:
|
||||
|
||||
- 5 个平台的二进制文件
|
||||
- Docker 镜像 (2 个标签)
|
||||
- 测试覆盖率报告
|
||||
|
||||
---
|
||||
|
||||
## 💡 **命令执行顺序和依赖关系**
|
||||
|
||||
### 🔗 **依赖关系图**
|
||||
|
||||
```
|
||||
version ─────► build
|
||||
health ──────► build
|
||||
run ─────────► build
|
||||
migrate ─────► build
|
||||
|
||||
coverage ────► test
|
||||
ci ──────────► deps → fmt → lint → test → build
|
||||
release ─────► ci → build-all → docker-build
|
||||
setup ───────► deps → env
|
||||
```
|
||||
|
||||
### ⚡ **执行时机建议**
|
||||
|
||||
#### **每次开发前**
|
||||
|
||||
```bash
|
||||
make setup # 首次使用
|
||||
make dev-up # 启动依赖服务
|
||||
make dev # 开始开发
|
||||
```
|
||||
|
||||
#### **提交代码前**
|
||||
|
||||
```bash
|
||||
make ci # 完整检查
|
||||
```
|
||||
|
||||
#### **发布版本前**
|
||||
|
||||
```bash
|
||||
make release # 完整构建
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**这个指南详细说明了每个命令背后的具体操作逻辑,帮助您完全理解 Makefile 的工作原理!** 🎯
|
||||
8
docs/docs.go
Normal file
8
docs/docs.go
Normal file
@@ -0,0 +1,8 @@
|
||||
// Package docs 生成的API文档包
|
||||
// 这个包导入了自动生成的Swagger文档
|
||||
package docs
|
||||
|
||||
import (
|
||||
// 导入生成的swagger文档
|
||||
_ "tyapi-server/docs/swagger"
|
||||
)
|
||||
592
docs/swagger/docs.go
Normal file
592
docs/swagger/docs.go
Normal file
@@ -0,0 +1,592 @@
|
||||
// Package swagger Code generated by swaggo/swag. DO NOT EDIT
|
||||
package swagger
|
||||
|
||||
import "github.com/swaggo/swag"
|
||||
|
||||
const docTemplate = `{
|
||||
"schemes": {{ marshal .Schemes }},
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "{{escape .Description}}",
|
||||
"title": "{{.Title}}",
|
||||
"contact": {
|
||||
"name": "API Support",
|
||||
"url": "https://github.com/your-org/tyapi-server-gin",
|
||||
"email": "support@example.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
},
|
||||
"version": "{{.Version}}"
|
||||
},
|
||||
"host": "{{.Host}}",
|
||||
"basePath": "{{.BasePath}}",
|
||||
"paths": {
|
||||
"/users/login-password": {
|
||||
"post": {
|
||||
"description": "使用手机号和密码进行用户登录,返回JWT令牌",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "用户密码登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "密码登录请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginWithPasswordRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "登录成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "认证失败",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/login-sms": {
|
||||
"post": {
|
||||
"description": "使用手机号和短信验证码进行用户登录,返回JWT令牌",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "用户短信验证码登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "短信登录请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginWithSMSRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "登录成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误或验证码无效",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "认证失败",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/me": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "根据JWT令牌获取当前登录用户的详细信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户管理"
|
||||
],
|
||||
"summary": "获取当前用户信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "用户信息",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UserResponse"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "未认证",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "用户不存在",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/me/password": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "使用旧密码、新密码确认和验证码修改当前用户的密码",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户管理"
|
||||
],
|
||||
"summary": "修改密码",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "修改密码请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.ChangePasswordRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "密码修改成功",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误或验证码无效",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "未认证",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/register": {
|
||||
"post": {
|
||||
"description": "使用手机号、密码和验证码进行用户注册,需要确认密码",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "用户注册",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "用户注册请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.RegisterRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "注册成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UserResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误或验证码无效",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "手机号已存在",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/send-code": {
|
||||
"post": {
|
||||
"description": "向指定手机号发送验证码,支持注册、登录、修改密码等场景",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "发送短信验证码",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "发送验证码请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.SendCodeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "验证码发送成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.SendCodeResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"429": {
|
||||
"description": "请求频率限制",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"dto.ChangePasswordRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"confirm_new_password",
|
||||
"new_password",
|
||||
"old_password"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "123456"
|
||||
},
|
||||
"confirm_new_password": {
|
||||
"type": "string",
|
||||
"example": "newpassword123"
|
||||
},
|
||||
"new_password": {
|
||||
"type": "string",
|
||||
"maxLength": 128,
|
||||
"minLength": 6,
|
||||
"example": "newpassword123"
|
||||
},
|
||||
"old_password": {
|
||||
"type": "string",
|
||||
"example": "oldpassword123"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LoginResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access_token": {
|
||||
"type": "string",
|
||||
"example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
},
|
||||
"expires_in": {
|
||||
"type": "integer",
|
||||
"example": 86400
|
||||
},
|
||||
"login_method": {
|
||||
"description": "password 或 sms",
|
||||
"type": "string",
|
||||
"example": "password"
|
||||
},
|
||||
"token_type": {
|
||||
"type": "string",
|
||||
"example": "Bearer"
|
||||
},
|
||||
"user": {
|
||||
"$ref": "#/definitions/dto.UserResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LoginWithPasswordRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"phone"
|
||||
],
|
||||
"properties": {
|
||||
"password": {
|
||||
"type": "string",
|
||||
"example": "password123"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LoginWithSMSRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"phone"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "123456"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RegisterRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"confirm_password",
|
||||
"password",
|
||||
"phone"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "123456"
|
||||
},
|
||||
"confirm_password": {
|
||||
"type": "string",
|
||||
"example": "password123"
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"maxLength": 128,
|
||||
"minLength": 6,
|
||||
"example": "password123"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.SendCodeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"phone",
|
||||
"scene"
|
||||
],
|
||||
"properties": {
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
},
|
||||
"scene": {
|
||||
"enum": [
|
||||
"register",
|
||||
"login",
|
||||
"change_password",
|
||||
"reset_password",
|
||||
"bind",
|
||||
"unbind"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/entities.SMSScene"
|
||||
}
|
||||
],
|
||||
"example": "register"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.SendCodeResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"expires_at": {
|
||||
"type": "string",
|
||||
"example": "2024-01-01T00:05:00Z"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "验证码发送成功"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.UserResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"example": "2024-01-01T00:00:00Z"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"example": "123e4567-e89b-12d3-a456-426614174000"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"example": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"entities.SMSScene": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"register",
|
||||
"login",
|
||||
"change_password",
|
||||
"reset_password",
|
||||
"bind",
|
||||
"unbind"
|
||||
],
|
||||
"x-enum-comments": {
|
||||
"SMSSceneBind": "绑定手机号",
|
||||
"SMSSceneChangePassword": "修改密码",
|
||||
"SMSSceneLogin": "登录",
|
||||
"SMSSceneRegister": "注册",
|
||||
"SMSSceneResetPassword": "重置密码",
|
||||
"SMSSceneUnbind": "解绑手机号"
|
||||
},
|
||||
"x-enum-varnames": [
|
||||
"SMSSceneRegister",
|
||||
"SMSSceneLogin",
|
||||
"SMSSceneChangePassword",
|
||||
"SMSSceneResetPassword",
|
||||
"SMSSceneBind",
|
||||
"SMSSceneUnbind"
|
||||
]
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"Bearer": {
|
||||
"description": "Type \"Bearer\" followed by a space and JWT token.",
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||
var SwaggerInfo = &swag.Spec{
|
||||
Version: "1.0",
|
||||
Host: "localhost:8080",
|
||||
BasePath: "/api/v1",
|
||||
Schemes: []string{},
|
||||
Title: "TYAPI Server API",
|
||||
Description: "基于DDD和Clean Architecture的企业级后端API服务\n采用Gin框架构建,支持用户管理、JWT认证、事件驱动等功能",
|
||||
InfoInstanceName: "swagger",
|
||||
SwaggerTemplate: docTemplate,
|
||||
LeftDelim: "{{",
|
||||
RightDelim: "}}",
|
||||
}
|
||||
|
||||
func init() {
|
||||
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||
}
|
||||
568
docs/swagger/swagger.json
Normal file
568
docs/swagger/swagger.json
Normal file
@@ -0,0 +1,568 @@
|
||||
{
|
||||
"swagger": "2.0",
|
||||
"info": {
|
||||
"description": "基于DDD和Clean Architecture的企业级后端API服务\n采用Gin框架构建,支持用户管理、JWT认证、事件驱动等功能",
|
||||
"title": "TYAPI Server API",
|
||||
"contact": {
|
||||
"name": "API Support",
|
||||
"url": "https://github.com/your-org/tyapi-server-gin",
|
||||
"email": "support@example.com"
|
||||
},
|
||||
"license": {
|
||||
"name": "Apache 2.0",
|
||||
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
|
||||
},
|
||||
"version": "1.0"
|
||||
},
|
||||
"host": "localhost:8080",
|
||||
"basePath": "/api/v1",
|
||||
"paths": {
|
||||
"/users/login-password": {
|
||||
"post": {
|
||||
"description": "使用手机号和密码进行用户登录,返回JWT令牌",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "用户密码登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "密码登录请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginWithPasswordRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "登录成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "认证失败",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/login-sms": {
|
||||
"post": {
|
||||
"description": "使用手机号和短信验证码进行用户登录,返回JWT令牌",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "用户短信验证码登录",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "短信登录请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginWithSMSRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "登录成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.LoginResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误或验证码无效",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "认证失败",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/me": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "根据JWT令牌获取当前登录用户的详细信息",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户管理"
|
||||
],
|
||||
"summary": "获取当前用户信息",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "用户信息",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UserResponse"
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "未认证",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "用户不存在",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/me/password": {
|
||||
"put": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"description": "使用旧密码、新密码确认和验证码修改当前用户的密码",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户管理"
|
||||
],
|
||||
"summary": "修改密码",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "修改密码请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.ChangePasswordRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "密码修改成功",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误或验证码无效",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "未认证",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/register": {
|
||||
"post": {
|
||||
"description": "使用手机号、密码和验证码进行用户注册,需要确认密码",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "用户注册",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "用户注册请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.RegisterRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "注册成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.UserResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误或验证码无效",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"409": {
|
||||
"description": "手机号已存在",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/send-code": {
|
||||
"post": {
|
||||
"description": "向指定手机号发送验证码,支持注册、登录、修改密码等场景",
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"用户认证"
|
||||
],
|
||||
"summary": "发送短信验证码",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "发送验证码请求",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.SendCodeRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "验证码发送成功",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/dto.SendCodeResponse"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "请求参数错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"429": {
|
||||
"description": "请求频率限制",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "服务器内部错误",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"definitions": {
|
||||
"dto.ChangePasswordRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"confirm_new_password",
|
||||
"new_password",
|
||||
"old_password"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "123456"
|
||||
},
|
||||
"confirm_new_password": {
|
||||
"type": "string",
|
||||
"example": "newpassword123"
|
||||
},
|
||||
"new_password": {
|
||||
"type": "string",
|
||||
"maxLength": 128,
|
||||
"minLength": 6,
|
||||
"example": "newpassword123"
|
||||
},
|
||||
"old_password": {
|
||||
"type": "string",
|
||||
"example": "oldpassword123"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LoginResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"access_token": {
|
||||
"type": "string",
|
||||
"example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
||||
},
|
||||
"expires_in": {
|
||||
"type": "integer",
|
||||
"example": 86400
|
||||
},
|
||||
"login_method": {
|
||||
"description": "password 或 sms",
|
||||
"type": "string",
|
||||
"example": "password"
|
||||
},
|
||||
"token_type": {
|
||||
"type": "string",
|
||||
"example": "Bearer"
|
||||
},
|
||||
"user": {
|
||||
"$ref": "#/definitions/dto.UserResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LoginWithPasswordRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"password",
|
||||
"phone"
|
||||
],
|
||||
"properties": {
|
||||
"password": {
|
||||
"type": "string",
|
||||
"example": "password123"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.LoginWithSMSRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"phone"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "123456"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.RegisterRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"code",
|
||||
"confirm_password",
|
||||
"password",
|
||||
"phone"
|
||||
],
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "string",
|
||||
"example": "123456"
|
||||
},
|
||||
"confirm_password": {
|
||||
"type": "string",
|
||||
"example": "password123"
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"maxLength": 128,
|
||||
"minLength": 6,
|
||||
"example": "password123"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.SendCodeRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"phone",
|
||||
"scene"
|
||||
],
|
||||
"properties": {
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
},
|
||||
"scene": {
|
||||
"enum": [
|
||||
"register",
|
||||
"login",
|
||||
"change_password",
|
||||
"reset_password",
|
||||
"bind",
|
||||
"unbind"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/entities.SMSScene"
|
||||
}
|
||||
],
|
||||
"example": "register"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.SendCodeResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"expires_at": {
|
||||
"type": "string",
|
||||
"example": "2024-01-01T00:05:00Z"
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "验证码发送成功"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dto.UserResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"example": "2024-01-01T00:00:00Z"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"example": "123e4567-e89b-12d3-a456-426614174000"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string",
|
||||
"example": "13800138000"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"example": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
}
|
||||
},
|
||||
"entities.SMSScene": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"register",
|
||||
"login",
|
||||
"change_password",
|
||||
"reset_password",
|
||||
"bind",
|
||||
"unbind"
|
||||
],
|
||||
"x-enum-comments": {
|
||||
"SMSSceneBind": "绑定手机号",
|
||||
"SMSSceneChangePassword": "修改密码",
|
||||
"SMSSceneLogin": "登录",
|
||||
"SMSSceneRegister": "注册",
|
||||
"SMSSceneResetPassword": "重置密码",
|
||||
"SMSSceneUnbind": "解绑手机号"
|
||||
},
|
||||
"x-enum-varnames": [
|
||||
"SMSSceneRegister",
|
||||
"SMSSceneLogin",
|
||||
"SMSSceneChangePassword",
|
||||
"SMSSceneResetPassword",
|
||||
"SMSSceneBind",
|
||||
"SMSSceneUnbind"
|
||||
]
|
||||
}
|
||||
},
|
||||
"securityDefinitions": {
|
||||
"Bearer": {
|
||||
"description": "Type \"Bearer\" followed by a space and JWT token.",
|
||||
"type": "apiKey",
|
||||
"name": "Authorization",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
}
|
||||
397
docs/swagger/swagger.yaml
Normal file
397
docs/swagger/swagger.yaml
Normal file
@@ -0,0 +1,397 @@
|
||||
basePath: /api/v1
|
||||
definitions:
|
||||
dto.ChangePasswordRequest:
|
||||
properties:
|
||||
code:
|
||||
example: "123456"
|
||||
type: string
|
||||
confirm_new_password:
|
||||
example: newpassword123
|
||||
type: string
|
||||
new_password:
|
||||
example: newpassword123
|
||||
maxLength: 128
|
||||
minLength: 6
|
||||
type: string
|
||||
old_password:
|
||||
example: oldpassword123
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
- confirm_new_password
|
||||
- new_password
|
||||
- old_password
|
||||
type: object
|
||||
dto.LoginResponse:
|
||||
properties:
|
||||
access_token:
|
||||
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
type: string
|
||||
expires_in:
|
||||
example: 86400
|
||||
type: integer
|
||||
login_method:
|
||||
description: password 或 sms
|
||||
example: password
|
||||
type: string
|
||||
token_type:
|
||||
example: Bearer
|
||||
type: string
|
||||
user:
|
||||
$ref: '#/definitions/dto.UserResponse'
|
||||
type: object
|
||||
dto.LoginWithPasswordRequest:
|
||||
properties:
|
||||
password:
|
||||
example: password123
|
||||
type: string
|
||||
phone:
|
||||
example: "13800138000"
|
||||
type: string
|
||||
required:
|
||||
- password
|
||||
- phone
|
||||
type: object
|
||||
dto.LoginWithSMSRequest:
|
||||
properties:
|
||||
code:
|
||||
example: "123456"
|
||||
type: string
|
||||
phone:
|
||||
example: "13800138000"
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
- phone
|
||||
type: object
|
||||
dto.RegisterRequest:
|
||||
properties:
|
||||
code:
|
||||
example: "123456"
|
||||
type: string
|
||||
confirm_password:
|
||||
example: password123
|
||||
type: string
|
||||
password:
|
||||
example: password123
|
||||
maxLength: 128
|
||||
minLength: 6
|
||||
type: string
|
||||
phone:
|
||||
example: "13800138000"
|
||||
type: string
|
||||
required:
|
||||
- code
|
||||
- confirm_password
|
||||
- password
|
||||
- phone
|
||||
type: object
|
||||
dto.SendCodeRequest:
|
||||
properties:
|
||||
phone:
|
||||
example: "13800138000"
|
||||
type: string
|
||||
scene:
|
||||
allOf:
|
||||
- $ref: '#/definitions/entities.SMSScene'
|
||||
enum:
|
||||
- register
|
||||
- login
|
||||
- change_password
|
||||
- reset_password
|
||||
- bind
|
||||
- unbind
|
||||
example: register
|
||||
required:
|
||||
- phone
|
||||
- scene
|
||||
type: object
|
||||
dto.SendCodeResponse:
|
||||
properties:
|
||||
expires_at:
|
||||
example: "2024-01-01T00:05:00Z"
|
||||
type: string
|
||||
message:
|
||||
example: 验证码发送成功
|
||||
type: string
|
||||
type: object
|
||||
dto.UserResponse:
|
||||
properties:
|
||||
created_at:
|
||||
example: "2024-01-01T00:00:00Z"
|
||||
type: string
|
||||
id:
|
||||
example: 123e4567-e89b-12d3-a456-426614174000
|
||||
type: string
|
||||
phone:
|
||||
example: "13800138000"
|
||||
type: string
|
||||
updated_at:
|
||||
example: "2024-01-01T00:00:00Z"
|
||||
type: string
|
||||
type: object
|
||||
entities.SMSScene:
|
||||
enum:
|
||||
- register
|
||||
- login
|
||||
- change_password
|
||||
- reset_password
|
||||
- bind
|
||||
- unbind
|
||||
type: string
|
||||
x-enum-comments:
|
||||
SMSSceneBind: 绑定手机号
|
||||
SMSSceneChangePassword: 修改密码
|
||||
SMSSceneLogin: 登录
|
||||
SMSSceneRegister: 注册
|
||||
SMSSceneResetPassword: 重置密码
|
||||
SMSSceneUnbind: 解绑手机号
|
||||
x-enum-varnames:
|
||||
- SMSSceneRegister
|
||||
- SMSSceneLogin
|
||||
- SMSSceneChangePassword
|
||||
- SMSSceneResetPassword
|
||||
- SMSSceneBind
|
||||
- SMSSceneUnbind
|
||||
host: localhost:8080
|
||||
info:
|
||||
contact:
|
||||
email: support@example.com
|
||||
name: API Support
|
||||
url: https://github.com/your-org/tyapi-server-gin
|
||||
description: |-
|
||||
基于DDD和Clean Architecture的企业级后端API服务
|
||||
采用Gin框架构建,支持用户管理、JWT认证、事件驱动等功能
|
||||
license:
|
||||
name: Apache 2.0
|
||||
url: http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
title: TYAPI Server API
|
||||
version: "1.0"
|
||||
paths:
|
||||
/users/login-password:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用手机号和密码进行用户登录,返回JWT令牌
|
||||
parameters:
|
||||
- description: 密码登录请求
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.LoginWithPasswordRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 登录成功
|
||||
schema:
|
||||
$ref: '#/definitions/dto.LoginResponse'
|
||||
"400":
|
||||
description: 请求参数错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"401":
|
||||
description: 认证失败
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: 用户密码登录
|
||||
tags:
|
||||
- 用户认证
|
||||
/users/login-sms:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用手机号和短信验证码进行用户登录,返回JWT令牌
|
||||
parameters:
|
||||
- description: 短信登录请求
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.LoginWithSMSRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 登录成功
|
||||
schema:
|
||||
$ref: '#/definitions/dto.LoginResponse'
|
||||
"400":
|
||||
description: 请求参数错误或验证码无效
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"401":
|
||||
description: 认证失败
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: 用户短信验证码登录
|
||||
tags:
|
||||
- 用户认证
|
||||
/users/me:
|
||||
get:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 根据JWT令牌获取当前登录用户的详细信息
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 用户信息
|
||||
schema:
|
||||
$ref: '#/definitions/dto.UserResponse'
|
||||
"401":
|
||||
description: 未认证
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"404":
|
||||
description: 用户不存在
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: 获取当前用户信息
|
||||
tags:
|
||||
- 用户管理
|
||||
/users/me/password:
|
||||
put:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用旧密码、新密码确认和验证码修改当前用户的密码
|
||||
parameters:
|
||||
- description: 修改密码请求
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.ChangePasswordRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 密码修改成功
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"400":
|
||||
description: 请求参数错误或验证码无效
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"401":
|
||||
description: 未认证
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: 修改密码
|
||||
tags:
|
||||
- 用户管理
|
||||
/users/register:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 使用手机号、密码和验证码进行用户注册,需要确认密码
|
||||
parameters:
|
||||
- description: 用户注册请求
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.RegisterRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"201":
|
||||
description: 注册成功
|
||||
schema:
|
||||
$ref: '#/definitions/dto.UserResponse'
|
||||
"400":
|
||||
description: 请求参数错误或验证码无效
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"409":
|
||||
description: 手机号已存在
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: 用户注册
|
||||
tags:
|
||||
- 用户认证
|
||||
/users/send-code:
|
||||
post:
|
||||
consumes:
|
||||
- application/json
|
||||
description: 向指定手机号发送验证码,支持注册、登录、修改密码等场景
|
||||
parameters:
|
||||
- description: 发送验证码请求
|
||||
in: body
|
||||
name: request
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/dto.SendCodeRequest'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: 验证码发送成功
|
||||
schema:
|
||||
$ref: '#/definitions/dto.SendCodeResponse'
|
||||
"400":
|
||||
description: 请求参数错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"429":
|
||||
description: 请求频率限制
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
"500":
|
||||
description: 服务器内部错误
|
||||
schema:
|
||||
additionalProperties: true
|
||||
type: object
|
||||
summary: 发送短信验证码
|
||||
tags:
|
||||
- 用户认证
|
||||
securityDefinitions:
|
||||
Bearer:
|
||||
description: Type "Bearer" followed by a space and JWT token.
|
||||
in: header
|
||||
name: Authorization
|
||||
type: apiKey
|
||||
swagger: "2.0"
|
||||
@@ -221,17 +221,18 @@ iostat 1 5
|
||||
|
||||
## 开发环境问题
|
||||
|
||||
### 1. 热重载不工作
|
||||
### 1. 开发服务器问题
|
||||
|
||||
```bash
|
||||
# 检查文件监控
|
||||
ls -la .air.toml
|
||||
# 停止当前开发服务器
|
||||
Ctrl+C
|
||||
|
||||
# 重启开发服务器
|
||||
make dev-restart
|
||||
# 重新启动开发服务器
|
||||
make dev
|
||||
|
||||
# 检查文件权限
|
||||
chmod +x scripts/dev.sh
|
||||
# 检查Go模块状态
|
||||
go mod tidy
|
||||
go mod download
|
||||
```
|
||||
|
||||
### 2. 测试失败
|
||||
145
docs/开始指南/文档索引.md
Normal file
145
docs/开始指南/文档索引.md
Normal file
@@ -0,0 +1,145 @@
|
||||
# 📚 TYAPI Server 文档中心
|
||||
|
||||
欢迎使用 TYAPI Server 文档中心!我们已将原本的使用指南拆分为多个专题文档,方便您按需查阅。
|
||||
|
||||
## 📋 文档导航
|
||||
|
||||
### 🚀 [快速开始指南](./快速开始指南.md)
|
||||
|
||||
- 前置要求
|
||||
- 一键启动
|
||||
- 验证安装
|
||||
- 访问管理界面
|
||||
|
||||
### 🔧 [环境搭建指南](./环境搭建指南.md)
|
||||
|
||||
- 开发环境配置
|
||||
- 生产环境配置
|
||||
- 服务配置说明
|
||||
- 常见配置问题
|
||||
|
||||
### 📋 [Makefile 命令指南](./MAKEFILE_GUIDE.md)
|
||||
|
||||
- 所有 Make 命令详细说明
|
||||
- 常用工作流程
|
||||
- 构建和部署命令
|
||||
- 开发工具命令
|
||||
- 故障排除技巧
|
||||
|
||||
### 👨💻 [开发指南](./开发指南.md)
|
||||
|
||||
- 项目结构理解
|
||||
- 开发流程
|
||||
- 测试编写
|
||||
- 调试技巧
|
||||
- 代码规范
|
||||
|
||||
### 🌐 [API 使用指南](./API使用指南.md)
|
||||
|
||||
- 认证机制
|
||||
- 用户管理 API
|
||||
- 响应格式
|
||||
- HTTP 状态码
|
||||
- API 测试
|
||||
|
||||
### 🚀 [部署指南](./部署指南.md)
|
||||
|
||||
- Docker 部署
|
||||
- Kubernetes 部署
|
||||
- 云平台部署
|
||||
- 负载均衡配置
|
||||
- 监控部署
|
||||
|
||||
### 📦 [生产环境部署指南](./生产环境部署指南.md)
|
||||
|
||||
- Docker + 私有 Registry 完整部署方案
|
||||
- 多阶段构建生产级镜像
|
||||
- 安全配置和资源限制
|
||||
- 自动化部署脚本
|
||||
- 监控和故障排除
|
||||
|
||||
### 🔍 [故障排除指南](./故障排除指南.md)
|
||||
|
||||
- 常见问题
|
||||
- 日志分析
|
||||
- 性能问题
|
||||
- 紧急响应流程
|
||||
|
||||
### 📋 [最佳实践指南](./最佳实践指南.md)
|
||||
|
||||
- 开发最佳实践
|
||||
- 安全最佳实践
|
||||
- 性能最佳实践
|
||||
- 运维最佳实践
|
||||
- 团队协作
|
||||
|
||||
### 🔍 [链路追踪指南](./链路追踪指南.md)
|
||||
|
||||
- Jaeger 配置和使用
|
||||
- OpenTelemetry 集成
|
||||
- Grafana 可视化
|
||||
- 性能监控和优化
|
||||
- 故障排查技巧
|
||||
|
||||
## 🎯 快速索引
|
||||
|
||||
### 新手入门
|
||||
|
||||
1. [快速开始指南](./快速开始指南.md) - 5 分钟快速体验
|
||||
2. [环境搭建指南](./环境搭建指南.md) - 配置开发环境
|
||||
3. [Makefile 命令指南](./MAKEFILE_GUIDE.md) - 掌握所有开发命令
|
||||
4. [开发指南](./开发指南.md) - 开始第一个功能
|
||||
|
||||
### 日常开发
|
||||
|
||||
- [Makefile 命令指南](./MAKEFILE_GUIDE.md) - 构建、测试、部署命令
|
||||
- [API 使用指南](./API使用指南.md) - API 调用参考
|
||||
- [开发指南](./开发指南.md) - 开发流程和规范
|
||||
- [链路追踪指南](./链路追踪指南.md) - 性能监控和问题排查
|
||||
- [故障排除指南](./故障排除指南.md) - 解决常见问题
|
||||
|
||||
### 生产部署
|
||||
|
||||
- [部署指南](./部署指南.md) - 生产环境部署
|
||||
- [生产环境部署指南](./生产环境部署指南.md) - Docker + 私有 Registry 完整方案
|
||||
- [最佳实践指南](./最佳实践指南.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)
|
||||
- **链路追踪**: http://localhost:16686 (Jaeger)
|
||||
|
||||
### 社区支持
|
||||
|
||||
- **GitHub Issues**: 提交问题和建议
|
||||
- **Wiki**: 查看详细技术文档
|
||||
- **讨论区**: 参与技术讨论
|
||||
|
||||
## 🔄 文档更新
|
||||
|
||||
本文档会持续更新,如果您发现任何问题或有改进建议,请:
|
||||
|
||||
1. 提交 GitHub Issue
|
||||
2. 发起 Pull Request
|
||||
3. 联系维护团队
|
||||
|
||||
---
|
||||
|
||||
**提示**:建议将此页面加入书签,方便随时查阅相关文档。
|
||||
338
docs/开始指南/生产环境部署指南.md
Normal file
338
docs/开始指南/生产环境部署指南.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# TYAPI 生产环境部署指南
|
||||
|
||||
## 🎯 **部署架构概览**
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 生产环境架构 │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Nginx (80/443) ──► TYAPI App (8080) ──► PostgreSQL (5432) │
|
||||
│ │ │ │ │
|
||||
│ │ └──► Redis (6379) │ │
|
||||
│ │ └──► Jaeger (4317) │ │
|
||||
│ └──► Jaeger UI (16686) │ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
|
||||
私有镜像仓库: docker-registry.tianyuanapi.com
|
||||
```
|
||||
|
||||
## 📋 **部署清单**
|
||||
|
||||
### ✅ **已创建的文件**
|
||||
|
||||
- `Dockerfile` - 多阶段构建的生产级镜像
|
||||
- `docker-compose.prod.yml` - 生产环境服务编排
|
||||
- `.dockerignore` - Docker 构建忽略文件
|
||||
- `deployments/docker/nginx.conf` - Nginx 反向代理配置
|
||||
- `.env.production` - 生产环境配置模板
|
||||
- `scripts/deploy.sh` - Linux/macOS 部署脚本
|
||||
- `scripts/deploy.ps1` - Windows PowerShell 部署脚本
|
||||
- `Makefile` - 新增生产环境相关命令
|
||||
|
||||
### 🛠 **服务组件**
|
||||
|
||||
1. **PostgreSQL** - 主数据库 (生产优化配置)
|
||||
2. **Redis** - 缓存和会话存储 (密码保护)
|
||||
3. **TYAPI App** - 主应用程序 (生产模式)
|
||||
4. **Jaeger** - 链路追踪 (生产级配置)
|
||||
5. **Nginx** - 反向代理和负载均衡
|
||||
6. **Prometheus** - 监控数据收集和存储
|
||||
7. **Grafana** - 监控数据可视化仪表盘
|
||||
8. **MinIO** - S3 兼容对象存储服务
|
||||
9. **pgAdmin** - PostgreSQL 数据库管理工具
|
||||
|
||||
## 🚀 **快速部署步骤**
|
||||
|
||||
### 1️⃣ **环境准备**
|
||||
|
||||
```bash
|
||||
# 确保服务器已安装
|
||||
- Docker 20.10+
|
||||
- Docker Compose 2.0+
|
||||
- Git (可选)
|
||||
|
||||
# 检查版本
|
||||
docker --version
|
||||
docker-compose --version
|
||||
```
|
||||
|
||||
### 2️⃣ **获取代码**
|
||||
|
||||
```bash
|
||||
# 克隆项目到服务器
|
||||
git clone <your-repo-url> tyapi-server
|
||||
cd tyapi-server
|
||||
|
||||
# 或直接上传项目文件
|
||||
```
|
||||
|
||||
### 3️⃣ **配置环境变量**
|
||||
|
||||
```bash
|
||||
# 复制配置模板
|
||||
cp .env.production .env
|
||||
|
||||
# 编辑配置文件
|
||||
nano .env
|
||||
```
|
||||
|
||||
**必须修改的关键配置:**
|
||||
|
||||
```bash
|
||||
# 数据库配置
|
||||
DB_PASSWORD=your_secure_database_password_here
|
||||
|
||||
# Redis配置
|
||||
REDIS_PASSWORD=your_secure_redis_password_here
|
||||
|
||||
# JWT密钥 (至少32位)
|
||||
JWT_SECRET=your_super_secure_jwt_secret_key_for_production_at_least_32_chars
|
||||
|
||||
# Grafana管理员配置
|
||||
GRAFANA_ADMIN_PASSWORD=your_secure_grafana_password_here
|
||||
|
||||
# MinIO对象存储配置
|
||||
MINIO_ROOT_PASSWORD=your_secure_minio_password_here
|
||||
|
||||
# pgAdmin数据库管理配置
|
||||
PGADMIN_PASSWORD=your_secure_pgadmin_password_here
|
||||
|
||||
# 短信服务配置
|
||||
SMS_ACCESS_KEY_ID=your_sms_access_key_id
|
||||
SMS_ACCESS_KEY_SECRET=your_sms_access_key_secret
|
||||
SMS_SIGN_NAME=your_sms_sign_name
|
||||
SMS_TEMPLATE_CODE=your_sms_template_code
|
||||
```
|
||||
|
||||
### 4️⃣ **执行部署**
|
||||
|
||||
#### **Linux/macOS:**
|
||||
|
||||
```bash
|
||||
# 给脚本执行权限
|
||||
chmod +x scripts/deploy.sh
|
||||
|
||||
# 部署指定版本
|
||||
./scripts/deploy.sh v1.0.0
|
||||
|
||||
# 或部署最新版本
|
||||
./scripts/deploy.sh
|
||||
```
|
||||
|
||||
#### **Windows:**
|
||||
|
||||
```powershell
|
||||
# 执行部署脚本
|
||||
.\scripts\deploy.ps1 -Version "v1.0.0"
|
||||
|
||||
# 或使用Makefile
|
||||
make docker-build-prod
|
||||
make docker-push-prod
|
||||
make prod-up
|
||||
```
|
||||
|
||||
## 📊 **部署脚本功能**
|
||||
|
||||
### 🔄 **自动化流程**
|
||||
|
||||
1. **环境检查** - 验证 Docker、docker-compose 等工具
|
||||
2. **配置验证** - 检查关键配置项的安全性
|
||||
3. **镜像构建** - 构建生产级 Docker 镜像
|
||||
4. **镜像推送** - 推送到私有 Registry
|
||||
5. **服务部署** - 启动所有生产服务
|
||||
6. **健康检查** - 验证服务运行状态
|
||||
7. **信息展示** - 显示访问地址和管理命令
|
||||
|
||||
### 🛡 **安全特性**
|
||||
|
||||
- **非 root 用户运行** - 容器内使用专用用户
|
||||
- **资源限制** - CPU 和内存使用限制
|
||||
- **健康检查** - 自动重启异常服务
|
||||
- **网络隔离** - 独立的 Docker 网络
|
||||
- **密码保护** - 数据库和 Redis 强制密码
|
||||
- **SSL 就绪** - Nginx HTTPS 配置模板
|
||||
|
||||
## 🎛 **管理命令**
|
||||
|
||||
### **通过 Makefile 管理:**
|
||||
|
||||
```bash
|
||||
# 构建生产镜像
|
||||
make docker-build-prod
|
||||
|
||||
# 推送到Registry
|
||||
make docker-push-prod
|
||||
|
||||
# 启动生产服务
|
||||
make prod-up
|
||||
|
||||
# 停止生产服务
|
||||
make prod-down
|
||||
|
||||
# 查看服务状态
|
||||
make prod-status
|
||||
|
||||
# 查看实时日志
|
||||
make prod-logs
|
||||
```
|
||||
|
||||
### **通过 docker-compose 管理:**
|
||||
|
||||
```bash
|
||||
# 启动所有服务
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# 停止所有服务
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
|
||||
# 查看服务状态
|
||||
docker-compose -f docker-compose.prod.yml ps
|
||||
|
||||
# 查看日志
|
||||
docker-compose -f docker-compose.prod.yml logs -f
|
||||
|
||||
# 重启特定服务
|
||||
docker-compose -f docker-compose.prod.yml restart tyapi-app
|
||||
```
|
||||
|
||||
## 🌐 **服务访问地址**
|
||||
|
||||
部署成功后,可以通过以下地址访问服务:
|
||||
|
||||
### **核心服务**
|
||||
|
||||
- **API 服务**: `http://your-server:8080`
|
||||
- **API 文档**: `http://your-server:8080/swagger/index.html`
|
||||
- **健康检查**: `http://your-server:8080/health`
|
||||
|
||||
### **监控和追踪**
|
||||
|
||||
- **Grafana 仪表盘**: `http://your-server:3000`
|
||||
- **Prometheus 监控**: `http://your-server:9090`
|
||||
- **Jaeger 链路追踪**: `http://your-server:16686`
|
||||
|
||||
### **管理工具**
|
||||
|
||||
- **pgAdmin 数据库管理**: `http://your-server:5050`
|
||||
- **MinIO 对象存储**: `http://your-server:9000` (API)
|
||||
- **MinIO 控制台**: `http://your-server:9001` (管理界面)
|
||||
|
||||
### **通过 Nginx 代理访问**
|
||||
|
||||
如果启用了 Nginx,也可以通过以下路径访问:
|
||||
|
||||
- **根目录**: `http://your-server/` → 重定向到 API 文档
|
||||
- **API 服务**: `http://your-server/api/`
|
||||
- **Grafana**: `http://your-server/grafana/`
|
||||
- **Prometheus**: `http://your-server/prometheus/`
|
||||
- **Jaeger**: `http://your-server/jaeger/`
|
||||
- **MinIO API**: `http://your-server/minio/`
|
||||
- **MinIO 控制台**: `http://your-server/minio-console/`
|
||||
- **pgAdmin**: `http://your-server/pgadmin/`
|
||||
|
||||
## 🔍 **监控和故障排除**
|
||||
|
||||
### **查看日志:**
|
||||
|
||||
```bash
|
||||
# 查看应用日志
|
||||
docker-compose -f docker-compose.prod.yml logs tyapi-app
|
||||
|
||||
# 查看数据库日志
|
||||
docker-compose -f docker-compose.prod.yml logs postgres
|
||||
|
||||
# 查看所有服务日志
|
||||
docker-compose -f docker-compose.prod.yml logs
|
||||
```
|
||||
|
||||
### **健康检查:**
|
||||
|
||||
```bash
|
||||
# 检查服务状态
|
||||
curl -f http://localhost:8080/health
|
||||
|
||||
# 检查Jaeger
|
||||
curl -f http://localhost:16686
|
||||
|
||||
# 查看容器状态
|
||||
docker ps
|
||||
```
|
||||
|
||||
### **常见问题:**
|
||||
|
||||
1. **镜像拉取失败**
|
||||
|
||||
```bash
|
||||
# 检查Registry连接
|
||||
docker pull docker-registry.tianyuanapi.com/tyapi-server:latest
|
||||
```
|
||||
|
||||
2. **数据库连接失败**
|
||||
|
||||
```bash
|
||||
# 检查数据库配置
|
||||
docker-compose -f docker-compose.prod.yml logs postgres
|
||||
```
|
||||
|
||||
3. **应用启动失败**
|
||||
```bash
|
||||
# 查看应用日志
|
||||
docker-compose -f docker-compose.prod.yml logs tyapi-app
|
||||
```
|
||||
|
||||
## 🔧 **配置优化**
|
||||
|
||||
### **性能调优:**
|
||||
|
||||
1. **数据库优化** - 根据服务器配置调整 PostgreSQL 参数
|
||||
2. **Redis 优化** - 配置内存和持久化策略
|
||||
3. **应用调优** - 调整连接池大小和超时时间
|
||||
4. **Nginx 优化** - 配置缓存和压缩
|
||||
|
||||
### **扩展配置:**
|
||||
|
||||
1. **HTTPS 配置** - 添加 SSL 证书支持
|
||||
2. **域名配置** - 绑定自定义域名
|
||||
3. **备份策略** - 配置数据库自动备份
|
||||
4. **日志收集** - 集成 ELK 或其他日志系统
|
||||
|
||||
## 🔄 **版本更新**
|
||||
|
||||
### **零停机更新:**
|
||||
|
||||
```bash
|
||||
# 构建新版本
|
||||
./scripts/deploy.sh v1.1.0
|
||||
|
||||
# 或渐进式更新
|
||||
docker-compose -f docker-compose.prod.yml pull tyapi-app
|
||||
docker-compose -f docker-compose.prod.yml up -d --no-deps tyapi-app
|
||||
```
|
||||
|
||||
### **回滚操作:**
|
||||
|
||||
```bash
|
||||
# 回滚到指定版本
|
||||
docker tag docker-registry.tianyuanapi.com/tyapi-server:v1.0.0 \
|
||||
docker-registry.tianyuanapi.com/tyapi-server:latest
|
||||
|
||||
docker-compose -f docker-compose.prod.yml up -d --no-deps tyapi-app
|
||||
```
|
||||
|
||||
## 📞 **技术支持**
|
||||
|
||||
如果在部署过程中遇到问题,请:
|
||||
|
||||
1. 检查本文档的故障排除部分
|
||||
2. 查看服务日志定位问题
|
||||
3. 确认配置文件的正确性
|
||||
4. 验证网络和防火墙设置
|
||||
|
||||
---
|
||||
|
||||
**部署前请务必:**
|
||||
|
||||
- ✅ 测试配置文件
|
||||
- ✅ 备份现有数据
|
||||
- ✅ 验证 Registry 访问
|
||||
- ✅ 确认服务器资源充足
|
||||
338
docs/开始指南/链路追踪指南.md
Normal file
338
docs/开始指南/链路追踪指南.md
Normal file
@@ -0,0 +1,338 @@
|
||||
# TYAPI 项目链路追踪指南
|
||||
|
||||
## 概述
|
||||
|
||||
本项目使用 **Jaeger** 进行分布式链路追踪,通过 **OpenTelemetry** 标准实现数据收集,并在 **Grafana** 中进行可视化展示。
|
||||
|
||||
## 架构说明
|
||||
|
||||
```
|
||||
应用程序 -> OpenTelemetry -> Jaeger -> Grafana 可视化
|
||||
```
|
||||
|
||||
- **应用程序**:使用 OpenTelemetry Go SDK 生成链路追踪数据
|
||||
- **Jaeger**:收集、存储和查询链路追踪数据
|
||||
- **Grafana**:提供链路追踪数据的可视化界面
|
||||
|
||||
## 快速启动
|
||||
|
||||
### 1. 启动基础设施服务
|
||||
|
||||
```bash
|
||||
# 启动所有服务(包括Jaeger)
|
||||
docker-compose -f docker-compose.dev.yml up -d
|
||||
|
||||
# 检查服务状态
|
||||
docker-compose -f docker-compose.dev.yml ps
|
||||
```
|
||||
|
||||
### 2. 验证服务启动
|
||||
|
||||
- **Jaeger UI**: http://localhost:16686
|
||||
- **Grafana**: http://localhost:3000 (admin/Gf7nB3xM9cV6pQ2w)
|
||||
- **应用程序**: http://localhost:8080
|
||||
|
||||
### 3. 启动应用程序
|
||||
|
||||
```bash
|
||||
# 确保配置正确
|
||||
make run
|
||||
```
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 应用配置(config.yaml)
|
||||
|
||||
```yaml
|
||||
monitoring:
|
||||
metrics_enabled: true
|
||||
metrics_port: "9090"
|
||||
tracing_enabled: true # 启用链路追踪
|
||||
tracing_endpoint: "http://localhost:4317" # OTLP gRPC 端点
|
||||
sample_rate: 0.1 # 采样率:10%
|
||||
```
|
||||
|
||||
### Jaeger 配置
|
||||
|
||||
- **UI 端口**: 16686
|
||||
- **OTLP gRPC**: 4317
|
||||
- **OTLP HTTP**: 4318
|
||||
- **传统 gRPC**: 14250
|
||||
- **传统 HTTP**: 14268
|
||||
|
||||
### 采样策略
|
||||
|
||||
项目使用智能采样策略(配置在 `deployments/docker/jaeger-sampling.json`):
|
||||
|
||||
- **默认采样率**: 10%
|
||||
- **健康检查接口**: 1%(减少噪音)
|
||||
- **关键业务接口**: 50%(如注册、登录)
|
||||
- **错误请求**: 100%(所有 4xx 和 5xx 错误)
|
||||
|
||||
#### 错误优先采样
|
||||
|
||||
系统实现了错误优先采样策略,确保所有出现错误的请求都被 100%采样记录,即使它们不在高采样率的关键业务接口中。这包括:
|
||||
|
||||
- 所有返回 4xx 状态码的客户端错误(如 404、400、403 等)
|
||||
- 所有返回 5xx 状态码的服务器错误(如 500、503 等)
|
||||
- 所有抛出异常的数据库操作
|
||||
- 所有失败的缓存操作
|
||||
- 所有失败的外部 API 调用
|
||||
|
||||
这种策略确保了在出现问题时,相关的链路追踪数据始终可用,便于问题排查和根因分析。
|
||||
|
||||
## 使用指南
|
||||
|
||||
### 在 Grafana 中查看链路追踪
|
||||
|
||||
1. **访问 Grafana**: http://localhost:3000
|
||||
2. **登录**: admin / Gf7nB3xM9cV6pQ2w
|
||||
3. **导航**: Dashboard → TYAPI 链路追踪监控
|
||||
4. **数据源**:
|
||||
- Jaeger 数据源已自动配置
|
||||
- URL: http://jaeger:16686
|
||||
|
||||
### 在 Jaeger UI 中查看链路追踪
|
||||
|
||||
1. **访问 Jaeger**: http://localhost:16686
|
||||
2. **选择服务**: TYAPI Server
|
||||
3. **查询追踪**:
|
||||
- 按时间范围筛选
|
||||
- 按操作类型筛选
|
||||
- 按标签筛选
|
||||
- 按错误状态筛选(使用标签`error=true`)
|
||||
|
||||
### 生成测试数据
|
||||
|
||||
```bash
|
||||
# 注册用户(会生成链路追踪数据)
|
||||
curl -X POST http://localhost:8080/api/v1/users/send-sms \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"phone": "13800138000"}'
|
||||
|
||||
# 用户注册
|
||||
curl -X POST http://localhost:8080/api/v1/users/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"phone": "13800138000",
|
||||
"password": "Test123456",
|
||||
"sms_code": "123456"
|
||||
}'
|
||||
|
||||
# 用户登录
|
||||
curl -X POST http://localhost:8080/api/v1/users/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"phone": "13800138000",
|
||||
"password": "Test123456"
|
||||
}'
|
||||
|
||||
# 生成错误请求(测试错误采样)
|
||||
curl -X GET http://localhost:8080/api/v1/not-exist-path
|
||||
```
|
||||
|
||||
## 链路追踪功能特性
|
||||
|
||||
### 自动追踪的操作
|
||||
|
||||
1. **HTTP 请求**: 所有入站 HTTP 请求
|
||||
2. **数据库查询**: GORM 操作
|
||||
3. **缓存操作**: Redis 读写
|
||||
4. **外部调用**: 短信服务等
|
||||
5. **业务逻辑**: 用户注册、登录等
|
||||
|
||||
### 追踪数据包含的信息
|
||||
|
||||
- **请求信息**: URL、HTTP 方法、状态码
|
||||
- **时间信息**: 开始时间、持续时间
|
||||
- **错误信息**: 异常堆栈和错误消息
|
||||
- **上下文信息**: TraceID、SpanID
|
||||
- **自定义标签**: 服务名、操作类型等
|
||||
|
||||
### TraceID 传播
|
||||
|
||||
应用程序会在 HTTP 响应头中返回 TraceID:
|
||||
|
||||
```
|
||||
X-Trace-ID: 4bf92f3577b34da6a3ce929d0e0e4736
|
||||
```
|
||||
|
||||
通过这个 ID,可以在日志系统和 Jaeger UI 中关联同一请求的所有信息。
|
||||
|
||||
## 错误追踪与分析
|
||||
|
||||
### 错误链路的查询
|
||||
|
||||
在 Jaeger UI 中,可以通过以下方式查询错误链路:
|
||||
|
||||
1. 在查询界面选择"Tags"标签
|
||||
2. 添加条件:`error=true`或`operation.type=error`
|
||||
3. 点击"Find Traces"按钮
|
||||
|
||||
这将显示所有被标记为错误的链路追踪数据,包括:
|
||||
|
||||
- 所有 HTTP 4xx/5xx 错误
|
||||
- 所有数据库操作错误
|
||||
- 所有缓存操作错误
|
||||
- 所有外部 API 调用错误
|
||||
|
||||
### 错误根因分析
|
||||
|
||||
链路追踪系统记录了错误发生的完整上下文,包括:
|
||||
|
||||
- 错误发生的具体操作
|
||||
- 错误的详细信息和堆栈
|
||||
- 错误发生前的所有操作序列
|
||||
- 相关的请求参数和环境信息
|
||||
|
||||
通过这些信息,可以快速定位问题根源,而不需要在多个日志文件中搜索。
|
||||
|
||||
## 性能优化建议
|
||||
|
||||
### 采样率配置
|
||||
|
||||
- **开发环境**: 10-50%(便于调试)
|
||||
- **测试环境**: 5-10%
|
||||
- **生产环境**: 1-5%(减少性能影响)
|
||||
- **错误请求**: 始终保持 100%(所有环境)
|
||||
|
||||
### 批处理配置
|
||||
|
||||
生产环境建议使用批处理导出器:
|
||||
|
||||
```yaml
|
||||
monitoring:
|
||||
tracing_enabled: true
|
||||
tracing_endpoint: "http://jaeger:4317"
|
||||
sample_rate: 0.01 # 生产环境1%采样率
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **链路追踪数据未显示**
|
||||
|
||||
- 检查应用配置中 `tracing_enabled: true`
|
||||
- 确认 Jaeger 服务正常运行
|
||||
- 检查网络连接和端口
|
||||
|
||||
2. **Grafana 无法连接 Jaeger**
|
||||
|
||||
- 确认 Jaeger 数据源配置正确
|
||||
- 检查容器网络连接
|
||||
- 验证 Jaeger UI 可访问
|
||||
|
||||
3. **性能影响过大**
|
||||
|
||||
- 降低采样率
|
||||
- 检查批处理配置
|
||||
- 监控内存和 CPU 使用率
|
||||
|
||||
4. **错误请求未被 100%采样**
|
||||
- 检查 Jaeger 采样配置中是否包含`"operation": "error"`的配置
|
||||
- 确认中间件正确设置了错误标记
|
||||
- 验证错误处理逻辑是否正确调用了`SetSpanError`方法
|
||||
|
||||
### 调试命令
|
||||
|
||||
```bash
|
||||
# 检查Jaeger健康状态
|
||||
curl http://localhost:14269/health
|
||||
|
||||
# 检查容器日志
|
||||
docker logs tyapi-jaeger
|
||||
|
||||
# 检查应用追踪配置
|
||||
curl http://localhost:8080/health
|
||||
```
|
||||
|
||||
## 监控仪表板
|
||||
|
||||
### 默认仪表板
|
||||
|
||||
项目提供了预配置的 Grafana 仪表板:
|
||||
|
||||
- **TYAPI 链路追踪监控**: 展示追踪概览和关键指标
|
||||
- **HTTP 请求分析**: 请求速率和延迟分布
|
||||
- **服务依赖图**: 服务间调用关系
|
||||
- **错误分析**: 错误率和错误类型分布
|
||||
|
||||
### 自定义仪表板
|
||||
|
||||
可以根据业务需求创建自定义仪表板:
|
||||
|
||||
1. 在 Grafana 中创建新仪表板
|
||||
2. 添加 Jaeger 查询面板
|
||||
3. 配置告警规则
|
||||
4. 导出仪表板配置
|
||||
|
||||
## 生产环境部署
|
||||
|
||||
### 环境变量配置
|
||||
|
||||
```bash
|
||||
export JAEGER_ENDPOINT="http://jaeger:4317"
|
||||
export TRACING_SAMPLE_RATE="0.01"
|
||||
```
|
||||
|
||||
### Kubernetes 部署
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: app-config
|
||||
data:
|
||||
config.yaml: |
|
||||
monitoring:
|
||||
tracing_enabled: true
|
||||
tracing_endpoint: "http://jaeger-collector:4317"
|
||||
sample_rate: 0.01
|
||||
```
|
||||
|
||||
## 扩展功能
|
||||
|
||||
### 自定义追踪
|
||||
|
||||
```go
|
||||
// 在业务代码中添加自定义追踪
|
||||
ctx, span := tracer.StartSpan(ctx, "custom-operation")
|
||||
defer span.End()
|
||||
|
||||
// 添加自定义属性
|
||||
tracer.AddSpanAttributes(span,
|
||||
attribute.String("user.id", userID),
|
||||
attribute.String("operation.type", "business"),
|
||||
)
|
||||
|
||||
// 记录错误
|
||||
if err != nil {
|
||||
tracer.SetSpanError(span, err)
|
||||
}
|
||||
```
|
||||
|
||||
### 业务指标集成
|
||||
|
||||
链路追踪数据可以与业务指标结合:
|
||||
|
||||
- 用户行为分析
|
||||
- 性能瓶颈定位
|
||||
- 错误率监控
|
||||
- 服务依赖分析
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **合理设置采样率**: 平衡数据完整性和性能影响
|
||||
2. **添加有意义的标签**: 便于后续查询和分析
|
||||
3. **处理敏感信息**: 避免在追踪数据中记录密码等敏感信息
|
||||
4. **监控存储空间**: 定期清理过期的追踪数据
|
||||
5. **设置告警规则**: 对异常追踪模式设置告警
|
||||
6. **错误优先采样**: 确保所有错误请求都被记录,无论采样率如何
|
||||
7. **关联日志系统**: 在日志中包含 TraceID,便于关联查询
|
||||
|
||||
## 参考资料
|
||||
|
||||
- [OpenTelemetry Go 文档](https://opentelemetry.io/docs/instrumentation/go/)
|
||||
- [Jaeger 官方文档](https://www.jaegertracing.io/docs/)
|
||||
- [Grafana Jaeger 数据源](https://grafana.com/docs/grafana/latest/datasources/jaeger/)
|
||||
102
docs/文档索引.md
102
docs/文档索引.md
@@ -1,102 +0,0 @@
|
||||
# 📚 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. 联系维护团队
|
||||
|
||||
---
|
||||
|
||||
**提示**:建议将此页面加入书签,方便随时查阅相关文档。
|
||||
Reference in New Issue
Block a user