545 lines
22 KiB
Markdown
545 lines
22 KiB
Markdown
|
|
# 故障排除
|
|||
|
|
|
|||
|
|
<cite>
|
|||
|
|
**本文引用的文件**
|
|||
|
|
- [cmd/server/main.go](file://cmd/server/main.go)
|
|||
|
|
- [internal/config/config.go](file://internal/config/config.go)
|
|||
|
|
- [internal/config/database.go](file://internal/config/database.go)
|
|||
|
|
- [internal/config/meilisearch.go](file://internal/config/meilisearch.go)
|
|||
|
|
- [internal/config/redis.go](file://internal/config/redis.go)
|
|||
|
|
- [internal/database/mysql.go](file://internal/database/mysql.go)
|
|||
|
|
- [internal/cache/redis.go](file://internal/cache/redis.go)
|
|||
|
|
- [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
|
|||
|
|
- [internal/router/router.go](file://internal/router/router.go)
|
|||
|
|
- [internal/middleware/logger.go](file://internal/middleware/logger.go)
|
|||
|
|
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
|
|||
|
|
- [internal/handler/health.go](file://internal/handler/health.go)
|
|||
|
|
- [internal/handler/model.go](file://internal/handler/model.go)
|
|||
|
|
- [internal/repository/model.go](file://internal/repository/model.go)
|
|||
|
|
- [internal/response/response.go](file://internal/response/response.go)
|
|||
|
|
- [go.mod](file://go.mod)
|
|||
|
|
- [README.md](file://README.md)
|
|||
|
|
</cite>
|
|||
|
|
|
|||
|
|
## 目录
|
|||
|
|
1. [简介](#简介)
|
|||
|
|
2. [项目结构](#项目结构)
|
|||
|
|
3. [核心组件](#核心组件)
|
|||
|
|
4. [架构总览](#架构总览)
|
|||
|
|
5. [详细组件分析](#详细组件分析)
|
|||
|
|
6. [依赖分析](#依赖分析)
|
|||
|
|
7. [性能考虑](#性能考虑)
|
|||
|
|
8. [故障排除指南](#故障排除指南)
|
|||
|
|
9. [结论](#结论)
|
|||
|
|
10. [附录](#附录)
|
|||
|
|
|
|||
|
|
## 简介
|
|||
|
|
本故障排除文档面向运维与开发人员,围绕 Luxsin 应用 API 的常见问题提供系统化的诊断与修复路径。重点覆盖以下方面:
|
|||
|
|
- 数据库连接问题:参数校验、连接池、超时与 Ping 校验
|
|||
|
|
- 缓存失效:Redis 连接、认证与可用性
|
|||
|
|
- 搜索异常:Meilisearch 连接、索引与查询
|
|||
|
|
- 日志分析:日志级别、字段与采样策略
|
|||
|
|
- 网络与配置:端口、主机、环境变量与路由
|
|||
|
|
- 权限与安全:生产环境敏感配置与最小暴露原则
|
|||
|
|
- 监控与告警:关键指标与告警流程
|
|||
|
|
- 应急响应:优雅停机、回滚策略与数据恢复指引
|
|||
|
|
|
|||
|
|
## 项目结构
|
|||
|
|
应用采用分层架构,入口在命令行模块,配置集中于内部配置包,服务通过中间件、路由、处理器、仓储与外部组件协作。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
graph TB
|
|||
|
|
subgraph "入口"
|
|||
|
|
MAIN["cmd/server/main.go<br/>启动与优雅停机"]
|
|||
|
|
end
|
|||
|
|
subgraph "配置"
|
|||
|
|
CFG["internal/config/config.go<br/>加载与导出地址"]
|
|||
|
|
DB_CFG["internal/config/database.go<br/>数据库配置与校验"]
|
|||
|
|
MS_CFG["internal/config/meilisearch.go<br/>搜索配置与校验"]
|
|||
|
|
RD_CFG["internal/config/redis.go<br/>缓存配置与校验"]
|
|||
|
|
end
|
|||
|
|
subgraph "基础设施"
|
|||
|
|
MYSQL["internal/database/mysql.go<br/>连接、Ping、连接池"]
|
|||
|
|
REDIS["internal/cache/redis.go<br/>客户端创建"]
|
|||
|
|
MEILI["internal/search/meilisearch.go<br/>搜索客户端与查询"]
|
|||
|
|
end
|
|||
|
|
subgraph "服务层"
|
|||
|
|
ROUTER["internal/router/router.go<br/>路由注册与中间件"]
|
|||
|
|
LOGMW["internal/middleware/logger.go<br/>请求日志中间件"]
|
|||
|
|
HEALTH["internal/handler/health.go<br/>健康检查"]
|
|||
|
|
MODEL_H["internal/handler/model.go<br/>模型查询处理器"]
|
|||
|
|
MODEL_R["internal/repository/model.go<br/>模型仓储"]
|
|||
|
|
RESP["internal/response/response.go<br/>统一响应体"]
|
|||
|
|
end
|
|||
|
|
MAIN --> CFG
|
|||
|
|
MAIN --> MYSQL
|
|||
|
|
MAIN --> REDIS
|
|||
|
|
MAIN --> MEILI
|
|||
|
|
MAIN --> ROUTER
|
|||
|
|
ROUTER --> LOGMW
|
|||
|
|
ROUTER --> HEALTH
|
|||
|
|
ROUTER --> MODEL_H
|
|||
|
|
MODEL_H --> MODEL_R
|
|||
|
|
MODEL_H --> RESP
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
|
|||
|
|
- [internal/config/config.go:18-56](file://internal/config/config.go#L18-L56)
|
|||
|
|
- [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72)
|
|||
|
|
- [internal/config/meilisearch.go:14-51](file://internal/config/meilisearch.go#L14-L51)
|
|||
|
|
- [internal/config/redis.go:16-57](file://internal/config/redis.go#L16-L57)
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [internal/search/meilisearch.go:17-46](file://internal/search/meilisearch.go#L17-L46)
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- [internal/handler/health.go:14-19](file://internal/handler/health.go#L14-L19)
|
|||
|
|
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
|
|||
|
|
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
|||
|
|
- [internal/response/response.go:15-37](file://internal/response/response.go#L15-L37)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [README.md:5-17](file://README.md#L5-L17)
|
|||
|
|
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
|
|||
|
|
## 核心组件
|
|||
|
|
- 启动与生命周期:读取配置、初始化日志、建立数据库/搜索/缓存连接、启动 HTTP 服务器、信号监听与优雅停机
|
|||
|
|
- 配置加载:支持从环境变量覆盖默认配置,并进行必要校验
|
|||
|
|
- 中间件:日志、CORS、Request ID、恢复
|
|||
|
|
- 路由与处理器:健康检查、品牌/模型查询、设备上报、模型列表搜索
|
|||
|
|
- 统一响应:标准化返回码与消息
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
|
|||
|
|
- [internal/config/config.go:18-56](file://internal/config/config.go#L18-L56)
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/response/response.go:15-37](file://internal/response/response.go#L15-L37)
|
|||
|
|
|
|||
|
|
## 架构总览
|
|||
|
|
应用通过 Gin 路由组织 API,中间件负责日志与跨域等横切关注点,处理器调用仓储访问数据库或调用搜索/缓存客户端。日志采用 Zap,按环境输出不同编码与时间格式。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Client as "客户端"
|
|||
|
|
participant Router as "Gin 路由"
|
|||
|
|
participant MW as "日志中间件"
|
|||
|
|
participant Handler as "处理器"
|
|||
|
|
participant Repo as "仓储"
|
|||
|
|
participant DB as "MySQL"
|
|||
|
|
participant Log as "Zap 日志"
|
|||
|
|
Client->>Router : "HTTP 请求"
|
|||
|
|
Router->>MW : "进入中间件链"
|
|||
|
|
MW->>Log : "记录请求开始"
|
|||
|
|
Router->>Handler : "匹配到处理器"
|
|||
|
|
Handler->>Repo : "执行查询"
|
|||
|
|
Repo->>DB : "执行 SQL"
|
|||
|
|
DB-->>Repo : "结果集"
|
|||
|
|
Repo-->>Handler : "领域对象列表"
|
|||
|
|
Handler-->>Client : "统一响应"
|
|||
|
|
MW->>Log : "记录状态/耗时/错误"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
|
|||
|
|
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
|||
|
|
|
|||
|
|
## 详细组件分析
|
|||
|
|
|
|||
|
|
### 数据库连接(MySQL)
|
|||
|
|
- 连接参数:用户、密码、主机、端口、数据库名、字符集与时区参数
|
|||
|
|
- 连接池:最大并发、空闲连接数、连接最大存活时间
|
|||
|
|
- Ping 校验:启动阶段 5 秒超时验证连通性
|
|||
|
|
- 错误处理:失败时关闭连接并返回带包装的错误
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
flowchart TD
|
|||
|
|
Start(["启动"]) --> BuildDSN["构建 DSN 参数"]
|
|||
|
|
BuildDSN --> Open["打开连接 sql.Open"]
|
|||
|
|
Open --> SetPool["设置连接池参数"]
|
|||
|
|
SetPool --> PingCtx["5 秒超时 PingContext"]
|
|||
|
|
PingCtx --> PingOK{"Ping 成功?"}
|
|||
|
|
PingOK --> |否| Close["关闭连接并报错"]
|
|||
|
|
PingOK --> |是| Ready["数据库就绪"]
|
|||
|
|
Close --> End(["结束"])
|
|||
|
|
Ready --> End
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72)
|
|||
|
|
|
|||
|
|
### 缓存(Redis)
|
|||
|
|
- 客户端创建:根据配置 Addr、Password、DB 初始化
|
|||
|
|
- 连接验证:通过 PingContext 在启动阶段进行
|
|||
|
|
- 关闭:服务优雅停机时关闭连接
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Main as "main.go"
|
|||
|
|
participant Cfg as "Redis 配置"
|
|||
|
|
participant Redis as "Redis 客户端"
|
|||
|
|
participant Log as "Zap 日志"
|
|||
|
|
Main->>Cfg : "读取 Redis 配置"
|
|||
|
|
Main->>Redis : "NewClient(Addr, Password, DB)"
|
|||
|
|
Redis-->>Main : "返回客户端实例"
|
|||
|
|
Main->>Log : "记录连接成功"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [cmd/server/main.go:56-62](file://cmd/server/main.go#L56-L62)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [internal/config/redis.go:16-57](file://internal/config/redis.go#L16-L57)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [internal/config/redis.go:16-57](file://internal/config/redis.go#L16-L57)
|
|||
|
|
|
|||
|
|
### 搜索(Meilisearch)
|
|||
|
|
- 客户端:基于 Host 与 API Key 创建索引管理器
|
|||
|
|
- 查询:限制返回条数、指定检索字段
|
|||
|
|
- 解码:将命中结果解码为映射列表
|
|||
|
|
- 错误:对查询与解码过程进行包装并返回
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant Handler as "处理器"
|
|||
|
|
participant Search as "Meilisearch 客户端"
|
|||
|
|
participant Index as "索引"
|
|||
|
|
participant Resp as "搜索响应"
|
|||
|
|
Handler->>Search : "ModelList(key, count)"
|
|||
|
|
Search->>Index : "SearchWithContext(req)"
|
|||
|
|
Index-->>Search : "响应"
|
|||
|
|
Search->>Search : "DecodeInto 映射列表"
|
|||
|
|
Search-->>Handler : "结果或错误"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [internal/search/meilisearch.go:22-46](file://internal/search/meilisearch.go#L22-L46)
|
|||
|
|
- [internal/config/meilisearch.go:14-51](file://internal/config/meilisearch.go#L14-L51)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/search/meilisearch.go:22-46](file://internal/search/meilisearch.go#L22-L46)
|
|||
|
|
- [internal/config/meilisearch.go:14-51](file://internal/config/meilisearch.go#L14-L51)
|
|||
|
|
|
|||
|
|
### 日志与中间件
|
|||
|
|
- 日志:生产环境使用生产配置,开发环境使用开发配置;时间键与编码可定制
|
|||
|
|
- 请求日志:记录状态码、方法、路径、延迟、客户端 IP、请求 ID、错误集合
|
|||
|
|
- 级别策略:>=500 记为错误,>=400 记为警告,否则为信息
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
flowchart TD
|
|||
|
|
Enter(["进入中间件"]) --> Start["记录开始时间与路径"]
|
|||
|
|
Start --> Next["调用下一个处理器"]
|
|||
|
|
Next --> Latency["计算耗时"]
|
|||
|
|
Latency --> Status["获取状态码"]
|
|||
|
|
Status --> Fields["组装日志字段"]
|
|||
|
|
Fields --> Level{"状态码级别"}
|
|||
|
|
Level --> |>=500| Error["记录错误日志"]
|
|||
|
|
Level --> |>=400| Warn["记录警告日志"]
|
|||
|
|
Level --> |<400| Info["记录信息日志"]
|
|||
|
|
Error --> Exit(["退出"])
|
|||
|
|
Warn --> Exit
|
|||
|
|
Info --> Exit
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
|||
|
|
|
|||
|
|
### 路由与处理器
|
|||
|
|
- 路由:健康检查、品牌、模型、模型列表、设备上报
|
|||
|
|
- 处理器:模型查询处理器调用仓储执行 SQL 查询
|
|||
|
|
- 统一响应:OK/Fail/BadRequest/InternalError
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
classDiagram
|
|||
|
|
class Router {
|
|||
|
|
+New(log, db, search, redis) Engine
|
|||
|
|
}
|
|||
|
|
class HealthHandler {
|
|||
|
|
+Check(c)
|
|||
|
|
}
|
|||
|
|
class ModelHandler {
|
|||
|
|
+GetModel(c)
|
|||
|
|
}
|
|||
|
|
class ModelRepository {
|
|||
|
|
+List(ctx, brandName, modelName) []Model
|
|||
|
|
}
|
|||
|
|
class Response {
|
|||
|
|
+OK(c, data)
|
|||
|
|
+Fail(c, httpStatus, code, message)
|
|||
|
|
+BadRequest(c, message)
|
|||
|
|
+InternalError(c, message)
|
|||
|
|
}
|
|||
|
|
Router --> HealthHandler : "注册"
|
|||
|
|
Router --> ModelHandler : "注册"
|
|||
|
|
ModelHandler --> ModelRepository : "调用"
|
|||
|
|
ModelHandler --> Response : "返回"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/handler/health.go:14-19](file://internal/handler/health.go#L14-L19)
|
|||
|
|
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
|
|||
|
|
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
|||
|
|
- [internal/response/response.go:15-37](file://internal/response/response.go#L15-L37)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
|
|||
|
|
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
|||
|
|
- [internal/response/response.go:15-37](file://internal/response/response.go#L15-L37)
|
|||
|
|
|
|||
|
|
## 依赖分析
|
|||
|
|
- 运行时依赖:Gin、MySQL 驱动、Meilisearch SDK、Redis SDK、Zap
|
|||
|
|
- 版本与间接依赖:go.mod 明确列出直接依赖及部分间接依赖
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
graph LR
|
|||
|
|
APP["app-api"] --> GIN["github.com/gin-gonic/gin"]
|
|||
|
|
APP --> MYSQL["github.com/go-sql-driver/mysql"]
|
|||
|
|
APP --> MEILI["github.com/meilisearch/meilisearch-go"]
|
|||
|
|
APP --> REDIS["github.com/redis/go-redis/v9"]
|
|||
|
|
APP --> ZAP["go.uber.org/zap"]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**图表来源**
|
|||
|
|
- [go.mod:5-11](file://go.mod#L5-L11)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [go.mod:5-11](file://go.mod#L5-L11)
|
|||
|
|
|
|||
|
|
## 性能考虑
|
|||
|
|
- 连接池:数据库设置最大并发、空闲连接与连接最大存活时间,有助于控制资源占用与抖动
|
|||
|
|
- 超时:启动阶段 PingContext 设置 5 秒超时,避免阻塞启动
|
|||
|
|
- 日志:生产环境使用生产配置,减少开销;仅在错误级别输出详细字段
|
|||
|
|
- 搜索:限制返回条数,避免过大数据传输
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/database/mysql.go:33-36](file://internal/database/mysql.go#L33-L36)
|
|||
|
|
- [internal/database/mysql.go:37-43](file://internal/database/mysql.go#L37-L43)
|
|||
|
|
- [pkg/logger/logger.go:10-17](file://pkg/logger/logger.go#L10-L17)
|
|||
|
|
- [internal/search/meilisearch.go:22-29](file://internal/search/meilisearch.go#L22-L29)
|
|||
|
|
|
|||
|
|
## 故障排除指南
|
|||
|
|
|
|||
|
|
### 一、数据库连接问题
|
|||
|
|
- 症状
|
|||
|
|
- 启动即报“database connect failed”
|
|||
|
|
- 健康检查正常但接口报错
|
|||
|
|
- 诊断步骤
|
|||
|
|
1) 检查环境变量是否正确:APP_ENV、DATABASE_HOST/PORT/NAME/USER/PASSWORD
|
|||
|
|
2) 校验配置加载:确认 loadDatabase 与 validate 是否通过
|
|||
|
|
3) 观察启动日志中数据库连接信息与 Ping 结果
|
|||
|
|
4) 使用数据库客户端验证凭据与网络连通性
|
|||
|
|
- 解决策略
|
|||
|
|
- 生产环境必须提供 DATABASE_PASSWORD
|
|||
|
|
- 如使用自定义配置,确保所有必填项非空
|
|||
|
|
- 调整连接池参数以适配负载
|
|||
|
|
- 相关实现
|
|||
|
|
- [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72)
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [cmd/server/main.go:38-48](file://cmd/server/main.go#L38-L48)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/config/database.go:17-72](file://internal/config/database.go#L17-L72)
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [cmd/server/main.go:38-48](file://cmd/server/main.go#L38-L48)
|
|||
|
|
|
|||
|
|
### 二、缓存失效(Redis)
|
|||
|
|
- 症状
|
|||
|
|
- 启动日志显示“redis connected”后立即报错
|
|||
|
|
- 接口出现缓存相关错误
|
|||
|
|
- 诊断步骤
|
|||
|
|
1) 检查 REDIS_HOST/PORT/PASSWORD/DATABASE 环境变量
|
|||
|
|
2) 校验 Redis 实例可达性与认证
|
|||
|
|
3) 查看启动日志中的连接信息
|
|||
|
|
- 解决策略
|
|||
|
|
- 确保 REDIS_HOST 非空并通过 validate
|
|||
|
|
- 如使用自定义配置,确保端口与数据库编号正确
|
|||
|
|
- 相关实现
|
|||
|
|
- [internal/config/redis.go:16-57](file://internal/config/redis.go#L16-L57)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [cmd/server/main.go:56-62](file://cmd/server/main.go#L56-L62)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/config/redis.go:16-57](file://internal/config/redis.go#L16-L57)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [cmd/server/main.go:56-62](file://cmd/server/main.go#L56-L62)
|
|||
|
|
|
|||
|
|
### 三、搜索异常(Meilisearch)
|
|||
|
|
- 症状
|
|||
|
|
- 搜索接口返回空结果或报错
|
|||
|
|
- 查询日志显示 decode 或 search 包装错误
|
|||
|
|
- 诊断步骤
|
|||
|
|
1) 检查 MEILISEARCH_HOST/API_KEY/INDEX 是否正确
|
|||
|
|
2) 校验索引是否存在且已同步
|
|||
|
|
3) 查看查询请求参数与返回字段映射
|
|||
|
|
- 解决策略
|
|||
|
|
- 确保 HOST/API_KEY/INDEX 均非空并通过 validate
|
|||
|
|
- 控制 Limit 并确认 AttributesToRetrieve 正确
|
|||
|
|
- 相关实现
|
|||
|
|
- [internal/config/meilisearch.go:14-51](file://internal/config/meilisearch.go#L14-L51)
|
|||
|
|
- [internal/search/meilisearch.go:22-46](file://internal/search/meilisearch.go#L22-L46)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/config/meilisearch.go:14-51](file://internal/config/meilisearch.go#L14-L51)
|
|||
|
|
- [internal/search/meilisearch.go:22-46](file://internal/search/meilisearch.go#L22-L46)
|
|||
|
|
|
|||
|
|
### 四、日志分析
|
|||
|
|
- 症状
|
|||
|
|
- 无法定位错误来源或耗时异常
|
|||
|
|
- 诊断步骤
|
|||
|
|
1) 区分日志级别:>=500 错误、>=400 警告、其他信息
|
|||
|
|
2) 关注字段:status、method、path、latency、ip、request_id、errors
|
|||
|
|
3) 生产环境使用 ISO8601 时间与无色编码,便于机器解析
|
|||
|
|
- 解决策略
|
|||
|
|
- 将关键错误与 request_id 关联到追踪链路
|
|||
|
|
- 对高频错误增加采样或降级
|
|||
|
|
- 相关实现
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
|||
|
|
|
|||
|
|
### 五、网络连接问题
|
|||
|
|
- 症状
|
|||
|
|
- 服务启动后无法访问或超时
|
|||
|
|
- 诊断步骤
|
|||
|
|
1) 检查 APP_HOST/APP_PORT 与防火墙策略
|
|||
|
|
2) 确认路由注册与路径正确
|
|||
|
|
3) 使用 curl 或浏览器访问 /api/v1/health 验证
|
|||
|
|
- 解决策略
|
|||
|
|
- 生产环境建议绑定内网地址并经反向代理对外暴露
|
|||
|
|
- 为健康检查与业务接口分别设置超时
|
|||
|
|
- 相关实现
|
|||
|
|
- [internal/config/config.go:54-56](file://internal/config/config.go#L54-L56)
|
|||
|
|
- [internal/router/router.go:27-38](file://internal/router/router.go#L27-L38)
|
|||
|
|
- [README.md:83-99](file://README.md#L83-L99)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/config/config.go:54-56](file://internal/config/config.go#L54-L56)
|
|||
|
|
- [internal/router/router.go:27-38](file://internal/router/router.go#L27-L38)
|
|||
|
|
- [README.md:83-99](file://README.md#L83-L99)
|
|||
|
|
|
|||
|
|
### 六、配置错误
|
|||
|
|
- 症状
|
|||
|
|
- 启动时报 invalid APP_PORT、database host is required 等
|
|||
|
|
- 诊断步骤
|
|||
|
|
1) 检查环境变量类型与默认值
|
|||
|
|
2) 确认 validate 返回的错误信息
|
|||
|
|
- 解决策略
|
|||
|
|
- 使用 .env 示例文件补齐缺失项
|
|||
|
|
- 生产环境敏感项不写入仓库
|
|||
|
|
- 相关实现
|
|||
|
|
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
|||
|
|
- [internal/config/database.go:57-71](file://internal/config/database.go#L57-L71)
|
|||
|
|
- [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50)
|
|||
|
|
- [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
|||
|
|
- [internal/config/database.go:57-71](file://internal/config/database.go#L57-L71)
|
|||
|
|
- [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50)
|
|||
|
|
- [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56)
|
|||
|
|
|
|||
|
|
### 七、权限问题
|
|||
|
|
- 症状
|
|||
|
|
- 数据库/搜索/缓存连接被拒绝
|
|||
|
|
- 诊断步骤
|
|||
|
|
1) 校验用户权限与白名单
|
|||
|
|
2) 确认 API Key 与密码正确
|
|||
|
|
3) 检查网络 ACL 与 VPC 策略
|
|||
|
|
- 解决策略
|
|||
|
|
- 最小权限原则分配账号
|
|||
|
|
- 生产环境使用只读账号用于查询
|
|||
|
|
- 相关实现
|
|||
|
|
- [internal/config/database.go:67-69](file://internal/config/database.go#L67-L69)
|
|||
|
|
- [internal/config/meilisearch.go:43-48](file://internal/config/meilisearch.go#L43-L48)
|
|||
|
|
- [internal/config/redis.go:52-55](file://internal/config/redis.go#L52-L55)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/config/database.go:67-69](file://internal/config/database.go#L67-L69)
|
|||
|
|
- [internal/config/meilisearch.go:43-48](file://internal/config/meilisearch.go#L43-L48)
|
|||
|
|
- [internal/config/redis.go:52-55](file://internal/config/redis.go#L52-L55)
|
|||
|
|
|
|||
|
|
### 八、系统监控指标与告警
|
|||
|
|
- 指标建议
|
|||
|
|
- QPS、P95/P99 延迟、错误率(4xx/5xx)、数据库连接池使用率、Redis 命中率、搜索查询耗时
|
|||
|
|
- 告警策略
|
|||
|
|
- 错误率超过阈值、延迟持续升高、连接池耗尽、搜索/缓存不可用
|
|||
|
|
- 日志采集
|
|||
|
|
- 生产环境使用结构化日志,结合 request_id 做关联分析
|
|||
|
|
|
|||
|
|
[本节为通用指导,无需特定文件引用]
|
|||
|
|
|
|||
|
|
### 九、应急响应与回滚
|
|||
|
|
- 优雅停机
|
|||
|
|
- 监听 SIGINT/SIGTERM,10 秒超时优雅关闭 HTTP 服务器
|
|||
|
|
- 回滚策略
|
|||
|
|
- 保留上一个版本二进制,变更配置文件即可快速回退
|
|||
|
|
- 数据恢复
|
|||
|
|
- 数据库:基于备份进行时间点恢复;搜索/缓存:重建索引或重载数据
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [cmd/server/main.go:81-94](file://cmd/server/main.go#L81-L94)
|
|||
|
|
|
|||
|
|
### 十、安全事件处理
|
|||
|
|
- 事件类型
|
|||
|
|
- 凭证泄露、未授权访问、DDoS、搜索/缓存被滥用
|
|||
|
|
- 处置流程
|
|||
|
|
- 立即冻结受影响账号与 API Key,变更密钥,审查日志,封禁来源 IP,升级防护策略
|
|||
|
|
- 预防措施
|
|||
|
|
- 强密码与多因子、最小权限、HTTPS、WAF、速率限制
|
|||
|
|
|
|||
|
|
[本节为通用指导,无需特定文件引用]
|
|||
|
|
|
|||
|
|
## 结论
|
|||
|
|
通过规范的配置校验、连接池与超时控制、结构化日志与中间件链路,以及明确的应急流程,可以有效降低故障发生概率并缩短恢复时间。建议在生产环境中严格执行最小暴露与最小权限原则,并建立完善的监控与告警体系。
|
|||
|
|
|
|||
|
|
## 附录
|
|||
|
|
|
|||
|
|
### A. 错误代码对照表(统一响应)
|
|||
|
|
- 200:操作成功(code=0)
|
|||
|
|
- 400:请求参数错误(code=40000)
|
|||
|
|
- 500:服务器内部错误(code=50000)
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/response/response.go:15-37](file://internal/response/response.go#L15-L37)
|
|||
|
|
|
|||
|
|
### B. 常见环境变量清单
|
|||
|
|
- 应用:APP_ENV、APP_HOST、APP_PORT、GIN_MODE
|
|||
|
|
- 数据库:DATABASE_HOST、DATABASE_PORT、DATABASE_NAME、DATABASE_USER、DATABASE_PASSWORD
|
|||
|
|
- 搜索:MEILISEARCH_HOST、MEILISEARCH_API_KEY、MEILISEARCH_INDEX
|
|||
|
|
- 缓存:REDIS_HOST、REDIS_PORT、REDIS_PASSWORD、REDIS_DATABASE
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
|||
|
|
- [internal/config/database.go:17-55](file://internal/config/database.go#L17-L55)
|
|||
|
|
- [internal/config/meilisearch.go:14-21](file://internal/config/meilisearch.go#L14-L21)
|
|||
|
|
- [internal/config/redis.go:16-49](file://internal/config/redis.go#L16-L49)
|
|||
|
|
|
|||
|
|
### C. 健康检查与基本验证
|
|||
|
|
- 健康检查:GET /api/v1/health
|
|||
|
|
- 响应:code=0,message="ok",data.status="up"
|
|||
|
|
|
|||
|
|
**章节来源**
|
|||
|
|
- [internal/router/router.go:27-30](file://internal/router/router.go#L27-L30)
|
|||
|
|
- [internal/handler/health.go:14-19](file://internal/handler/health.go#L14-L19)
|
|||
|
|
- [README.md:83-99](file://README.md#L83-L99)
|