新增功能
This commit is contained in:
@@ -0,0 +1,383 @@
|
||||
# 基础设施
|
||||
|
||||
<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/cache/redis.go](file://internal/cache/redis.go)
|
||||
- [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
|
||||
- [internal/database/mysql.go](file://internal/database/mysql.go)
|
||||
- [internal/router/router.go](file://internal/router/router.go)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go)
|
||||
- [internal/middleware/request_id.go](file://internal/middleware/request_id.go)
|
||||
- [internal/handler/model_list.go](file://internal/handler/model_list.go)
|
||||
- [internal/repository/model.go](file://internal/repository/model.go)
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
|
||||
- [README.md](file://README.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖分析](#依赖分析)
|
||||
7. [性能考量](#性能考量)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件聚焦于 Luxsin 应用 API 的基础设施组件,系统性阐述缓存系统(Redis)、搜索引擎(Meilisearch)与日志系统(Zap)的配置、初始化流程、连接管理、配置项与运行时行为,并结合实际代码路径说明组件间的协作关系与数据流向。同时提供性能优化建议、监控告警与扩展性设计思路、安全注意事项以及可操作的排障指引。
|
||||
|
||||
## 项目结构
|
||||
应用采用分层与按功能模块划分的组织方式:
|
||||
- 入口层:cmd/server/main.go 负责加载配置、初始化日志、数据库、搜索引擎与缓存客户端,并启动 HTTP 服务。
|
||||
- 配置层:internal/config/* 提供配置加载与校验逻辑,支持从环境变量或默认值读取数据库、Redis、Meilisearch 参数。
|
||||
- 基础设施接入:internal/database/mysql.go、internal/cache/redis.go、internal/search/meilisearch.go 封装底层驱动与 SDK 初始化。
|
||||
- Web 层:internal/router/router.go 注册路由与中间件;internal/middleware/* 提供请求 ID、日志与 CORS 中间件。
|
||||
- 业务处理:internal/handler/* 与 internal/repository/* 实现具体业务逻辑。
|
||||
- 日志封装:pkg/logger/logger.go 提供生产/开发两种日志配置。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
main["cmd/server/main.go<br/>应用入口"] --> cfg["internal/config/config.go<br/>配置加载"]
|
||||
main --> logpkg["pkg/logger/logger.go<br/>日志初始化"]
|
||||
main --> dbinit["internal/database/mysql.go<br/>数据库初始化"]
|
||||
main --> msinit["internal/search/meilisearch.go<br/>搜索引擎初始化"]
|
||||
main --> rdinit["internal/cache/redis.go<br/>缓存初始化"]
|
||||
main --> router["internal/router/router.go<br/>路由与中间件"]
|
||||
router --> handlers["internal/handler/*<br/>处理器"]
|
||||
handlers --> repos["internal/repository/*<br/>仓储层"]
|
||||
```
|
||||
|
||||
图示来源
|
||||
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||||
- [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
|
||||
## 核心组件
|
||||
本节概述三大基础设施组件的职责、初始化与配置要点。
|
||||
|
||||
- Redis 缓存
|
||||
- 职责:提供键值存储能力,用于热点数据缓存、会话或临时状态存储。
|
||||
- 初始化:在入口处依据配置创建客户端实例,随后在处理器中注入使用。
|
||||
- 关键配置:主机、端口、密码、数据库索引。
|
||||
- 连接管理:入口处创建客户端并在进程退出时关闭;未见显式的连接池参数设置。
|
||||
|
||||
- Meilisearch 搜索引擎
|
||||
- 职责:提供全文检索能力,当前用于模型列表的搜索与结果返回。
|
||||
- 初始化:在入口处创建客户端并绑定到指定索引;处理器调用其搜索方法。
|
||||
- 关键配置:主机地址、API 密钥、索引名。
|
||||
- 数据流:HTTP 请求 -> 处理器 -> 搜索客户端 -> 搜索引擎 -> 结果解码 -> 响应。
|
||||
|
||||
- 日志系统(Zap)
|
||||
- 职责:统一输出结构化日志,区分开发与生产环境的编码风格。
|
||||
- 初始化:入口处按环境创建日志实例;中间件在每次请求结束时输出请求级日志。
|
||||
- 关键配置:环境变量控制生产/开发模式,时间编码等细节可定制。
|
||||
|
||||
章节来源
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [internal/search/meilisearch.go:17-45](file://internal/search/meilisearch.go#L17-L45)
|
||||
- [internal/config/meilisearch.go:14-50](file://internal/config/meilisearch.go#L14-L50)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
|
||||
## 架构总览
|
||||
下图展示应用启动阶段如何初始化三大基础设施,并在运行期如何被业务层调用。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Entrypoint as "入口(main.go)"
|
||||
participant Cfg as "配置(config.go)"
|
||||
participant Log as "日志(pkg/logger)"
|
||||
participant DB as "数据库(mysql.go)"
|
||||
participant MS as "搜索引擎(meilisearch.go)"
|
||||
participant RD as "缓存(redis.go)"
|
||||
participant Router as "路由(router.go)"
|
||||
Entrypoint->>Cfg : 加载配置
|
||||
Entrypoint->>Log : 创建日志实例
|
||||
Entrypoint->>DB : 初始化数据库连接
|
||||
Entrypoint->>MS : 初始化搜索引擎客户端
|
||||
Entrypoint->>RD : 初始化缓存客户端
|
||||
Entrypoint->>Router : 注册路由与中间件
|
||||
Router-->>Entrypoint : 返回 HTTP 引擎
|
||||
```
|
||||
|
||||
图示来源
|
||||
- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64)
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||||
- [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### Redis 缓存组件
|
||||
- 初始化流程
|
||||
- 入口处依据配置创建 Redis 客户端实例,随后在处理器中注入使用。
|
||||
- 未见显式的连接池参数配置,如最大空闲/活动连接数、超时等。
|
||||
- 连接管理
|
||||
- 进程启动时建立连接;进程退出时关闭客户端。
|
||||
- 未见自动重连与健康检查逻辑。
|
||||
- 配置项
|
||||
- 主机、端口、密码、数据库索引。
|
||||
- 支持从环境变量覆盖默认值。
|
||||
- 使用场景
|
||||
- 当前路由中存在设备信息上报处理器,但未在现有代码中看到直接使用 Redis 的示例。建议在需要缓存的场景(如热门查询结果、限流令牌、会话状态)引入缓存策略。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["应用启动"]) --> LoadCfg["加载 Redis 配置"]
|
||||
LoadCfg --> NewClient["创建 Redis 客户端"]
|
||||
NewClient --> Inject["注入到处理器/服务"]
|
||||
Inject --> UseCase{"是否命中缓存?"}
|
||||
UseCase --> |是| ReturnCache["返回缓存数据"]
|
||||
UseCase --> |否| ExecOp["执行业务操作"]
|
||||
ExecOp --> StoreCache["写入缓存"]
|
||||
StoreCache --> ReturnResult["返回结果"]
|
||||
ReturnCache --> End(["完成"])
|
||||
ReturnResult --> End
|
||||
```
|
||||
|
||||
图示来源
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [cmd/server/main.go:56-57](file://cmd/server/main.go#L56-L57)
|
||||
|
||||
章节来源
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [cmd/server/main.go:56-57](file://cmd/server/main.go#L56-L57)
|
||||
|
||||
### Meilisearch 搜索组件
|
||||
- 初始化流程
|
||||
- 入口处依据配置创建客户端并绑定到指定索引。
|
||||
- 处理器调用搜索客户端的搜索方法,限制返回字段与数量。
|
||||
- 搜索优化
|
||||
- 仅检索必要字段,减少网络与序列化开销。
|
||||
- 通过查询参数控制返回条数,避免一次性返回过多数据。
|
||||
- 错误处理
|
||||
- 对搜索失败与结果解码失败进行包装与错误返回。
|
||||
- 数据流向
|
||||
- HTTP 请求 -> 处理器 -> 搜索客户端 -> 搜索引擎 -> 解码 -> 响应。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant Handler as "ModelListHandler"
|
||||
participant Search as "search.Client"
|
||||
participant Engine as "Meilisearch"
|
||||
Client->>Handler : GET /audio/modelList?key=&count=
|
||||
Handler->>Search : ModelList(ctx, key, count)
|
||||
Search->>Engine : Index.SearchWithContext(...)
|
||||
Engine-->>Search : Hits
|
||||
Search->>Search : DecodeInto(map)
|
||||
Search-->>Handler : 列表
|
||||
Handler-->>Client : JSON 或 Base64 响应
|
||||
```
|
||||
|
||||
图示来源
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
- [internal/config/meilisearch.go:14-50](file://internal/config/meilisearch.go#L14-L50)
|
||||
|
||||
章节来源
|
||||
- [internal/search/meilisearch.go:17-45](file://internal/search/meilisearch.go#L17-L45)
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
- [internal/config/meilisearch.go:14-50](file://internal/config/meilisearch.go#L14-L50)
|
||||
|
||||
### 日志系统(Zap)
|
||||
- 初始化
|
||||
- 根据环境变量选择生产或开发配置,时间编码与级别编码可定制。
|
||||
- 中间件日志
|
||||
- 记录状态码、方法、路径、耗时、客户端 IP、请求 ID、错误集合等。
|
||||
- 按状态码分级输出(错误、警告、信息)。
|
||||
- 请求 ID
|
||||
- 自动生成或透传请求 ID,便于跨服务链路追踪。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
ReqStart["请求进入"] --> GenRID["生成或透传请求ID"]
|
||||
GenRID --> Next["继续中间件链"]
|
||||
Next --> AfterReq["请求处理完成"]
|
||||
AfterReq --> Fields["组装日志字段"]
|
||||
Fields --> Level{"状态码分级"}
|
||||
Level --> |>=5xx| LogErr["记录错误日志"]
|
||||
Level --> |>=4xx| LogWarn["记录警告日志"]
|
||||
Level --> |<4xx| LogInfo["记录信息日志"]
|
||||
LogErr --> End["完成"]
|
||||
LogWarn --> End
|
||||
LogInfo --> End
|
||||
```
|
||||
|
||||
图示来源
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
|
||||
### 数据库(MySQL)与缓存/搜索的协作
|
||||
- 数据库连接
|
||||
- 初始化时设置最大打开连接数、最大空闲连接数与连接最大生命周期,并进行超时探测。
|
||||
- 仓储层
|
||||
- 仓储层负责 SQL 查询与结果扫描,为上层处理器提供稳定的数据访问接口。
|
||||
- 协作关系
|
||||
- 处理器在需要时从数据库读取数据,随后可将热点数据写入缓存;搜索用于全文检索场景。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Handler as "处理器"
|
||||
participant Repo as "仓储(ModelRepository)"
|
||||
participant DB as "MySQL(sql.DB)"
|
||||
participant RD as "Redis"
|
||||
participant MS as "Meilisearch"
|
||||
Handler->>Repo : 查询数据
|
||||
Repo->>DB : 执行 SQL
|
||||
DB-->>Repo : 结果集
|
||||
Repo-->>Handler : 结构化数据
|
||||
Handler->>RD : 写入/读取缓存可选
|
||||
Handler->>MS : 全文搜索可选
|
||||
```
|
||||
|
||||
图示来源
|
||||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||||
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
|
||||
章节来源
|
||||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||||
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
||||
|
||||
## 依赖分析
|
||||
- 组件耦合
|
||||
- 入口层集中初始化三大基础设施并向路由层注入。
|
||||
- 处理器通过依赖注入的方式使用数据库、搜索引擎与缓存客户端。
|
||||
- 外部依赖
|
||||
- Gin:Web 框架与路由。
|
||||
- go-sql-driver/mysql:MySQL 驱动。
|
||||
- redis/go-redis/v9:Redis 客户端。
|
||||
- meilisearch/meilisearch-go:Meilisearch 客户端。
|
||||
- zap:结构化日志。
|
||||
- 潜在循环依赖
|
||||
- 当前结构清晰,无明显循环导入。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
Entrypoint["入口(main.go)"] --> Gin["Gin 路由"]
|
||||
Entrypoint --> Zap["Zap 日志"]
|
||||
Entrypoint --> MySQL["MySQL 驱动"]
|
||||
Entrypoint --> Redis["Redis 客户端"]
|
||||
Entrypoint --> Meili["Meilisearch 客户端"]
|
||||
Gin --> Handlers["处理器"]
|
||||
Handlers --> Repos["仓储"]
|
||||
```
|
||||
|
||||
图示来源
|
||||
- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
|
||||
## 性能考量
|
||||
- Redis
|
||||
- 建议增加连接池参数配置(最大空闲/活动连接、超时),以提升高并发下的稳定性与吞吐。
|
||||
- 对热点键设置合理的过期策略,避免内存膨胀。
|
||||
- 使用 pipeline 或批量操作降低 RTT。
|
||||
- Meilisearch
|
||||
- 控制返回字段与数量,减少序列化与传输开销。
|
||||
- 对高频查询建立索引与排序规则,优化查询性能。
|
||||
- 合理设置分页与缓存策略,避免重复检索。
|
||||
- 日志
|
||||
- 生产环境建议异步落盘或使用缓冲队列,避免阻塞请求。
|
||||
- 控制日志字段数量,避免过度编码。
|
||||
- 数据库
|
||||
- 已设置连接池参数与生命周期,建议结合压测调整最大连接数与空闲连接数。
|
||||
- 对复杂查询添加索引,避免全表扫描。
|
||||
|
||||
## 故障排除指南
|
||||
- Redis
|
||||
- 症状:连接失败或超时。
|
||||
- 排查:确认主机、端口、密码与数据库索引配置正确;检查网络连通性与防火墙策略。
|
||||
- 建议:增加连接超时与重试机制。
|
||||
- Meilisearch
|
||||
- 症状:搜索报错或返回空结果。
|
||||
- 排查:确认主机、API 密钥与索引名配置;检查索引是否存在且已同步。
|
||||
- 建议:在处理器中增加重试与降级策略。
|
||||
- 日志
|
||||
- 症状:日志缺失或格式异常。
|
||||
- 排查:确认环境变量与日志配置;检查中间件是否正确挂载。
|
||||
- 数据库
|
||||
- 症状:连接超时或连接池耗尽。
|
||||
- 排查:核对连接参数与密码;检查最大连接数与空闲连接数设置;查看慢查询日志。
|
||||
|
||||
章节来源
|
||||
- [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56)
|
||||
- [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50)
|
||||
- [internal/database/mysql.go:33-35](file://internal/database/mysql.go#L33-L35)
|
||||
|
||||
## 结论
|
||||
本项目在基础设施层面实现了清晰的分层与职责分离:入口集中初始化、配置统一加载、日志结构化输出、数据库与搜索引擎按需接入。当前代码已具备可扩展的基础,建议在 Redis 与搜索层面补充连接池与缓存策略,在日志层面增强异步与采样能力,并完善监控与告警体系以支撑生产环境的稳定性与可观测性。
|
||||
|
||||
## 附录
|
||||
|
||||
### 配置清单与示例
|
||||
- 应用配置
|
||||
- 环境变量:APP_ENV、APP_HOST、APP_PORT。
|
||||
- 示例:参见项目自述文件中的环境变量表格与示例。
|
||||
- 数据库配置
|
||||
- 支持通过 DATABASE_HOST/PORT/NAME/USER/PASSWORD 覆盖默认值。
|
||||
- 生产环境必须提供 DATABASE_PASSWORD。
|
||||
- Redis 配置
|
||||
- 支持通过 REDIS_HOST/PORT/DATABASE/PASSWORD 覆盖默认值。
|
||||
- Meilisearch 配置
|
||||
- 支持通过 MEILISEARCH_HOST/API_KEY/INDEX 覆盖默认值。
|
||||
|
||||
章节来源
|
||||
- [README.md:39-73](file://README.md#L39-L73)
|
||||
- [internal/config/database.go:17-55](file://internal/config/database.go#L17-L55)
|
||||
- [internal/config/redis.go:16-48](file://internal/config/redis.go#L16-L48)
|
||||
- [internal/config/meilisearch.go:14-36](file://internal/config/meilisearch.go#L14-L36)
|
||||
|
||||
### 最佳实践
|
||||
- 安全
|
||||
- 生产环境敏感配置(数据库密码、搜索引擎密钥)务必通过环境变量注入。
|
||||
- Redis 与 Meilisearch 建议启用鉴权与网络隔离。
|
||||
- 可靠性
|
||||
- 为 Redis、数据库与搜索引擎增加健康检查与熔断策略。
|
||||
- 对外部依赖调用增加超时与重试。
|
||||
- 可观测性
|
||||
- 结合请求 ID 串联日志、指标与链路追踪。
|
||||
- 对关键路径埋点,关注延迟分布与错误率。
|
||||
|
||||
### 扩展性设计
|
||||
- 缓存层
|
||||
- 引入多级缓存(本地 LRU + 远端 Redis)与失效策略。
|
||||
- 对热点数据预热与定期刷新。
|
||||
- 搜索层
|
||||
- 建立索引更新流水线,保证数据一致性。
|
||||
- 引入搜索结果缓存与冷热数据分离。
|
||||
- 日志与监控
|
||||
- 增加指标采集(QPS、P95/P99、错误率)与告警阈值。
|
||||
- 使用分布式追踪定位慢调用。
|
||||
@@ -0,0 +1,355 @@
|
||||
# 搜索引擎
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
|
||||
- [internal/config/meilisearch.go](file://internal/config/meilisearch.go)
|
||||
- [internal/config/config.go](file://internal/config/config.go)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go)
|
||||
- [internal/router/router.go](file://internal/router/router.go)
|
||||
- [internal/handler/model_list.go](file://internal/handler/model_list.go)
|
||||
- [internal/handler/model.go](file://internal/handler/model.go)
|
||||
- [internal/repository/model.go](file://internal/repository/model.go)
|
||||
- [internal/model/model.go](file://internal/model/model.go)
|
||||
- [internal/database/mysql.go](file://internal/database/mysql.go)
|
||||
- [internal/cache/redis.go](file://internal/cache/redis.go)
|
||||
- [internal/response/response.go](file://internal/response/response.go)
|
||||
- [README.md](file://README.md)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排除指南](#故障排除指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向 Luxsin 应用 API 项目中的搜索引擎集成,系统性介绍 Meilisearch 的配置与初始化、搜索客户端的创建流程、索引管理策略、全文搜索实现原理以及搜索 API 的使用示例。同时提供性能优化建议、高亮显示、自动补全与相关性排序的扩展思路,以及连接问题诊断、索引重建与性能调优的故障排除指南。内容从基础概念到高级应用,兼顾不同层次开发者需求。
|
||||
|
||||
## 项目结构
|
||||
该项目采用分层架构,围绕 Gin HTTP 框架组织模块:
|
||||
- 配置层:集中加载运行环境、数据库、Meilisearch、Redis 等配置
|
||||
- 数据访问层:MySQL 数据库连接与模型扫描
|
||||
- 搜索层:Meilisearch 客户端与搜索请求封装
|
||||
- 处理层:HTTP 处理器与路由注册
|
||||
- 缓存层:Redis 客户端(用于查询缓存等)
|
||||
- 工具层:统一响应体、日志、编码工具
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用入口"
|
||||
MAIN["cmd/server/main.go"]
|
||||
end
|
||||
subgraph "配置层"
|
||||
CFG["internal/config/config.go"]
|
||||
MS_CFG["internal/config/meilisearch.go"]
|
||||
end
|
||||
subgraph "数据访问层"
|
||||
MYSQL["internal/database/mysql.go"]
|
||||
REPO["internal/repository/model.go"]
|
||||
MODEL["internal/model/model.go"]
|
||||
end
|
||||
subgraph "搜索层"
|
||||
SEARCH_CLIENT["internal/search/meilisearch.go"]
|
||||
end
|
||||
subgraph "处理层"
|
||||
ROUTER["internal/router/router.go"]
|
||||
HANDLER_MODEL["internal/handler/model.go"]
|
||||
HANDLER_MODEL_LIST["internal/handler/model_list.go"]
|
||||
end
|
||||
subgraph "缓存层"
|
||||
REDIS["internal/cache/redis.go"]
|
||||
end
|
||||
MAIN --> CFG
|
||||
CFG --> MS_CFG
|
||||
MAIN --> MYSQL
|
||||
MAIN --> SEARCH_CLIENT
|
||||
MAIN --> REDIS
|
||||
ROUTER --> HANDLER_MODEL
|
||||
ROUTER --> HANDLER_MODEL_LIST
|
||||
HANDLER_MODEL --> REPO
|
||||
SEARCH_CLIENT --> MS_CFG
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64)
|
||||
- [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51)
|
||||
- [internal/config/meilisearch.go:14-37](file://internal/config/meilisearch.go#L14-L37)
|
||||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||||
- [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
- [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24)
|
||||
- [internal/handler/model_list.go:19-24](file://internal/handler/model_list.go#L19-L24)
|
||||
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
||||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
|
||||
章节来源
|
||||
- [README.md:5-17](file://README.md#L5-L17)
|
||||
- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64)
|
||||
- [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51)
|
||||
|
||||
## 核心组件
|
||||
- 配置加载与验证:集中加载运行环境、数据库、Meilisearch、Redis 配置,并进行必填项校验
|
||||
- Meilisearch 客户端:封装搜索请求,限定返回字段,支持上下文取消
|
||||
- 路由与处理器:对外提供 /audio/modelList 搜索接口,支持分页数量控制与可选 Base64 响应
|
||||
- 数据访问层:提供按品牌名或型号名的 SQL 查询能力(当前未直接使用 Meilisearch)
|
||||
- 缓存层:Redis 客户端,可用于查询结果缓存
|
||||
|
||||
章节来源
|
||||
- [internal/config/meilisearch.go:8-12](file://internal/config/meilisearch.go#L8-L12)
|
||||
- [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50)
|
||||
- [internal/search/meilisearch.go:13-15](file://internal/search/meilisearch.go#L13-L15)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
|
||||
## 架构总览
|
||||
应用启动时加载配置,建立数据库与 Meilisearch 连接,注册路由并启动 HTTP 服务。搜索请求通过 /audio/modelList 路由进入处理器,处理器调用搜索客户端执行全文检索,最终以 JSON 或 Base64 编码形式返回。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant Router as "路由"
|
||||
participant Handler as "ModelListHandler"
|
||||
participant Search as "Meilisearch Client"
|
||||
participant Engine as "HTTP 引擎"
|
||||
Client->>Engine : "GET /audio/modelList?key=...&count=..."
|
||||
Engine->>Router : "匹配 /audio/modelList"
|
||||
Router->>Handler : "调用 ModelList()"
|
||||
Handler->>Handler : "解析查询参数<br/>解析 count 与 Base64 选项"
|
||||
Handler->>Search : "ModelList(ctx, key, count)"
|
||||
Search->>Search : "构造 SearchRequest<br/>限制返回字段"
|
||||
Search-->>Handler : "返回 hits 列表"
|
||||
Handler-->>Client : "JSON 或 Base64 响应"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38)
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 配置加载与验证
|
||||
- 配置结构包含运行环境、监听地址、端口、数据库、Meilisearch、Redis 等字段
|
||||
- 加载逻辑按环境选择默认值,支持通过环境变量覆盖
|
||||
- Meilisearch 配置包含 Host、APIKey、Index,均需校验非空
|
||||
- 启动日志记录已配置的 Meilisearch 主机与索引
|
||||
|
||||
章节来源
|
||||
- [internal/config/config.go:9-16](file://internal/config/config.go#L9-L16)
|
||||
- [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51)
|
||||
- [internal/config/meilisearch.go:8-12](file://internal/config/meilisearch.go#L8-L12)
|
||||
- [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50)
|
||||
- [cmd/server/main.go:50-54](file://cmd/server/main.go#L50-L54)
|
||||
|
||||
### Meilisearch 客户端
|
||||
- 客户端封装了 IndexManager,负责全文搜索
|
||||
- 初始化时传入 Host 与 APIKey,选择指定 Index
|
||||
- ModelList 方法接收 key 与 count,限制返回字段,解码为 map 并返回
|
||||
- 错误处理统一包装,便于上层捕获
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class Client {
|
||||
-index : "IndexManager"
|
||||
+NewClient(cfg) : "Client"
|
||||
+ModelList(ctx, key, count) : "[]map[string]any, error"
|
||||
}
|
||||
class MeilisearchConfig {
|
||||
+Host : "string"
|
||||
+APIKey : "string"
|
||||
+Index : "string"
|
||||
+validate() : "error"
|
||||
}
|
||||
Client --> MeilisearchConfig : "依赖"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/search/meilisearch.go:13-20](file://internal/search/meilisearch.go#L13-L20)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
- [internal/config/meilisearch.go:8-12](file://internal/config/meilisearch.go#L8-L12)
|
||||
- [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50)
|
||||
|
||||
章节来源
|
||||
- [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
|
||||
### 路由与处理器
|
||||
- 路由在 /audio 下注册 /modelList 接口
|
||||
- ModelListHandler 解析查询参数 key、count,并支持 Base64 响应
|
||||
- 调用搜索客户端执行搜索,错误时返回统一错误响应
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant C as "客户端"
|
||||
participant R as "路由"
|
||||
participant H as "ModelListHandler"
|
||||
participant S as "Meilisearch Client"
|
||||
C->>R : "GET /audio/modelList?key=...&count=..."
|
||||
R->>H : "ModelList()"
|
||||
H->>H : "解析 key/count/base64"
|
||||
H->>S : "ModelList(ctx, key, count)"
|
||||
S-->>H : "hits"
|
||||
H-->>C : "JSON 或 Base64"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38)
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
|
||||
章节来源
|
||||
- [internal/router/router.go:32-38](file://internal/router/router.go#L32-L38)
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
|
||||
### 数据访问层(SQL 查询)
|
||||
- ModelRepository 支持按品牌名精确匹配与按型号名模糊匹配
|
||||
- 默认不使用 Meilisearch,直接走数据库查询
|
||||
- 可作为搜索降级路径或补充场景
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["进入 List"]) --> Trim["去除前后空格"]
|
||||
Trim --> Switch{"条件分支"}
|
||||
Switch --> |brandName 非空| BrandQuery["按品牌名精确查询<br/>按名称升序"]
|
||||
Switch --> |modelName 非空| LikeQuery["按型号名模糊查询<br/>按名称升序"]
|
||||
Switch --> |否则| Empty["返回空数组"]
|
||||
BrandQuery --> Exec["执行查询"]
|
||||
LikeQuery --> Exec
|
||||
Exec --> Scan["逐行扫描并组装模型"]
|
||||
Scan --> End(["返回结果"])
|
||||
Empty --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
||||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||||
|
||||
章节来源
|
||||
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
||||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||||
|
||||
### 数据库连接与模型扫描
|
||||
- 使用 go-sql-driver/mysql 建立连接,设置字符集、时区与连接池参数
|
||||
- PingContext 超时检测连接可用性
|
||||
- 扫描函数将 NullString 转换为指针类型,避免空值污染
|
||||
|
||||
章节来源
|
||||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||||
- [internal/repository/model.go:63-86](file://internal/repository/model.go#L63-L86)
|
||||
|
||||
### 缓存层(Redis)
|
||||
- 提供 NewClient 工厂方法,按配置创建 Redis 客户端
|
||||
- 可用于搜索结果缓存、热门关键词缓存等
|
||||
|
||||
章节来源
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
|
||||
## 依赖关系分析
|
||||
- 入口 main 依赖配置加载、数据库、Meilisearch、Redis 与路由
|
||||
- 路由依赖处理器,处理器依赖搜索客户端与数据库
|
||||
- 搜索客户端依赖配置模块与 Meilisearch SDK
|
||||
- 数据库层依赖 MySQL 驱动与配置
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
MAIN["cmd/server/main.go"] --> CFG["internal/config/config.go"]
|
||||
MAIN --> MYSQL["internal/database/mysql.go"]
|
||||
MAIN --> SEARCH["internal/search/meilisearch.go"]
|
||||
MAIN --> REDIS["internal/cache/redis.go"]
|
||||
ROUTER["internal/router/router.go"] --> HANDLER1["internal/handler/model.go"]
|
||||
ROUTER --> HANDLER2["internal/handler/model_list.go"]
|
||||
HANDLER2 --> SEARCH
|
||||
HANDLER1 --> REPO["internal/repository/model.go"]
|
||||
REPO --> MODEL["internal/model/model.go"]
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:22-64](file://cmd/server/main.go#L22-L64)
|
||||
- [internal/config/config.go:18-51](file://internal/config/config.go#L18-L51)
|
||||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||||
- [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
- [internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24)
|
||||
- [internal/handler/model_list.go:19-24](file://internal/handler/model_list.go#L19-L24)
|
||||
- [internal/repository/model.go:20-61](file://internal/repository/model.go#L20-L61)
|
||||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||||
|
||||
## 性能考虑
|
||||
- 索引预处理
|
||||
- 在导入数据前,确保字段映射与排序规则已配置,减少运行时开销
|
||||
- 对高频查询字段(如品牌名、型号名)建立合适字段权重
|
||||
- 查询缓存
|
||||
- 使用 Redis 缓存热点搜索结果,设置合理过期时间
|
||||
- 对于稳定不变的数据(如品牌列表),可缓存静态结果
|
||||
- 分页策略
|
||||
- 控制 count 参数上限,避免一次性返回过多数据
|
||||
- 结合游标分页或基于主键的分页,提升大结果集性能
|
||||
- 连接池与超时
|
||||
- 数据库连接池参数已设置,搜索客户端使用短连接或复用连接视场景而定
|
||||
- 设置合理的读写超时与上下文取消,防止阻塞
|
||||
- 字段裁剪
|
||||
- 仅返回必要字段,降低网络传输与序列化成本
|
||||
- 相关性与排序
|
||||
- 使用 Meilisearch 的排序与过滤能力,避免后端二次排序
|
||||
- 日志与监控
|
||||
- 记录搜索耗时、命中率与错误统计,便于定位性能瓶颈
|
||||
|
||||
## 故障排除指南
|
||||
- 连接问题诊断
|
||||
- 检查 MEILISEARCH_HOST、MEILISEARCH_API_KEY、MEILISEARCH_INDEX 是否正确设置
|
||||
- 确认 Meilisearch 服务可达且端口开放
|
||||
- 查看启动日志中 Meilisearch 配置是否正确加载
|
||||
- 索引重建
|
||||
- 如需重建索引,先清空旧索引,再批量导入数据,最后更新字段映射与排序规则
|
||||
- 导入完成后进行回归测试,确保搜索结果符合预期
|
||||
- 性能调优
|
||||
- 逐步增加 count 上限,观察延迟变化,找到平衡点
|
||||
- 对热点查询启用缓存,减少重复请求
|
||||
- 优化数据库查询(如品牌/型号过滤)作为降级方案
|
||||
- 错误处理
|
||||
- 搜索失败时返回统一错误响应,便于前端提示
|
||||
- 对 decode 失败、上下文取消等异常进行分类处理
|
||||
|
||||
章节来源
|
||||
- [internal/config/meilisearch.go:39-50](file://internal/config/meilisearch.go#L39-L50)
|
||||
- [cmd/server/main.go:50-54](file://cmd/server/main.go#L50-L54)
|
||||
- [internal/handler/model_list.go:37-42](file://internal/handler/model_list.go#L37-L42)
|
||||
- [internal/response/response.go:34-36](file://internal/response/response.go#L34-L36)
|
||||
|
||||
## 结论
|
||||
本项目已实现 Meilisearch 的基础集成:配置加载、客户端初始化与搜索接口。当前搜索接口主要返回指定字段的命中结果,未涉及高亮、自动补全与相关性排序的高级特性。建议后续在以下方面增强:
|
||||
- 高亮显示:利用 Meilisearch 的高亮能力,返回匹配片段
|
||||
- 自动补全:结合前缀匹配与热门词,提供输入建议
|
||||
- 相关性排序:配置字段权重与排序规则,提升搜索体验
|
||||
- 索引策略:按业务维度拆分索引,优化写入与查询性能
|
||||
- 缓存策略:引入 Redis 缓存,显著降低重复查询延迟
|
||||
|
||||
## 附录
|
||||
|
||||
### 搜索 API 使用示例
|
||||
- 设备型号搜索
|
||||
- 请求:GET /audio/modelList?key=型号关键词&count=100
|
||||
- 响应:返回命中的设备列表(仅包含指定字段)
|
||||
- 品牌过滤
|
||||
- 当前未直接使用 Meilisearch 实现品牌过滤,可通过数据库查询替代
|
||||
- 请求:GET /audio/getModel?brandName=品牌名
|
||||
- 结果排序
|
||||
- 当前未显式设置排序,可结合 Meilisearch 的排序规则实现
|
||||
- Base64 响应
|
||||
- 可通过查询参数 base64=true 获取 Base64 编码的 JSON
|
||||
|
||||
章节来源
|
||||
- [internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||||
- [internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50)
|
||||
- [internal/search/meilisearch.go:22-45](file://internal/search/meilisearch.go#L22-L45)
|
||||
@@ -0,0 +1,382 @@
|
||||
# 日志系统
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
|
||||
- [internal/middleware/logger.go](file://internal/middleware/logger.go)
|
||||
- [internal/middleware/request_id.go](file://internal/middleware/request_id.go)
|
||||
- [cmd/server/main.go](file://cmd/server/main.go)
|
||||
- [internal/router/router.go](file://internal/router/router.go)
|
||||
- [internal/handler/device.go](file://internal/handler/device.go)
|
||||
- [internal/handler/model.go](file://internal/handler/model.go)
|
||||
- [internal/handler/brand.go](file://internal/handler/brand.go)
|
||||
- [internal/config/config.go](file://internal/config/config.go)
|
||||
- [go.mod](file://go.mod)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能与轮转配置](#性能与轮转配置)
|
||||
8. [最佳实践与规范](#最佳实践与规范)
|
||||
9. [故障排查与调试](#故障排查与调试)
|
||||
10. [结论](#结论)
|
||||
|
||||
## 简介
|
||||
本文件面向 Luxsin 应用 API 项目的日志系统,围绕基于 Zap 的结构化日志进行系统性梳理。内容覆盖日志客户端初始化流程、配置选项与输出格式、日志级别使用场景、在中间件与处理器中的使用方式、以及与配置加载、请求链路追踪的集成。同时给出日志聚合、监控告警与故障排查的实践建议,帮助开发者建立完善且可维护的日志体系。
|
||||
|
||||
## 项目结构
|
||||
日志系统在本项目中采用分层设计:
|
||||
- 初始化层:在服务启动时根据环境变量创建全局日志器。
|
||||
- 中间件层:统一记录请求生命周期的关键指标,按状态码选择日志级别。
|
||||
- 处理器层:在业务逻辑中记录关键事件与错误,携带上下文信息。
|
||||
- 配置层:通过环境变量控制运行模式与端口等,间接影响日志输出风格。
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "启动阶段"
|
||||
MAIN["cmd/server/main.go<br/>读取配置/创建日志器"]
|
||||
CFG["internal/config/config.go<br/>环境与端口配置"]
|
||||
end
|
||||
subgraph "中间件层"
|
||||
REQID["internal/middleware/request_id.go<br/>生成/透传请求ID"]
|
||||
LOGMW["internal/middleware/logger.go<br/>请求日志中间件"]
|
||||
ROUTER["internal/router/router.go<br/>注册中间件与路由"]
|
||||
end
|
||||
subgraph "处理器层"
|
||||
DEV["internal/handler/device.go<br/>设备上报日志"]
|
||||
MODEL["internal/handler/model.go<br/>模型查询日志"]
|
||||
BRAND["internal/handler/brand.go<br/>品牌查询日志"]
|
||||
end
|
||||
subgraph "日志库封装"
|
||||
ZAP["pkg/logger/logger.go<br/>Zap配置与构建"]
|
||||
end
|
||||
CFG --> MAIN
|
||||
MAIN --> ZAP
|
||||
MAIN --> ROUTER
|
||||
ROUTER --> REQID
|
||||
ROUTER --> LOGMW
|
||||
LOGMW --> DEV
|
||||
LOGMW --> MODEL
|
||||
LOGMW --> BRAND
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||||
- [internal/config/config.go:18-56](file://internal/config/config.go#L18-L56)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84)
|
||||
- [internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50)
|
||||
- [internal/handler/brand.go:26-49](file://internal/handler/brand.go#L26-L49)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||||
- [internal/config/config.go:18-56](file://internal/config/config.go#L18-L56)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84)
|
||||
- [internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50)
|
||||
- [internal/handler/brand.go:26-49](file://internal/handler/brand.go#L26-L49)
|
||||
|
||||
## 核心组件
|
||||
- 日志器工厂(Zap 封装):根据环境变量选择生产或开发配置,定制时间键与编码器,返回全局日志器实例。
|
||||
- 请求日志中间件:在请求完成后收集状态码、方法、路径、延迟、IP、请求ID、查询串与错误信息,按状态码映射到不同日志级别。
|
||||
- 请求ID中间件:生成唯一请求ID并在请求头中透传,便于跨服务/模块关联日志。
|
||||
- 启动入口:加载配置、设置 Gin 模式、创建日志器、连接数据库/缓存/搜索引擎、启动 HTTP 服务器并优雅关闭。
|
||||
- 处理器层:在业务关键点记录 Info/Warn/Error 等日志,携带上下文字段,如远程IP、时间戳、错误详情等。
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||||
- [internal/handler/device.go:47-78](file://internal/handler/device.go#L47-L78)
|
||||
- [internal/handler/model.go:33-43](file://internal/handler/model.go#L33-L43)
|
||||
- [internal/handler/brand.go:32-41](file://internal/handler/brand.go#L32-L41)
|
||||
|
||||
## 架构总览
|
||||
下图展示了从启动到请求处理的完整日志链路,强调日志器的创建、中间件的注入与处理器中的使用。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant Server as "HTTP服务器"
|
||||
participant Router as "Gin路由"
|
||||
participant ReqID as "请求ID中间件"
|
||||
participant LogMW as "请求日志中间件"
|
||||
participant Handler as "业务处理器"
|
||||
participant Logger as "Zap日志器"
|
||||
Client->>Server : "发起HTTP请求"
|
||||
Server->>Router : "进入路由"
|
||||
Router->>ReqID : "生成/透传请求ID"
|
||||
ReqID->>LogMW : "继续处理"
|
||||
LogMW->>Handler : "调用业务处理器"
|
||||
Handler->>Logger : "记录Info/Warn/Error"
|
||||
Handler-->>Client : "返回响应"
|
||||
LogMW->>Logger : "记录请求日志(按状态码)"
|
||||
LogMW-->>Router : "完成"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:64-64](file://cmd/server/main.go#L64-L64)
|
||||
- [internal/router/router.go:17-18](file://internal/router/router.go#L17-L18)
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [internal/handler/device.go:47-78](file://internal/handler/device.go#L47-L78)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### 日志器工厂(Zap 封装)
|
||||
- 功能:根据环境变量选择生产或开发配置,定制时间键与编码器,构建并返回全局日志器。
|
||||
- 关键点:
|
||||
- 生产环境:使用生产配置,时间键为“time”,时间编码为 ISO8601。
|
||||
- 开发环境:使用开发配置,级别编码为带颜色的大写形式。
|
||||
- 使用方式:在启动入口调用工厂创建日志器,并在退出前同步缓冲区。
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["函数入口"]) --> CheckEnv{"环境是否为生产?"}
|
||||
CheckEnv --> |是| ProdCfg["使用生产配置<br/>设置时间键与编码器"]
|
||||
CheckEnv --> |否| DevCfg["使用开发配置<br/>设置级别编码为彩色"]
|
||||
ProdCfg --> Build["构建日志器"]
|
||||
DevCfg --> Build
|
||||
Build --> Return(["返回日志器"])
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
|
||||
章节来源
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
|
||||
### 请求日志中间件
|
||||
- 功能:在请求完成后记录关键指标,按状态码选择日志级别。
|
||||
- 字段规范:
|
||||
- 状态码、方法、路径、延迟、客户端IP、请求ID。
|
||||
- 可选字段:查询串、错误信息。
|
||||
- 级别映射:
|
||||
- 5xx:Error
|
||||
- 4xx:Warn
|
||||
- 其他:Info
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Enter(["进入中间件"]) --> Collect["收集开始时间/路径/查询串"]
|
||||
Collect --> Next["调用后续处理器"]
|
||||
Next --> After["计算延迟/获取状态码/提取请求ID"]
|
||||
After --> HasErrors{"是否存在错误?"}
|
||||
HasErrors --> |是| AddErrors["附加错误字段"]
|
||||
HasErrors --> |否| SkipErrors["跳过错误字段"]
|
||||
AddErrors --> Level["按状态码选择级别"]
|
||||
SkipErrors --> Level
|
||||
Level --> Log["记录请求日志"]
|
||||
Log --> Exit(["返回响应"])
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
|
||||
章节来源
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
|
||||
### 请求ID中间件
|
||||
- 功能:生成随机十六进制字符串作为请求ID,若请求头未提供则自动生成并透传。
|
||||
- 作用:贯穿请求链路,便于聚合与关联日志。
|
||||
|
||||
章节来源
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
|
||||
### 启动入口与日志集成
|
||||
- 加载配置:从环境变量读取运行环境、主机、端口等。
|
||||
- 设置模式:生产环境设置 Gin 为 Release 模式。
|
||||
- 创建日志器:根据配置环境调用日志工厂。
|
||||
- 连接外部组件:数据库、搜索引擎、缓存;连接成功后记录 Info 日志。
|
||||
- 启动服务器:记录启动日志,捕获异常并记录 Fatal 日志。
|
||||
- 优雅关闭:记录关闭与停止日志。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Main as "main.go"
|
||||
participant Cfg as "config.Load()"
|
||||
participant Log as "logger.New()"
|
||||
participant DB as "database.Open()"
|
||||
participant Redis as "cache.NewClient()"
|
||||
participant MS as "search.NewClient()"
|
||||
participant Engine as "router.New()"
|
||||
Main->>Cfg : "加载配置"
|
||||
Cfg-->>Main : "返回配置"
|
||||
Main->>Log : "创建日志器"
|
||||
Log-->>Main : "返回日志器"
|
||||
Main->>DB : "连接数据库"
|
||||
DB-->>Main : "连接结果"
|
||||
Main->>MS : "配置搜索引擎"
|
||||
MS-->>Main : "配置结果"
|
||||
Main->>Redis : "连接缓存"
|
||||
Redis-->>Main : "连接结果"
|
||||
Main->>Engine : "创建路由引擎"
|
||||
Engine-->>Main : "返回引擎"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||||
- [internal/config/config.go:18-56](file://internal/config/config.go#L18-L56)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||||
- [internal/config/config.go:18-56](file://internal/config/config.go#L18-L56)
|
||||
|
||||
### 处理器中的日志使用
|
||||
- 设备上报处理器:记录上报事件与远程IP、时间等字段;对序列化与缓存写入失败记录 Error 日志。
|
||||
- 模型/品牌处理器:对数据库查询失败与响应编码失败记录 Error 日志,并返回统一错误响应。
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class DeviceHandler {
|
||||
-redis : "redis.Client"
|
||||
-log : "zap.Logger"
|
||||
+ReportDevInfo(c)
|
||||
}
|
||||
class ModelHandler {
|
||||
-repo : "ModelRepository"
|
||||
-log : "zap.Logger"
|
||||
+GetModel(c)
|
||||
}
|
||||
class BrandHandler {
|
||||
-repo : "BrandRepository"
|
||||
-log : "zap.Logger"
|
||||
+GetBrand(c)
|
||||
}
|
||||
class ZapLogger {
|
||||
+Info(msg, fields)
|
||||
+Warn(msg, fields)
|
||||
+Error(msg, fields)
|
||||
+Fatal(msg, fields)
|
||||
}
|
||||
DeviceHandler --> ZapLogger : "记录Info/Error"
|
||||
ModelHandler --> ZapLogger : "记录Error"
|
||||
BrandHandler --> ZapLogger : "记录Error"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/handler/device.go:14-24](file://internal/handler/device.go#L14-L24)
|
||||
- [internal/handler/model.go:14-24](file://internal/handler/model.go#L14-L24)
|
||||
- [internal/handler/brand.go:14-24](file://internal/handler/brand.go#L14-L24)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
|
||||
章节来源
|
||||
- [internal/handler/device.go:47-78](file://internal/handler/device.go#L47-L78)
|
||||
- [internal/handler/model.go:33-43](file://internal/handler/model.go#L33-L43)
|
||||
- [internal/handler/brand.go:32-41](file://internal/handler/brand.go#L32-L41)
|
||||
|
||||
## 依赖关系分析
|
||||
- 组件耦合:
|
||||
- 路由器依赖日志器、数据库、搜索引擎、缓存客户端;通过构造函数注入,降低耦合度。
|
||||
- 中间件依赖日志器;请求ID中间件独立于日志器。
|
||||
- 处理器依赖日志器与数据源;通过构造函数注入。
|
||||
- 外部依赖:
|
||||
- Gin:Web 框架,提供中间件与路由能力。
|
||||
- Zap:结构化日志库,提供高性能日志记录。
|
||||
- Redis、MySQL、Meilisearch:外部服务,通过连接客户端访问。
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
MAIN["cmd/server/main.go"] --> ROUTER["internal/router/router.go"]
|
||||
MAIN --> ZAP["pkg/logger/logger.go"]
|
||||
ROUTER --> REQID["internal/middleware/request_id.go"]
|
||||
ROUTER --> LOGMW["internal/middleware/logger.go"]
|
||||
ROUTER --> DEV["internal/handler/device.go"]
|
||||
ROUTER --> MODEL["internal/handler/model.go"]
|
||||
ROUTER --> BRAND["internal/handler/brand.go"]
|
||||
DEV --> ZAP
|
||||
MODEL --> ZAP
|
||||
BRAND --> ZAP
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:64-64](file://cmd/server/main.go#L64-L64)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
- [internal/middleware/request_id.go:20-30](file://internal/middleware/request_id.go#L20-L30)
|
||||
- [internal/middleware/logger.go:10-45](file://internal/middleware/logger.go#L10-L45)
|
||||
- [internal/handler/device.go:14-24](file://internal/handler/device.go#L14-L24)
|
||||
- [internal/handler/model.go:14-24](file://internal/handler/model.go#L14-L24)
|
||||
- [internal/handler/brand.go:14-24](file://internal/handler/brand.go#L14-L24)
|
||||
- [pkg/logger/logger.go:8-19](file://pkg/logger/logger.go#L8-L19)
|
||||
|
||||
章节来源
|
||||
- [go.mod:5-11](file://go.mod#L5-L11)
|
||||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||||
|
||||
## 性能与轮转配置
|
||||
- 当前实现:
|
||||
- 日志器在启动时创建并使用默认输出(标准输出),未显式配置文件输出与轮转策略。
|
||||
- 在退出时执行同步,确保缓冲区落盘。
|
||||
- 建议扩展(概念性指导):
|
||||
- 文件输出与轮转:通过自定义 Zap 编码器与输出目标,结合文件轮转策略(大小/时间/数量限制)提升可维护性。
|
||||
- 异步写入:启用异步日志器,减少阻塞;结合队列长度与丢弃策略平衡性能与可靠性。
|
||||
- 采样与速率限制:对高频日志进行采样,避免在峰值流量下产生过多 I/O。
|
||||
- 结构化字段规范化:统一字段命名与类型,便于下游检索与聚合。
|
||||
- 本节为通用建议,不直接对应具体代码文件。
|
||||
|
||||
## 最佳实践与规范
|
||||
- 字段命名规范
|
||||
- 使用语义明确的键名,如状态码、方法、路径、延迟、IP、请求ID、错误等。
|
||||
- 时间字段建议统一为 ISO8601 或 Unix 时间戳,便于排序与解析。
|
||||
- 上下文传递
|
||||
- 通过请求ID贯穿请求链路,便于跨模块聚合日志。
|
||||
- 在处理器中记录关键业务事件与错误详情,包含上下文字段。
|
||||
- 日志级别使用
|
||||
- Info:常规业务事件、连接成功、启动/关闭等。
|
||||
- Warn:客户端错误(4xx)、潜在问题但不影响功能。
|
||||
- Error:服务端错误(5xx)、数据库/缓存/序列化失败等。
|
||||
- Fatal:致命错误导致进程退出,通常用于不可恢复的初始化失败。
|
||||
- 性能考虑
|
||||
- 避免在热路径上进行昂贵的字符串拼接或格式化。
|
||||
- 对高频日志进行采样或降级。
|
||||
- 控制日志字段数量,仅记录必要信息。
|
||||
- 实践示例
|
||||
- 启动阶段记录连接信息与环境配置。
|
||||
- 中间件按状态码选择级别,统一记录请求指标。
|
||||
- 处理器在错误分支记录 Error 日志并返回统一错误响应。
|
||||
|
||||
章节来源
|
||||
- [internal/middleware/logger.go:22-43](file://internal/middleware/logger.go#L22-L43)
|
||||
- [internal/handler/device.go:47-78](file://internal/handler/device.go#L47-L78)
|
||||
- [internal/handler/model.go:33-43](file://internal/handler/model.go#L33-L43)
|
||||
- [internal/handler/brand.go:32-41](file://internal/handler/brand.go#L32-L41)
|
||||
- [cmd/server/main.go:44-48](file://cmd/server/main.go#L44-L48)
|
||||
- [cmd/server/main.go:75-78](file://cmd/server/main.go#L75-L78)
|
||||
|
||||
## 故障排查与调试
|
||||
- 常见问题
|
||||
- 数据库连接失败:启动阶段记录 Fatal 日志,检查配置与网络连通性。
|
||||
- Redis 连接失败:记录 Error 日志,确认地址、端口与认证配置。
|
||||
- 请求日志缺失:确认中间件已注册且顺序正确。
|
||||
- 请求ID未透传:检查请求头是否被上游代理或网关修改。
|
||||
- 调试技巧
|
||||
- 切换到开发环境以获得彩色输出与更详细的级别编码,便于本地调试。
|
||||
- 在关键业务点增加 Info 日志,记录输入参数与关键中间结果。
|
||||
- 使用统一错误响应包装,确保错误信息一致且可检索。
|
||||
- 建议的排查步骤
|
||||
- 查看启动日志,确认各组件连接成功。
|
||||
- 在中间件层观察请求日志,定位异常状态码与耗时。
|
||||
- 在处理器层查看 Error 日志,结合请求ID定位具体请求。
|
||||
- 检查下游服务(数据库/缓存/搜索引擎)的可用性与配置。
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:40-41](file://cmd/server/main.go#L40-L41)
|
||||
- [cmd/server/main.go:56-62](file://cmd/server/main.go#L56-L62)
|
||||
- [internal/middleware/logger.go:37-43](file://internal/middleware/logger.go#L37-L43)
|
||||
- [internal/handler/device.go:62-78](file://internal/handler/device.go#L62-L78)
|
||||
|
||||
## 结论
|
||||
本项目采用简洁而高效的日志体系:通过工厂封装统一创建日志器,中间件集中记录请求指标,处理器在关键节点记录业务与错误日志。结合请求ID与结构化字段,能够有效支撑日志聚合、监控告警与故障排查。建议在生产环境中进一步引入文件输出与轮转策略、异步写入与采样机制,以满足更高的可靠性与性能要求。
|
||||
@@ -0,0 +1,326 @@
|
||||
# 缓存系统
|
||||
|
||||
<cite>
|
||||
**本文引用的文件**
|
||||
- [cmd/server/main.go](file://cmd/server/main.go)
|
||||
- [internal/cache/redis.go](file://internal/cache/redis.go)
|
||||
- [internal/config/config.go](file://internal/config/config.go)
|
||||
- [internal/config/redis.go](file://internal/config/redis.go)
|
||||
- [internal/router/router.go](file://internal/router/router.go)
|
||||
- [internal/handler/device.go](file://internal/handler/device.go)
|
||||
- [go.mod](file://go.mod)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [简介](#简介)
|
||||
2. [项目结构](#项目结构)
|
||||
3. [核心组件](#核心组件)
|
||||
4. [架构总览](#架构总览)
|
||||
5. [详细组件分析](#详细组件分析)
|
||||
6. [依赖关系分析](#依赖关系分析)
|
||||
7. [性能考虑](#性能考虑)
|
||||
8. [故障排查指南](#故障排查指南)
|
||||
9. [结论](#结论)
|
||||
10. [附录](#附录)
|
||||
|
||||
## 简介
|
||||
本文件面向 Luxsin 应用 API 的缓存系统,聚焦 Redis 缓存客户端的初始化流程、连接配置与使用方式。当前代码库实现了最小可用的 Redis 客户端封装与配置加载,并在设备上报接口中演示了哈希写入的典型用法。本文将从系统架构、组件职责、数据流、错误处理到性能优化与故障恢复进行系统化梳理,帮助初学者快速上手,同时为高级用户提供深入的技术细节与最佳实践参考。
|
||||
|
||||
## 项目结构
|
||||
与缓存系统直接相关的模块分布如下:
|
||||
- 配置层:负责加载环境变量与默认值,生成 RedisConfig 并进行基础校验
|
||||
- 缓存层:基于 RedisConfig 构造 Redis 客户端实例
|
||||
- 应用入口:在启动时加载配置、初始化缓存客户端并注入路由
|
||||
- 路由与处理器:将 Redis 客户端注入到需要缓存能力的处理器中
|
||||
- 外部依赖:通过 go.mod 指定 Redis 客户端版本
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "应用入口"
|
||||
MAIN["cmd/server/main.go<br/>启动与生命周期管理"]
|
||||
end
|
||||
subgraph "配置层"
|
||||
CFG["internal/config/config.go<br/>统一配置加载"]
|
||||
REDIS_CFG["internal/config/redis.go<br/>Redis 配置与校验"]
|
||||
end
|
||||
subgraph "缓存层"
|
||||
CACHE["internal/cache/redis.go<br/>NewClient 构造 Redis 客户端"]
|
||||
end
|
||||
subgraph "路由与处理器"
|
||||
ROUTER["internal/router/router.go<br/>路由注册与依赖注入"]
|
||||
DEVICE["internal/handler/device.go<br/>设备上报使用 Redis"]
|
||||
end
|
||||
subgraph "外部依赖"
|
||||
MOD["go.mod<br/>Redis 客户端版本"]
|
||||
end
|
||||
MAIN --> CFG
|
||||
CFG --> REDIS_CFG
|
||||
MAIN --> CACHE
|
||||
CACHE --> DEVICE
|
||||
ROUTER --> DEVICE
|
||||
MOD --> CACHE
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:22-62](file://cmd/server/main.go#L22-L62)
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/router/router.go:14-25](file://internal/router/router.go#L14-L25)
|
||||
- [internal/handler/device.go:26-78](file://internal/handler/device.go#L26-L78)
|
||||
- [go.mod:9](file://go.mod#L9)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:22-62](file://cmd/server/main.go#L22-L62)
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/router/router.go:14-25](file://internal/router/router.go#L14-L25)
|
||||
- [internal/handler/device.go:26-78](file://internal/handler/device.go#L26-L78)
|
||||
- [go.mod:9](file://go.mod#L9)
|
||||
|
||||
## 核心组件
|
||||
- RedisConfig:定义 Redis 连接所需的主机、端口、密码与数据库编号,并提供校验逻辑
|
||||
- NewClient:根据 RedisConfig 创建 Redis 客户端实例,设置 Addr、Password、DB 等选项
|
||||
- 配置加载:Load 统一加载应用配置,其中包含 Redis 配置加载与校验
|
||||
- 启动流程:main 在启动阶段创建 Redis 客户端并注入路由,服务关闭时释放连接
|
||||
- 使用示例:设备上报接口在请求上下文中向 Redis 写入哈希字段
|
||||
|
||||
章节来源
|
||||
- [internal/config/redis.go:9-14](file://internal/config/redis.go#L9-L14)
|
||||
- [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [cmd/server/main.go:22-62](file://cmd/server/main.go#L22-L62)
|
||||
- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
|
||||
|
||||
## 架构总览
|
||||
下图展示了从应用启动到 Redis 客户端被注入处理器的整体流程:
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Boot as "启动器(main)"
|
||||
participant Cfg as "配置加载(Config.Load)"
|
||||
participant RdsCfg as "Redis 配置(loadRedis)"
|
||||
participant Cache as "NewClient"
|
||||
participant Router as "路由(router)"
|
||||
participant Dev as "设备处理器(DeviceHandler)"
|
||||
Boot->>Cfg : 加载配置
|
||||
Cfg->>RdsCfg : 读取 Redis 配置并校验
|
||||
RdsCfg-->>Cfg : 返回 RedisConfig
|
||||
Cfg-->>Boot : 返回完整 Config
|
||||
Boot->>Cache : 基于 RedisConfig 创建客户端
|
||||
Cache-->>Boot : 返回 *redis.Client
|
||||
Boot->>Router : 注入 Redis 客户端
|
||||
Router-->>Dev : 初始化处理器并传入 Redis 客户端
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:22-62](file://cmd/server/main.go#L22-L62)
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/router/router.go:14-25](file://internal/router/router.go#L14-L25)
|
||||
|
||||
## 详细组件分析
|
||||
|
||||
### Redis 客户端初始化与配置
|
||||
- NewClient 实现要点
|
||||
- 将 Host 与 Port 组合为 Addr 字符串
|
||||
- 设置 Password 与 DB
|
||||
- 返回 redis.Client 实例供后续调用
|
||||
- 配置来源与优先级
|
||||
- 若存在环境变量 REDIS_HOST,则以环境变量 REDIS_HOST/REDIS_PORT/REDIS_PASSWORD/REDIS_DATABASE 为准
|
||||
- 否则根据运行环境(开发/生产)选择默认主机与端口,并从环境变量读取密码与数据库编号
|
||||
- 校验规则
|
||||
- RedisConfig.validate 校验 Host 必填;其他字段如 Password、Database 可为空或按需提供
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start(["开始"]) --> CheckEnv["检查是否存在 REDIS_HOST"]
|
||||
CheckEnv --> |是| FromEnv["从环境变量读取 Redis 配置"]
|
||||
CheckEnv --> |否| SwitchEnv["根据运行环境选择默认配置"]
|
||||
FromEnv --> Validate["执行 validate 校验 Host"]
|
||||
SwitchEnv --> Validate
|
||||
Validate --> |通过| BuildClient["调用 NewClient 构造客户端"]
|
||||
Validate --> |失败| Error["返回错误"]
|
||||
BuildClient --> End(["结束"])
|
||||
Error --> End
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
|
||||
章节来源
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
- [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56)
|
||||
|
||||
### 启动流程与生命周期
|
||||
- 启动阶段
|
||||
- 加载配置后,创建 Redis 客户端并记录连接信息
|
||||
- 将客户端注入路由,随后启动 HTTP 服务器
|
||||
- 关闭阶段
|
||||
- 优雅关闭时调用 Close 释放连接
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant M as "main"
|
||||
participant R as "Redis 客户端"
|
||||
participant S as "HTTP 服务器"
|
||||
M->>M : 加载配置
|
||||
M->>R : NewClient(cfg.Redis)
|
||||
M->>S : 启动监听
|
||||
S-->>M : 服务运行中
|
||||
M->>R : 关闭时调用 Close
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:22-62](file://cmd/server/main.go#L22-L62)
|
||||
- [cmd/server/main.go:87-94](file://cmd/server/main.go#L87-L94)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:22-62](file://cmd/server/main.go#L22-L62)
|
||||
- [cmd/server/main.go:87-94](file://cmd/server/main.go#L87-L94)
|
||||
|
||||
### 设备上报接口中的缓存使用
|
||||
- 典型场景
|
||||
- 从请求参数构造设备信息,序列化为 JSON
|
||||
- 在请求上下文基础上向 Redis 写入哈希字段 devices,键为 MAC 地址
|
||||
- 错误处理
|
||||
- HSet 失败时记录日志并返回系统错误响应
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client as "客户端"
|
||||
participant Handler as "DeviceHandler"
|
||||
participant Redis as "Redis 客户端"
|
||||
Client->>Handler : GET /audio/reportDevInfo?mac=...&model=...
|
||||
Handler->>Handler : 参数校验与日志记录
|
||||
Handler->>Handler : 构造设备信息并序列化
|
||||
Handler->>Redis : HSet(ctx, "devices", mac, json)
|
||||
alt 成功
|
||||
Handler-->>Client : 返回成功响应
|
||||
else 失败
|
||||
Handler-->>Client : 返回系统错误
|
||||
end
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/handler/device.go:26-78](file://internal/handler/device.go#L26-L78)
|
||||
|
||||
章节来源
|
||||
- [internal/handler/device.go:26-78](file://internal/handler/device.go#L26-L78)
|
||||
|
||||
### 类图:配置与客户端关系
|
||||
```mermaid
|
||||
classDiagram
|
||||
class RedisConfig {
|
||||
+string Host
|
||||
+int Port
|
||||
+string Password
|
||||
+int Database
|
||||
+validate() error
|
||||
}
|
||||
class NewClient {
|
||||
+NewClient(cfg RedisConfig) *redis.Client
|
||||
}
|
||||
class Config {
|
||||
+string Env
|
||||
+string Host
|
||||
+int Port
|
||||
+Database DatabaseConfig
|
||||
+Meilisearch MeilisearchConfig
|
||||
+Redis RedisConfig
|
||||
+Addr() string
|
||||
}
|
||||
NewClient --> RedisConfig : "接收配置"
|
||||
Config --> RedisConfig : "包含"
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [internal/config/redis.go:9-14](file://internal/config/redis.go#L9-L14)
|
||||
- [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56)
|
||||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||||
- [internal/config/config.go:9-16](file://internal/config/config.go#L9-L16)
|
||||
|
||||
## 依赖关系分析
|
||||
- Redis 客户端版本
|
||||
- 通过 go.mod 指定 github.com/redis/go-redis/v9 版本
|
||||
- 模块耦合
|
||||
- cache/redis.go 仅依赖 internal/config 中的 RedisConfig
|
||||
- cmd/server/main.go 依赖 cache/redis.go 与 internal/config
|
||||
- internal/router/router.go 依赖 redis.go 与 handler 层
|
||||
- internal/handler/device.go 依赖 redis.go 与 zap 日志
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
MAIN["cmd/server/main.go"] --> CACHE["internal/cache/redis.go"]
|
||||
MAIN --> CFG["internal/config/config.go"]
|
||||
CFG --> REDISCFG["internal/config/redis.go"]
|
||||
ROUTER["internal/router/router.go"] --> DEVICE["internal/handler/device.go"]
|
||||
DEVICE --> CACHE
|
||||
MOD["go.mod"] --> CACHE
|
||||
```
|
||||
|
||||
图表来源
|
||||
- [cmd/server/main.go:13-18](file://cmd/server/main.go#L13-L18)
|
||||
- [internal/cache/redis.go:6-7](file://internal/cache/redis.go#L6-L7)
|
||||
- [internal/router/router.go:10](file://internal/router/router.go#L10)
|
||||
- [internal/handler/device.go:10](file://internal/handler/device.go#L10)
|
||||
- [go.mod:9](file://go.mod#L9)
|
||||
|
||||
章节来源
|
||||
- [cmd/server/main.go:13-18](file://cmd/server/main.go#L13-L18)
|
||||
- [internal/cache/redis.go:6-7](file://internal/cache/redis.go#L6-L7)
|
||||
- [internal/router/router.go:10](file://internal/router/router.go#L10)
|
||||
- [internal/handler/device.go:10](file://internal/handler/device.go#L10)
|
||||
- [go.mod:9](file://go.mod#L9)
|
||||
|
||||
## 性能考虑
|
||||
- 连接池与并发
|
||||
- 当前 NewClient 未显式设置连接池参数,Redis 客户端默认行为将复用连接;在高并发场景建议结合业务压力测试评估连接数上限
|
||||
- 超时与上下文
|
||||
- 所有 Redis 操作均使用请求上下文,便于在上游取消或超时控制
|
||||
- 数据过期与键空间
|
||||
- 当前示例未设置过期时间;对于临时数据可考虑在写入时设置 TTL,避免无界增长
|
||||
- 键命名规范
|
||||
- 示例使用固定字段名 devices;建议采用前缀+业务域+标识的命名规范,便于运维与清理
|
||||
- 批量与流水线
|
||||
- 对于批量写入场景,可考虑使用 Pipeline 或 MSET/MGET 提升吞吐
|
||||
|
||||
## 故障排查指南
|
||||
- 连接失败
|
||||
- 检查 REDIS_HOST/REDIS_PORT/REDIS_PASSWORD/REDIS_DATABASE 是否正确
|
||||
- 确认 validate 校验未返回“redis host is required”
|
||||
- 写入失败
|
||||
- 查看 HSet 返回的错误并结合日志定位
|
||||
- 确认 Redis 服务状态与网络连通性
|
||||
- 优雅关闭
|
||||
- 确保在服务关闭时调用 Close,避免资源泄漏
|
||||
|
||||
章节来源
|
||||
- [internal/config/redis.go:51-56](file://internal/config/redis.go#L51-L56)
|
||||
- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
|
||||
- [cmd/server/main.go:87-94](file://cmd/server/main.go#L87-L94)
|
||||
|
||||
## 结论
|
||||
当前缓存系统以简洁的方式完成了 Redis 客户端的初始化与注入,满足基本的键值写入需求。建议在后续迭代中补充连接池配置、过期策略、键命名规范与监控告警,以提升稳定性与可观测性。同时,可在更多处理器中引入缓存读取与写入,形成统一的缓存访问模式。
|
||||
|
||||
## 附录
|
||||
|
||||
### 配置项一览
|
||||
- 应用层
|
||||
- APP_ENV:运行环境(development/production)
|
||||
- APP_HOST:监听地址
|
||||
- APP_PORT:监听端口
|
||||
- Redis 层
|
||||
- REDIS_HOST:Redis 主机(优先级最高)
|
||||
- REDIS_PORT:Redis 端口(默认 16279)
|
||||
- REDIS_PASSWORD:Redis 密码(默认 eafon123!)
|
||||
- REDIS_DATABASE:数据库编号(默认 1)
|
||||
|
||||
章节来源
|
||||
- [internal/config/config.go:18-52](file://internal/config/config.go#L18-L52)
|
||||
- [internal/config/redis.go:16-56](file://internal/config/redis.go#L16-L56)
|
||||
Reference in New Issue
Block a user