2026-05-27 18:07:55 +08:00
|
|
|
|
# 路由系统
|
|
|
|
|
|
|
|
|
|
|
|
<cite>
|
|
|
|
|
|
**本文引用的文件**
|
|
|
|
|
|
- [router.go](file://internal/router/router.go)
|
|
|
|
|
|
- [main.go](file://cmd/server/main.go)
|
|
|
|
|
|
- [cors.go](file://internal/middleware/cors.go)
|
|
|
|
|
|
- [logger.go](file://internal/middleware/logger.go)
|
|
|
|
|
|
- [request_id.go](file://internal/middleware/request_id.go)
|
|
|
|
|
|
- [health.go](file://internal/handler/health.go)
|
|
|
|
|
|
- [brand.go](file://internal/handler/brand.go)
|
|
|
|
|
|
- [model.go](file://internal/handler/model.go)
|
|
|
|
|
|
- [model_list.go](file://internal/handler/model_list.go)
|
|
|
|
|
|
- [device.go](file://internal/handler/device.go)
|
|
|
|
|
|
- [response.go](file://internal/response/response.go)
|
|
|
|
|
|
- [config.go](file://internal/config/config.go)
|
|
|
|
|
|
- [base64.go](file://pkg/encode/base64.go)
|
|
|
|
|
|
- [README.md](file://README.md)
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- [redis.go](file://internal/cache/redis.go)
|
|
|
|
|
|
- [brand_cache.go](file://internal/cache/brand_cache.go)
|
|
|
|
|
|
- [model_cache.go](file://internal/cache/model_cache.go)
|
|
|
|
|
|
- [brand.go](file://internal/repository/brand.go)
|
|
|
|
|
|
- [model.go](file://internal/repository/model.go)
|
|
|
|
|
|
- [redis.go](file://internal/config/redis.go)
|
|
|
|
|
|
- [meilisearch.go](file://internal/config/meilisearch.go)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
</cite>
|
|
|
|
|
|
|
|
|
|
|
|
## 目录
|
|
|
|
|
|
1. [简介](#简介)
|
|
|
|
|
|
2. [项目结构](#项目结构)
|
|
|
|
|
|
3. [核心组件](#核心组件)
|
|
|
|
|
|
4. [架构总览](#架构总览)
|
|
|
|
|
|
5. [详细组件分析](#详细组件分析)
|
|
|
|
|
|
6. [依赖关系分析](#依赖关系分析)
|
|
|
|
|
|
7. [性能考量](#性能考量)
|
|
|
|
|
|
8. [故障排查指南](#故障排查指南)
|
|
|
|
|
|
9. [结论](#结论)
|
|
|
|
|
|
10. [附录](#附录)
|
|
|
|
|
|
|
|
|
|
|
|
## 简介
|
|
|
|
|
|
本文件系统性梳理 Luxsin 应用 API 的路由体系与中间件机制,重点覆盖:
|
|
|
|
|
|
- Gin 路由工厂函数 New 的实现与控制流
|
|
|
|
|
|
- 路由分组策略(/api/v1 与 /audio)
|
|
|
|
|
|
- 中间件执行顺序与职责(CORS、日志、请求 ID)
|
|
|
|
|
|
- 各端点功能、参数与返回规范
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- 依赖注入链:缓存与仓库实例的初始化与装配
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 最佳实践与性能优化建议
|
|
|
|
|
|
- 典型调用序列与中间件链路分析
|
|
|
|
|
|
|
|
|
|
|
|
## 项目结构
|
2026-05-28 15:30:05 +08:00
|
|
|
|
路由系统位于 internal/router,入口在 cmd/server/main.go,配合中间件、处理器、统一响应体、缓存与仓库模块协同工作。**更新**:路由系统现已增强,负责初始化缓存和仓库实例,建立完整的依赖注入链。
|
2026-05-27 18:07:55 +08:00
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
graph TB
|
|
|
|
|
|
subgraph "服务入口"
|
|
|
|
|
|
MAIN["cmd/server/main.go<br/>启动 HTTP 服务器"]
|
2026-05-28 15:30:05 +08:00
|
|
|
|
ENDSUBGRAPH
|
2026-05-27 18:07:55 +08:00
|
|
|
|
subgraph "路由与中间件"
|
|
|
|
|
|
ROUTER["internal/router/router.go<br/>路由工厂与分组注册"]
|
|
|
|
|
|
CORS["internal/middleware/cors.go<br/>CORS 中间件"]
|
|
|
|
|
|
LOGMW["internal/middleware/logger.go<br/>日志中间件"]
|
|
|
|
|
|
REQID["internal/middleware/request_id.go<br/>请求 ID 中间件"]
|
2026-05-28 15:30:05 +08:00
|
|
|
|
ENDSUBGRAPH
|
|
|
|
|
|
subgraph "缓存与仓库层"
|
|
|
|
|
|
BRANDCACHE["internal/cache/brand_cache.go<br/>品牌缓存"]
|
|
|
|
|
|
MODELCACHE["internal/cache/model_cache.go<br/>型号缓存"]
|
|
|
|
|
|
BRANDREPO["internal/repository/brand.go<br/>品牌仓库"]
|
|
|
|
|
|
MODELREPO["internal/repository/model.go<br/>型号仓库"]
|
|
|
|
|
|
ENDSUBGRAPH
|
2026-05-27 18:07:55 +08:00
|
|
|
|
subgraph "处理器层"
|
|
|
|
|
|
HEALTH["internal/handler/health.go"]
|
|
|
|
|
|
BRAND["internal/handler/brand.go"]
|
|
|
|
|
|
MODEL["internal/handler/model.go"]
|
|
|
|
|
|
MODELLIST["internal/handler/model_list.go"]
|
|
|
|
|
|
DEVICE["internal/handler/device.go"]
|
2026-05-28 15:30:05 +08:00
|
|
|
|
ENDSUBGRAPH
|
2026-05-27 18:07:55 +08:00
|
|
|
|
subgraph "基础设施"
|
|
|
|
|
|
RESP["internal/response/response.go<br/>统一响应体"]
|
|
|
|
|
|
ENCODE["pkg/encode/base64.go<br/>Base64 编解码"]
|
|
|
|
|
|
CONFIG["internal/config/config.go<br/>配置加载"]
|
2026-05-28 15:30:05 +08:00
|
|
|
|
ENDSUBGRAPH
|
2026-05-27 18:07:55 +08:00
|
|
|
|
MAIN --> ROUTER
|
|
|
|
|
|
ROUTER --> CORS
|
|
|
|
|
|
ROUTER --> LOGMW
|
|
|
|
|
|
ROUTER --> REQID
|
2026-05-28 15:30:05 +08:00
|
|
|
|
ROUTER --> BRANDCACHE
|
|
|
|
|
|
ROUTER --> MODELCACHE
|
|
|
|
|
|
ROUTER --> BRANDREPO
|
|
|
|
|
|
ROUTER --> MODELREPO
|
2026-05-27 18:07:55 +08:00
|
|
|
|
ROUTER --> HEALTH
|
|
|
|
|
|
ROUTER --> BRAND
|
|
|
|
|
|
ROUTER --> MODEL
|
|
|
|
|
|
ROUTER --> MODELLIST
|
|
|
|
|
|
ROUTER --> DEVICE
|
|
|
|
|
|
BRAND --> RESP
|
|
|
|
|
|
MODEL --> RESP
|
|
|
|
|
|
MODELLIST --> RESP
|
|
|
|
|
|
DEVICE --> RESP
|
|
|
|
|
|
MODELLIST --> ENCODE
|
|
|
|
|
|
BRAND --> ENCODE
|
|
|
|
|
|
MODEL --> ENCODE
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**图表来源**
|
|
|
|
|
|
- [router.go:16-52](file://internal/router/router.go#L16-L52)
|
|
|
|
|
|
- [main.go:59-70](file://cmd/server/main.go#L59-L70)
|
|
|
|
|
|
- [brand_cache.go:18-44](file://internal/cache/brand_cache.go#L18-L44)
|
|
|
|
|
|
- [model_cache.go:19-69](file://internal/cache/model_cache.go#L19-L69)
|
|
|
|
|
|
- [brand.go:14-52](file://internal/repository/brand.go#L14-L52)
|
|
|
|
|
|
- [model.go:14-79](file://internal/repository/model.go#L14-L79)
|
|
|
|
|
|
|
|
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [router.go:16-52](file://internal/router/router.go#L16-L52)
|
|
|
|
|
|
- [main.go:25-101](file://cmd/server/main.go#L25-L101)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [README.md:19-123](file://README.md#L19-L123)
|
|
|
|
|
|
|
|
|
|
|
|
## 核心组件
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- 路由工厂函数 New:集中初始化 Gin 引擎、注册全局中间件、创建各处理器实例,并完成路由分组与注册。**更新**:现负责初始化缓存和仓库实例,建立完整的依赖注入链。
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 路由分组:
|
|
|
|
|
|
- /api/v1:版本化健康检查端点
|
|
|
|
|
|
- /audio:音频设备相关业务端点
|
|
|
|
|
|
- 中间件链:Recovery -> RequestID -> Logger -> CORS
|
|
|
|
|
|
- 统一响应体:OK/Fail/BadRequest/InternalError,保证一致的返回结构
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- **新增**:依赖注入链路
|
|
|
|
|
|
- 缓存层:BrandCache、ModelCache
|
|
|
|
|
|
- 仓库层:BrandRepository、ModelRepository
|
|
|
|
|
|
- 处理器层:HealthHandler、BrandHandler、ModelHandler、ModelListHandler、DeviceHandler
|
2026-05-27 18:07:55 +08:00
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [router.go:16-52](file://internal/router/router.go#L16-L52)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [response.go:15-36](file://internal/response/response.go#L15-L36)
|
|
|
|
|
|
|
|
|
|
|
|
## 架构总览
|
2026-05-28 15:30:05 +08:00
|
|
|
|
下图展示了从请求进入至响应返回的完整链路,包括中间件执行顺序、依赖注入与处理器调用。
|
2026-05-27 18:07:55 +08:00
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
|
participant C as "客户端"
|
|
|
|
|
|
participant G as "Gin 引擎"
|
|
|
|
|
|
participant R as "路由分组(/api/v1 或 /audio)"
|
|
|
|
|
|
participant M1 as "中间件 : Recovery"
|
|
|
|
|
|
participant M2 as "中间件 : RequestID"
|
|
|
|
|
|
participant M3 as "中间件 : Logger"
|
|
|
|
|
|
participant M4 as "中间件 : CORS"
|
|
|
|
|
|
participant H as "处理器"
|
|
|
|
|
|
C->>G : "HTTP 请求"
|
|
|
|
|
|
G->>M1 : "进入中间件链"
|
|
|
|
|
|
M1->>M2 : "继续"
|
|
|
|
|
|
M2->>M3 : "继续"
|
|
|
|
|
|
M3->>M4 : "继续"
|
|
|
|
|
|
M4->>R : "匹配路由分组"
|
|
|
|
|
|
R->>H : "调用对应处理器"
|
|
|
|
|
|
H-->>G : "写入响应"
|
|
|
|
|
|
G-->>C : "HTTP 响应"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**图表来源**
|
|
|
|
|
|
- [router.go:16-52](file://internal/router/router.go#L16-L52)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [logger.go:10-44](file://internal/middleware/logger.go#L10-L44)
|
|
|
|
|
|
- [request_id.go:20-29](file://internal/middleware/request_id.go#L20-L29)
|
|
|
|
|
|
- [cors.go:7-19](file://internal/middleware/cors.go#L7-L19)
|
|
|
|
|
|
|
|
|
|
|
|
## 详细组件分析
|
|
|
|
|
|
|
|
|
|
|
|
### 路由工厂与中间件链
|
|
|
|
|
|
- 工厂函数 New 创建 Gin 引擎并按顺序注册中间件,确保异常恢复、请求追踪、日志记录与跨域支持贯穿所有路由。
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- **更新**:在处理器创建前完成缓存和仓库实例的初始化,形成完整的依赖注入链。
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 中间件顺序决定日志统计的粒度与错误兜底能力,建议保持现有顺序以获得最佳可观测性与稳定性。
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [router.go:16-52](file://internal/router/router.go#L16-L52)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [logger.go:10-44](file://internal/middleware/logger.go#L10-L44)
|
|
|
|
|
|
- [request_id.go:20-29](file://internal/middleware/request_id.go#L20-L29)
|
|
|
|
|
|
- [cors.go:7-19](file://internal/middleware/cors.go#L7-L19)
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
### 依赖注入链详解
|
|
|
|
|
|
|
|
|
|
|
|
#### 缓存层初始化
|
|
|
|
|
|
- BrandCache:管理品牌全量数据缓存,键为 "brand:all",TTL 30 分钟
|
|
|
|
|
|
- ModelCache:管理型号数据缓存,支持按品牌和全量两种缓存策略
|
|
|
|
|
|
- 缓存键空间:
|
|
|
|
|
|
- 品牌:brand:all
|
|
|
|
|
|
- 型号按品牌:model:brand:{brand}
|
|
|
|
|
|
- 型号全量:model:all
|
|
|
|
|
|
|
|
|
|
|
|
#### 仓库层初始化
|
|
|
|
|
|
- BrandRepository:封装品牌数据访问,支持缓存优先策略
|
|
|
|
|
|
- ModelRepository:封装型号数据访问,支持多维度缓存策略
|
|
|
|
|
|
- 仓库层具备缓存降级能力,Redis 异常时自动回退到数据库
|
|
|
|
|
|
|
|
|
|
|
|
#### 处理器层初始化
|
|
|
|
|
|
- HealthHandler:健康检查处理器
|
|
|
|
|
|
- BrandHandler:品牌列表处理器,依赖 BrandRepository
|
|
|
|
|
|
- ModelHandler:型号列表处理器,依赖 ModelRepository
|
|
|
|
|
|
- ModelListHandler:型号搜索处理器,依赖 Meilisearch 客户端
|
|
|
|
|
|
- DeviceHandler:设备信息上报处理器,直接依赖 Redis 客户端
|
|
|
|
|
|
|
|
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [router.go:23-36](file://internal/router/router.go#L23-L36)
|
|
|
|
|
|
- [brand_cache.go:13-44](file://internal/cache/brand_cache.go#L13-L44)
|
|
|
|
|
|
- [model_cache.go:13-69](file://internal/cache/model_cache.go#L13-L69)
|
|
|
|
|
|
- [brand.go:14-52](file://internal/repository/brand.go#L14-L52)
|
|
|
|
|
|
- [model.go:14-79](file://internal/repository/model.go#L14-L79)
|
|
|
|
|
|
|
2026-05-27 18:07:55 +08:00
|
|
|
|
### 路由分组与端点清单
|
|
|
|
|
|
- /api/v1 分组
|
|
|
|
|
|
- GET /api/v1/health → 健康检查
|
|
|
|
|
|
- /audio 分组
|
|
|
|
|
|
- GET /audio/getBrand → 品牌列表
|
|
|
|
|
|
- GET /audio/getModel → 型号列表
|
|
|
|
|
|
- GET /audio/modelList → 模型搜索列表
|
|
|
|
|
|
- GET /audio/reportDevInfo → 设备信息上报
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [router.go:38-49](file://internal/router/router.go#L38-L49)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [README.md:83-110](file://README.md#L83-L110)
|
|
|
|
|
|
|
|
|
|
|
|
### 中间件详解
|
|
|
|
|
|
|
|
|
|
|
|
#### CORS 中间件
|
|
|
|
|
|
- 设置允许来源、方法、头字段与暴露头
|
|
|
|
|
|
- 对预检请求直接返回状态码
|
|
|
|
|
|
- 放行后续处理器执行
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [cors.go:7-19](file://internal/middleware/cors.go#L7-L19)
|
|
|
|
|
|
|
|
|
|
|
|
#### 日志中间件
|
|
|
|
|
|
- 记录请求路径、方法、耗时、状态码、客户端 IP、请求 ID、查询参数与错误信息
|
|
|
|
|
|
- 按状态码分级输出(info/warn/error)
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [logger.go:10-44](file://internal/middleware/logger.go#L10-L44)
|
|
|
|
|
|
|
|
|
|
|
|
#### 请求 ID 中间件
|
|
|
|
|
|
- 从请求头读取或生成唯一标识,注入上下文并回传给客户端
|
|
|
|
|
|
- 用于全链路追踪与问题定位
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [request_id.go:20-29](file://internal/middleware/request_id.go#L20-L29)
|
|
|
|
|
|
|
|
|
|
|
|
### 处理器与端点行为
|
|
|
|
|
|
|
|
|
|
|
|
#### 健康检查 /api/v1/health
|
|
|
|
|
|
- 功能:返回服务运行状态
|
|
|
|
|
|
- 参数:无
|
|
|
|
|
|
- 返回:统一响应体,data 包含状态字段
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [health.go:14-18](file://internal/handler/health.go#L14-L18)
|
|
|
|
|
|
- [response.go:15-21](file://internal/response/response.go#L15-L21)
|
|
|
|
|
|
|
|
|
|
|
|
#### 品牌列表 /audio/getBrand
|
|
|
|
|
|
- 功能:按品牌名模糊查询品牌列表
|
|
|
|
|
|
- 查询参数:
|
|
|
|
|
|
- brandName:品牌名称(可选)
|
|
|
|
|
|
- base64Resp:是否返回 Base64 编码结果(默认 true)
|
|
|
|
|
|
- 行为:
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- 调用仓库层查询,优先使用缓存
|
|
|
|
|
|
- 缓存未命中时回退到数据库
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 可选地对结果进行 JSON 编码后返回
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [brand.go:25-48](file://internal/handler/brand.go#L25-L48)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
|
|
|
|
|
|
|
|
|
|
|
#### 型号列表 /audio/getModel
|
|
|
|
|
|
- 功能:按品牌或型号关键词查询型号列表
|
|
|
|
|
|
- 查询参数:
|
|
|
|
|
|
- brandName:品牌名称(可选)
|
|
|
|
|
|
- modelName:型号名称(可选)
|
|
|
|
|
|
- base64Resp:是否返回 Base64 编码结果(默认 true)
|
|
|
|
|
|
- 行为:
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- 调用仓库层查询,支持多种查询策略
|
|
|
|
|
|
- 缓存优先,异常时回退到数据库
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 可选地对结果进行 JSON 编码后返回
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [model.go:25-49](file://internal/handler/model.go#L25-L49)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
|
|
|
|
|
|
|
|
|
|
|
#### 模型搜索列表 /audio/modelList
|
|
|
|
|
|
- 功能:基于关键字与数量限制进行模型检索
|
|
|
|
|
|
- 查询参数:
|
|
|
|
|
|
- key:搜索关键字
|
|
|
|
|
|
- count:返回条数上限(可选,默认较大值)
|
|
|
|
|
|
- base64Resp:是否返回 Base64 编码结果(默认 true)
|
|
|
|
|
|
- 行为:
|
|
|
|
|
|
- 调用搜索引擎客户端查询
|
|
|
|
|
|
- 可选地对结果进行 JSON 编码后返回
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
|
|
|
|
|
|
|
|
|
|
|
#### 设备信息上报 /audio/reportDevInfo
|
|
|
|
|
|
- 功能:接收设备 MAC、型号、版本与来源 IP,写入缓存
|
|
|
|
|
|
- 查询参数:
|
|
|
|
|
|
- mac:设备 MAC 地址(必填)
|
|
|
|
|
|
- model:设备型号(必填)
|
|
|
|
|
|
- ver:版本号(可选)
|
|
|
|
|
|
- 行为:
|
|
|
|
|
|
- 校验必填参数
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- 组装设备信息并写入 Redis Hash
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 返回统一响应体
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [device.go:26-84](file://internal/handler/device.go#L26-L84)
|
|
|
|
|
|
|
|
|
|
|
|
### 统一响应体
|
|
|
|
|
|
- OK:成功响应,code=0,message="ok"
|
|
|
|
|
|
- Fail:通用错误,携带业务 code 与 message
|
|
|
|
|
|
- BadRequest:客户端错误
|
|
|
|
|
|
- InternalError:服务端错误
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [response.go:15-36](file://internal/response/response.go#L15-L36)
|
|
|
|
|
|
|
|
|
|
|
|
### 路由注册流程(工厂模式)
|
|
|
|
|
|
- 初始化 Gin 引擎
|
|
|
|
|
|
- 注册全局中间件(Recovery、RequestID、Logger、CORS)
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- **新增**:初始化缓存实例(BrandCache、ModelCache)
|
|
|
|
|
|
- **新增**:初始化仓库实例(BrandRepository、ModelRepository)
|
|
|
|
|
|
- **新增**:初始化处理器实例(注入相应依赖)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 创建路由分组并注册端点
|
|
|
|
|
|
- 返回引擎供 HTTP 服务器使用
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
flowchart TD
|
|
|
|
|
|
Start(["调用 New"]) --> Init["创建 Gin 引擎"]
|
|
|
|
|
|
Init --> UseRecovery["注册 Recovery 中间件"]
|
|
|
|
|
|
UseRecovery --> UseReqID["注册 RequestID 中间件"]
|
|
|
|
|
|
UseReqID --> UseLogger["注册 Logger 中间件"]
|
|
|
|
|
|
UseLogger --> UseCORS["注册 CORS 中间件"]
|
2026-05-28 15:30:05 +08:00
|
|
|
|
UseCORS --> NewCache["初始化缓存实例<br/>BrandCache, ModelCache"]
|
|
|
|
|
|
NewCache --> NewRepo["初始化仓库实例<br/>BrandRepository, ModelRepository"]
|
|
|
|
|
|
NewRepo --> NewHandlers["创建各处理器实例<br/>注入相应依赖"]
|
2026-05-27 18:07:55 +08:00
|
|
|
|
NewHandlers --> GroupV1["创建 /api/v1 分组"]
|
|
|
|
|
|
GroupV1 --> RegHealth["注册 /api/v1/health"]
|
|
|
|
|
|
NewHandlers --> GroupAudio["创建 /audio 分组"]
|
|
|
|
|
|
GroupAudio --> RegBrand["注册 /audio/getBrand"]
|
|
|
|
|
|
GroupAudio --> RegModel["注册 /audio/getModel"]
|
|
|
|
|
|
GroupAudio --> RegModelList["注册 /audio/modelList"]
|
|
|
|
|
|
GroupAudio --> RegDevice["注册 /audio/reportDevInfo"]
|
|
|
|
|
|
RegDevice --> ReturnEngine["返回引擎"]
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**图表来源**
|
|
|
|
|
|
- [router.go:16-52](file://internal/router/router.go#L16-L52)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
|
|
|
|
|
|
## 依赖关系分析
|
|
|
|
|
|
- 路由层依赖中间件层与处理器层
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- **更新**:处理器层依赖响应体、编码工具与底层存储
|
|
|
|
|
|
- **更新**:仓库层依赖缓存层与数据库连接
|
|
|
|
|
|
- **更新**:缓存层依赖 Redis 客户端
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 服务启动层负责装配配置、数据库、搜索引擎与缓存,并将它们注入路由工厂
|
|
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
graph LR
|
|
|
|
|
|
MAIN["cmd/server/main.go"] --> ROUTER["internal/router/router.go"]
|
|
|
|
|
|
ROUTER --> MW_REQID["internal/middleware/request_id.go"]
|
|
|
|
|
|
ROUTER --> MW_LOG["internal/middleware/logger.go"]
|
|
|
|
|
|
ROUTER --> MW_CORS["internal/middleware/cors.go"]
|
2026-05-28 15:30:05 +08:00
|
|
|
|
ROUTER --> CACHE["internal/cache/*"]
|
|
|
|
|
|
ROUTER --> REPO["internal/repository/*"]
|
2026-05-27 18:07:55 +08:00
|
|
|
|
ROUTER --> H_HEALTH["internal/handler/health.go"]
|
|
|
|
|
|
ROUTER --> H_BRAND["internal/handler/brand.go"]
|
|
|
|
|
|
ROUTER --> H_MODEL["internal/handler/model.go"]
|
|
|
|
|
|
ROUTER --> H_MODELLIST["internal/handler/model_list.go"]
|
|
|
|
|
|
ROUTER --> H_DEVICE["internal/handler/device.go"]
|
|
|
|
|
|
H_BRAND --> RESP["internal/response/response.go"]
|
|
|
|
|
|
H_MODEL --> RESP
|
|
|
|
|
|
H_MODELLIST --> RESP
|
|
|
|
|
|
H_DEVICE --> RESP
|
|
|
|
|
|
H_MODELLIST --> ENCODE["pkg/encode/base64.go"]
|
|
|
|
|
|
H_BRAND --> ENCODE
|
|
|
|
|
|
H_MODEL --> ENCODE
|
2026-05-28 15:30:05 +08:00
|
|
|
|
CACHE --> REDIS["Redis 客户端"]
|
|
|
|
|
|
REPO --> DB["MySQL 数据库"]
|
2026-05-27 18:07:55 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**图表来源**
|
|
|
|
|
|
- [main.go:59-70](file://cmd/server/main.go#L59-L70)
|
|
|
|
|
|
- [router.go:23-36](file://internal/router/router.go#L23-L36)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [response.go:15-36](file://internal/response/response.go#L15-L36)
|
|
|
|
|
|
- [base64.go:44-51](file://pkg/encode/base64.go#L44-L51)
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [main.go:25-101](file://cmd/server/main.go#L25-L101)
|
|
|
|
|
|
- [router.go:16-52](file://internal/router/router.go#L16-L52)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
|
|
|
|
|
|
## 性能考量
|
|
|
|
|
|
- 中间件顺序与开销
|
|
|
|
|
|
- Recovery 放在首位,避免重复包裹
|
|
|
|
|
|
- RequestID/CORS/LR 等轻量中间件顺序合理,尽量减少阻塞
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- **新增**:缓存策略优化
|
|
|
|
|
|
- 品牌全量缓存:brand:all,TTL 30 分钟
|
|
|
|
|
|
- 型号按品牌缓存:model:brand:{brand},TTL 30 分钟
|
|
|
|
|
|
- 型号全量缓存:model:all,TTL 30 分钟
|
|
|
|
|
|
- 缓存降级:Redis 异常时自动回退到数据库
|
|
|
|
|
|
- **新增**:预热机制
|
|
|
|
|
|
- 启动时从数据库加载数据到 Redis
|
|
|
|
|
|
- 品牌和型号分别进行全量预热
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- 日志中间件
|
|
|
|
|
|
- 建议仅在必要时记录查询参数,避免大对象日志
|
|
|
|
|
|
- 控制错误日志频率,防止雪崩
|
|
|
|
|
|
- 编码优化
|
|
|
|
|
|
- base64Resp 仅在需要时开启,避免不必要的编码成本
|
|
|
|
|
|
- 路由分组
|
|
|
|
|
|
- 将版本化与业务域分离,便于未来扩展与限流策略落地
|
|
|
|
|
|
|
|
|
|
|
|
## 故障排查指南
|
|
|
|
|
|
- 健康检查失败
|
|
|
|
|
|
- 检查 /api/v1/health 是否可达
|
|
|
|
|
|
- 关注日志中间件输出的状态码与耗时
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- **新增**:缓存相关问题
|
|
|
|
|
|
- Redis 连接失败:检查 Redis 配置与网络连通性
|
|
|
|
|
|
- 缓存数据异常:验证缓存键空间与 TTL 设置
|
|
|
|
|
|
- 缓存降级:确认数据库连接正常
|
|
|
|
|
|
- **新增**:仓库层问题
|
|
|
|
|
|
- SQL 查询超时:检查数据库索引与查询条件
|
|
|
|
|
|
- 仓库初始化失败:确认依赖的缓存和数据库连接正常
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- CORS 相关问题
|
|
|
|
|
|
- 确认浏览器预检请求已正确处理
|
|
|
|
|
|
- 核对允许的方法与头字段
|
|
|
|
|
|
- 请求 ID 未返回
|
|
|
|
|
|
- 检查客户端是否正确传递与读取 X-Request-ID
|
|
|
|
|
|
- 处理器错误
|
|
|
|
|
|
- 查看处理器日志中的错误字段
|
|
|
|
|
|
- 使用统一响应体的 code/message 定位问题
|
|
|
|
|
|
- 编码异常
|
|
|
|
|
|
- base64Resp 开启时确认客户端解析逻辑
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [logger.go:33-43](file://internal/middleware/logger.go#L33-L43)
|
|
|
|
|
|
- [request_id.go:22-27](file://internal/middleware/request_id.go#L22-L27)
|
|
|
|
|
|
- [cors.go:9-12](file://internal/middleware/cors.go#L9-L12)
|
|
|
|
|
|
- [response.go:23-36](file://internal/response/response.go#L23-L36)
|
|
|
|
|
|
|
|
|
|
|
|
## 结论
|
2026-05-28 15:30:05 +08:00
|
|
|
|
本路由系统采用清晰的工厂模式与中间件链设计,结合版本化与业务域分组,具备良好的可维护性与扩展性。**更新**:路由系统现已增强,负责初始化缓存和仓库实例,建立了完整的依赖注入链,提升了系统的整体性能与可靠性。遵循现有中间件顺序与统一响应体规范,有助于提升可观测性与稳定性。建议在新增端点时严格复用现有中间件与响应体,确保一致性与性能。
|
2026-05-27 18:07:55 +08:00
|
|
|
|
|
|
|
|
|
|
## 附录
|
|
|
|
|
|
|
|
|
|
|
|
### 端点一览与参数说明
|
|
|
|
|
|
- /api/v1/health
|
|
|
|
|
|
- 方法:GET
|
|
|
|
|
|
- 参数:无
|
|
|
|
|
|
- 返回:统一响应体
|
|
|
|
|
|
- /audio/getBrand
|
|
|
|
|
|
- 方法:GET
|
|
|
|
|
|
- 参数:
|
|
|
|
|
|
- brandName:字符串(可选)
|
|
|
|
|
|
- base64Resp:布尔或数字字符串(可选,默认 true)
|
|
|
|
|
|
- 返回:统一响应体
|
|
|
|
|
|
- /audio/getModel
|
|
|
|
|
|
- 方法:GET
|
|
|
|
|
|
- 参数:
|
|
|
|
|
|
- brandName:字符串(可选)
|
|
|
|
|
|
- modelName:字符串(可选)
|
|
|
|
|
|
- base64Resp:布尔或数字字符串(可选,默认 true)
|
|
|
|
|
|
- 返回:统一响应体
|
|
|
|
|
|
- /audio/modelList
|
|
|
|
|
|
- 方法:GET
|
|
|
|
|
|
- 参数:
|
|
|
|
|
|
- key:字符串(必填)
|
|
|
|
|
|
- count:整数(可选,默认较大值)
|
|
|
|
|
|
- base64Resp:布尔或数字字符串(可选,默认 true)
|
|
|
|
|
|
- 返回:统一响应体
|
|
|
|
|
|
- /audio/reportDevInfo
|
|
|
|
|
|
- 方法:GET
|
|
|
|
|
|
- 参数:
|
|
|
|
|
|
- mac:字符串(必填)
|
|
|
|
|
|
- model:字符串(必填)
|
|
|
|
|
|
- ver:字符串(可选)
|
|
|
|
|
|
- 返回:统一响应体
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**章节来源**
|
|
|
|
|
|
- [router.go:38-49](file://internal/router/router.go#L38-L49)
|
|
|
|
|
|
- [brand.go:25-48](file://internal/handler/brand.go#L25-L48)
|
|
|
|
|
|
- [model.go:25-49](file://internal/handler/model.go#L25-L49)
|
|
|
|
|
|
- [model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
|
|
|
|
|
- [device.go:26-84](file://internal/handler/device.go#L26-L84)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
|
|
|
|
|
|
### 中间件链路分析(序列图)
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
sequenceDiagram
|
|
|
|
|
|
participant Client as "客户端"
|
|
|
|
|
|
participant Engine as "Gin 引擎"
|
|
|
|
|
|
participant Recovery as "Recovery"
|
|
|
|
|
|
participant ReqID as "RequestID"
|
|
|
|
|
|
participant Logger as "Logger"
|
|
|
|
|
|
participant CORS as "CORS"
|
|
|
|
|
|
participant Handler as "处理器"
|
|
|
|
|
|
Client->>Engine : "请求"
|
|
|
|
|
|
Engine->>Recovery : "进入"
|
|
|
|
|
|
Recovery->>ReqID : "继续"
|
|
|
|
|
|
ReqID->>Logger : "继续"
|
|
|
|
|
|
Logger->>CORS : "继续"
|
|
|
|
|
|
CORS->>Handler : "匹配路由并调用"
|
|
|
|
|
|
Handler-->>Engine : "写入响应"
|
|
|
|
|
|
Engine-->>Client : "响应"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-05-28 15:30:05 +08:00
|
|
|
|
**图表来源**
|
|
|
|
|
|
- [router.go:18-21](file://internal/router/router.go#L18-L21)
|
2026-05-27 18:07:55 +08:00
|
|
|
|
- [logger.go:16](file://internal/middleware/logger.go#L16)
|
|
|
|
|
|
- [request_id.go:28](file://internal/middleware/request_id.go#L28)
|
2026-05-28 15:30:05 +08:00
|
|
|
|
- [cors.go:18](file://internal/middleware/cors.go#L18)
|
|
|
|
|
|
|
|
|
|
|
|
### 依赖注入链路图
|
|
|
|
|
|
```mermaid
|
|
|
|
|
|
graph TB
|
|
|
|
|
|
subgraph "应用启动"
|
|
|
|
|
|
MAIN["cmd/server/main.go<br/>warmUpCache()"]
|
|
|
|
|
|
ENDSUBGRAPH
|
|
|
|
|
|
subgraph "路由工厂"
|
|
|
|
|
|
ROUTER["internal/router/router.go<br/>New()"]
|
|
|
|
|
|
ENDSUBGRAPH
|
|
|
|
|
|
subgraph "缓存层"
|
|
|
|
|
|
BC["BrandCache<br/>brand:all"]
|
|
|
|
|
|
MC["ModelCache<br/>model:brand:, model:all"]
|
|
|
|
|
|
ENDSUBGRAPH
|
|
|
|
|
|
subgraph "仓库层"
|
|
|
|
|
|
BR["BrandRepository<br/>缓存+数据库"]
|
|
|
|
|
|
MR["ModelRepository<br/>缓存+数据库"]
|
|
|
|
|
|
ENDSUBGRAPH
|
|
|
|
|
|
subgraph "处理器层"
|
|
|
|
|
|
HH["HealthHandler"]
|
|
|
|
|
|
BH["BrandHandler"]
|
|
|
|
|
|
MH["ModelHandler"]
|
|
|
|
|
|
MLH["ModelListHandler"]
|
|
|
|
|
|
DH["DeviceHandler"]
|
|
|
|
|
|
ENDSUBGRAPH
|
|
|
|
|
|
MAIN --> BC
|
|
|
|
|
|
MAIN --> MC
|
|
|
|
|
|
MAIN --> BR
|
|
|
|
|
|
MAIN --> MR
|
|
|
|
|
|
ROUTER --> BC
|
|
|
|
|
|
ROUTER --> MC
|
|
|
|
|
|
ROUTER --> BR
|
|
|
|
|
|
ROUTER --> MR
|
|
|
|
|
|
ROUTER --> BH
|
|
|
|
|
|
ROUTER --> MH
|
|
|
|
|
|
ROUTER --> MLH
|
|
|
|
|
|
ROUTER --> DH
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**图表来源**
|
|
|
|
|
|
- [main.go:103-130](file://cmd/server/main.go#L103-L130)
|
|
|
|
|
|
- [router.go:23-36](file://internal/router/router.go#L23-L36)
|
|
|
|
|
|
- [brand_cache.go:18-44](file://internal/cache/brand_cache.go#L18-L44)
|
|
|
|
|
|
- [model_cache.go:19-69](file://internal/cache/model_cache.go#L19-L69)
|
|
|
|
|
|
- [brand.go:14-52](file://internal/repository/brand.go#L14-L52)
|
|
|
|
|
|
- [model.go:14-79](file://internal/repository/model.go#L14-L79)
|