513 lines
27 KiB
Markdown
513 lines
27 KiB
Markdown
# 核心模块
|
||
|
||
<cite>
|
||
**本文引用的文件**
|
||
- [cmd/server/main.go](file://cmd/server/main.go)
|
||
- [internal/router/router.go](file://internal/router/router.go)
|
||
- [internal/config/config.go](file://internal/config/config.go)
|
||
- [internal/database/mysql.go](file://internal/database/mysql.go)
|
||
- [internal/cache/redis.go](file://internal/cache/redis.go)
|
||
- [internal/handler/brand.go](file://internal/handler/brand.go)
|
||
- [internal/handler/model.go](file://internal/handler/model.go)
|
||
- [internal/handler/model_list.go](file://internal/handler/model_list.go)
|
||
- [internal/handler/device.go](file://internal/handler/device.go)
|
||
- [internal/handler/health.go](file://internal/handler/health.go)
|
||
- [internal/repository/brand.go](file://internal/repository/brand.go)
|
||
- [internal/repository/model.go](file://internal/repository/model.go)
|
||
- [internal/model/brand.go](file://internal/model/brand.go)
|
||
- [internal/model/model.go](file://internal/model/model.go)
|
||
- [internal/response/response.go](file://internal/response/response.go)
|
||
- [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
|
||
- [pkg/encode/base64.go](file://pkg/encode/base64.go)
|
||
- [pkg/logger/logger.go](file://pkg/logger/logger.go)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [简介](#简介)
|
||
2. [项目结构](#项目结构)
|
||
3. [核心组件](#核心组件)
|
||
4. [架构总览](#架构总览)
|
||
5. [详细组件分析](#详细组件分析)
|
||
6. [依赖分析](#依赖分析)
|
||
7. [性能考量](#性能考量)
|
||
8. [故障排查指南](#故障排查指南)
|
||
9. [结论](#结论)
|
||
10. [附录](#附录)
|
||
|
||
## 简介
|
||
本文件围绕 Luxsin 应用 API 的核心模块进行系统化文档化,重点覆盖以下方面:
|
||
- 业务处理器(Handler):负责接收请求、解析参数、调用仓库层、封装统一响应。
|
||
- 数据访问层(Repository):负责与数据库交互,执行查询与扫描逻辑。
|
||
- 数据模型(Model):定义持久化与对外传输的数据结构。
|
||
- 统一响应(Response):规范 HTTP 响应体格式,提供便捷的构造方法。
|
||
- 依赖注入与启动流程:从配置加载到服务启动、中间件装配、路由注册与资源管理。
|
||
- 错误处理与日志记录:在各层中的一致性错误处理与可观测性。
|
||
- 扩展最佳实践:如何新增模块、如何复用编码器、如何接入缓存与搜索引擎。
|
||
- 性能优化与并发安全:连接池、超时控制、上下文传播、Redis 并发安全。
|
||
|
||
## 项目结构
|
||
项目采用分层与按功能域组织的结构:
|
||
- cmd/server:应用入口,负责配置加载、外部依赖初始化、HTTP 服务器启动与优雅关闭。
|
||
- internal/config:集中式配置加载与校验。
|
||
- internal/database:数据库连接与连接池配置。
|
||
- internal/cache:Redis 客户端初始化。
|
||
- internal/search:搜索引擎客户端封装。
|
||
- internal/router:路由注册与中间件装配。
|
||
- internal/handler:业务处理器,面向具体 API 路由。
|
||
- internal/repository:数据访问层,封装 SQL 查询。
|
||
- internal/model:领域模型与传输模型。
|
||
- internal/response:统一响应体封装。
|
||
- pkg/*:通用工具包(如编码器、日志)。
|
||
|
||
```mermaid
|
||
graph TB
|
||
subgraph "入口与配置"
|
||
MAIN["cmd/server/main.go<br/>应用入口"]
|
||
CFG["internal/config/config.go<br/>配置加载"]
|
||
end
|
||
subgraph "基础设施"
|
||
DB["internal/database/mysql.go<br/>MySQL 连接与池"]
|
||
RDS["internal/cache/redis.go<br/>Redis 客户端"]
|
||
SRCH["internal/search/meilisearch.go<br/>搜索引擎客户端"]
|
||
LOG["pkg/logger/logger.go<br/>日志"]
|
||
end
|
||
subgraph "服务编排"
|
||
RT["internal/router/router.go<br/>路由与中间件"]
|
||
end
|
||
subgraph "业务层"
|
||
H_BRAND["internal/handler/brand.go<br/>品牌处理器"]
|
||
H_MODEL["internal/handler/model.go<br/>型号处理器"]
|
||
H_MLIST["internal/handler/model_list.go<br/>型号搜索处理器"]
|
||
H_DEV["internal/handler/device.go<br/>设备上报处理器"]
|
||
H_HEALTH["internal/handler/health.go<br/>健康检查处理器"]
|
||
end
|
||
subgraph "数据访问与模型"
|
||
REPO_BRAND["internal/repository/brand.go<br/>品牌仓库"]
|
||
REPO_MODEL["internal/repository/model.go<br/>型号仓库"]
|
||
MODEL_BRAND["internal/model/brand.go<br/>品牌模型"]
|
||
MODEL_MODEL["internal/model/model.go<br/>型号模型"]
|
||
RESP["internal/response/response.go<br/>统一响应"]
|
||
ENC["pkg/encode/base64.go<br/>Base64 编码器"]
|
||
end
|
||
MAIN --> CFG
|
||
MAIN --> DB
|
||
MAIN --> RDS
|
||
MAIN --> SRCH
|
||
MAIN --> LOG
|
||
MAIN --> RT
|
||
RT --> H_HEALTH
|
||
RT --> H_BRAND
|
||
RT --> H_MODEL
|
||
RT --> H_MLIST
|
||
RT --> H_DEV
|
||
H_BRAND --> REPO_BRAND
|
||
H_MODEL --> REPO_MODEL
|
||
H_MLIST --> SRCH
|
||
H_DEV --> RDS
|
||
REPO_BRAND --> DB
|
||
REPO_MODEL --> DB
|
||
H_BRAND --> RESP
|
||
H_MODEL --> RESP
|
||
H_MLIST --> RESP
|
||
H_HEALTH --> RESP
|
||
H_BRAND --> ENC
|
||
H_MODEL --> ENC
|
||
H_MLIST --> ENC
|
||
```
|
||
|
||
图表来源
|
||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
- [internal/config/config.go:18-64](file://internal/config/config.go#L18-L64)
|
||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||
- [internal/handler/brand.go:19-49](file://internal/handler/brand.go#L19-L49)
|
||
- [internal/handler/model.go:19-50](file://internal/handler/model.go#L19-L50)
|
||
- [internal/handler/model_list.go:19-56](file://internal/handler/model_list.go#L19-L56)
|
||
- [internal/handler/device.go:19-84](file://internal/handler/device.go#L19-L84)
|
||
- [internal/handler/health.go:10-18](file://internal/handler/health.go#L10-L18)
|
||
- [internal/repository/brand.go:16-50](file://internal/repository/brand.go#L16-L50)
|
||
- [internal/repository/model.go:16-94](file://internal/repository/model.go#L16-L94)
|
||
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
|
||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||
- [internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
|
||
- [pkg/encode/base64.go](file://pkg/encode/base64.go)
|
||
|
||
章节来源
|
||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
|
||
## 核心组件
|
||
本节聚焦 Handler、Repository、Model、Response 四大核心模块的职责、协作方式与实现要点。
|
||
|
||
- Handler(业务处理器)
|
||
- 职责:解析请求参数、调用仓库或外部服务、封装统一响应;必要时进行参数校验与基础编码处理。
|
||
- 典型实现位置:
|
||
- 品牌列表:[internal/handler/brand.go:26-49](file://internal/handler/brand.go#L26-L49)
|
||
- 型号列表:[internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50)
|
||
- 型号搜索:[internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||
- 设备上报:[internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84)
|
||
- 健康检查:[internal/handler/health.go:14-18](file://internal/handler/health.go#L14-L18)
|
||
|
||
- Repository(数据访问层)
|
||
- 职责:封装 SQL 查询、参数拼装、结果扫描与错误包装;支持上下文传播与超时控制。
|
||
- 典型实现位置:
|
||
- 品牌仓库:[internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50)
|
||
- 型号仓库:[internal/repository/model.go:20-94](file://internal/repository/model.go#L20-L94)
|
||
|
||
- Model(数据模型)
|
||
- 职责:定义数据库字段映射与 JSON 序列化字段名;可选字段使用指针以区分空值与缺省。
|
||
- 典型实现位置:
|
||
- 品牌模型:[internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
|
||
- 型号模型:[internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||
|
||
- Response(统一响应)
|
||
- 职责:统一响应体结构与常用状态构造方法,保证前后端契约一致。
|
||
- 典型实现位置:
|
||
- 统一响应:[internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
|
||
|
||
章节来源
|
||
- [internal/handler/brand.go:19-49](file://internal/handler/brand.go#L19-L49)
|
||
- [internal/handler/model.go:19-50](file://internal/handler/model.go#L19-L50)
|
||
- [internal/handler/model_list.go:19-56](file://internal/handler/model_list.go#L19-L56)
|
||
- [internal/handler/device.go:19-84](file://internal/handler/device.go#L19-L84)
|
||
- [internal/handler/health.go:10-18](file://internal/handler/health.go#L10-L18)
|
||
- [internal/repository/brand.go:16-50](file://internal/repository/brand.go#L16-L50)
|
||
- [internal/repository/model.go:16-94](file://internal/repository/model.go#L16-L94)
|
||
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
|
||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||
- [internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
|
||
|
||
## 架构总览
|
||
下图展示从请求进入至响应返回的关键路径,以及各层之间的依赖关系与调用方向。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant C as "客户端"
|
||
participant G as "Gin 路由<br/>internal/router/router.go"
|
||
participant H as "业务处理器<br/>internal/handler/*"
|
||
participant R as "仓库层<br/>internal/repository/*"
|
||
participant DB as "数据库<br/>internal/database/mysql.go"
|
||
participant S as "搜索引擎<br/>internal/search/meilisearch.go"
|
||
participant RC as "Redis<br/>internal/cache/redis.go"
|
||
participant RESP as "统一响应<br/>internal/response/response.go"
|
||
C->>G : "HTTP 请求"
|
||
G->>H : "匹配路由并调用处理器"
|
||
alt "品牌/型号列表"
|
||
H->>R : "调用仓库查询"
|
||
R->>DB : "执行 SQL 查询"
|
||
DB-->>R : "返回结果集"
|
||
R-->>H : "返回模型切片"
|
||
else "型号搜索"
|
||
H->>S : "调用搜索引擎"
|
||
S-->>H : "返回搜索结果"
|
||
else "设备上报"
|
||
H->>RC : "写入 Redis Hash"
|
||
RC-->>H : "返回写入结果"
|
||
end
|
||
H->>RESP : "构造统一响应"
|
||
RESP-->>C : "HTTP 响应"
|
||
```
|
||
|
||
图表来源
|
||
- [internal/router/router.go:21-38](file://internal/router/router.go#L21-L38)
|
||
- [internal/handler/brand.go:30-35](file://internal/handler/brand.go#L30-L35)
|
||
- [internal/handler/model.go:31-36](file://internal/handler/model.go#L31-L36)
|
||
- [internal/handler/model_list.go:37-42](file://internal/handler/model_list.go#L37-L42)
|
||
- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
|
||
- [internal/repository/brand.go:31-35](file://internal/repository/brand.go#L31-L35)
|
||
- [internal/repository/model.go:42-46](file://internal/repository/model.go#L42-L46)
|
||
- [internal/response/response.go:15-21](file://internal/response/response.go#L15-L21)
|
||
|
||
## 详细组件分析
|
||
|
||
### Handler 层
|
||
- 品牌处理器(BrandHandler)
|
||
- 关键点:读取查询参数、调用仓库、错误日志与统一错误响应、可选 Base64 响应。
|
||
- 参考路径:[internal/handler/brand.go:26-49](file://internal/handler/brand.go#L26-L49)
|
||
- 型号处理器(ModelHandler)
|
||
- 关键点:多条件查询(品牌/名称模糊)、上下文传播、统一响应与错误处理。
|
||
- 参考路径:[internal/handler/model.go:26-50](file://internal/handler/model.go#L26-L50)
|
||
- 型号搜索处理器(ModelListHandler)
|
||
- 关键点:搜索引擎客户端调用、count 参数限制、统一响应。
|
||
- 参考路径:[internal/handler/model_list.go:26-56](file://internal/handler/model_list.go#L26-L56)
|
||
- 设备上报处理器(DeviceHandler)
|
||
- 关键点:参数校验、日志记录、Redis Hash 写入、错误处理。
|
||
- 参考路径:[internal/handler/device.go:26-84](file://internal/handler/device.go#L26-L84)
|
||
- 健康检查处理器(HealthHandler)
|
||
- 关键点:简单响应,使用统一响应体。
|
||
- 参考路径:[internal/handler/health.go:14-18](file://internal/handler/health.go#L14-L18)
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class BrandHandler {
|
||
-repo : BrandRepository
|
||
-log : Logger
|
||
+GetBrand(c)
|
||
}
|
||
class ModelHandler {
|
||
-repo : ModelRepository
|
||
-log : Logger
|
||
+GetModel(c)
|
||
}
|
||
class ModelListHandler {
|
||
-search : SearchClient
|
||
-log : Logger
|
||
+ModelList(c)
|
||
}
|
||
class DeviceHandler {
|
||
-redis : RedisClient
|
||
-log : Logger
|
||
+ReportDevInfo(c)
|
||
}
|
||
class HealthHandler {
|
||
+Check(c)
|
||
}
|
||
BrandHandler --> BrandRepository : "依赖"
|
||
ModelHandler --> ModelRepository : "依赖"
|
||
ModelListHandler --> SearchClient : "依赖"
|
||
DeviceHandler --> RedisClient : "依赖"
|
||
```
|
||
|
||
图表来源
|
||
- [internal/handler/brand.go:14-24](file://internal/handler/brand.go#L14-L24)
|
||
- [internal/handler/model.go:14-24](file://internal/handler/model.go#L14-L24)
|
||
- [internal/handler/model_list.go:14-24](file://internal/handler/model_list.go#L14-L24)
|
||
- [internal/handler/device.go:14-24](file://internal/handler/device.go#L14-L24)
|
||
- [internal/handler/health.go:8-12](file://internal/handler/health.go#L8-L12)
|
||
|
||
章节来源
|
||
- [internal/handler/brand.go:19-49](file://internal/handler/brand.go#L19-L49)
|
||
- [internal/handler/model.go:19-50](file://internal/handler/model.go#L19-L50)
|
||
- [internal/handler/model_list.go:19-56](file://internal/handler/model_list.go#L19-L56)
|
||
- [internal/handler/device.go:19-84](file://internal/handler/device.go#L19-L84)
|
||
- [internal/handler/health.go:10-18](file://internal/handler/health.go#L10-L18)
|
||
|
||
### Repository 层
|
||
- 品牌仓库(BrandRepository)
|
||
- 关键点:条件查询、排序、结果扫描。
|
||
- 参考路径:[internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50)
|
||
- 型号仓库(ModelRepository)
|
||
- 关键点:多条件拼装、LIKE 模糊匹配、NullString 处理、上下文传播。
|
||
- 参考路径:[internal/repository/model.go:20-94](file://internal/repository/model.go#L20-L94)
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class BrandRepository {
|
||
-db : sql.DB
|
||
+List(ctx, brandName) []Brand
|
||
}
|
||
class ModelRepository {
|
||
-db : sql.DB
|
||
+List(ctx, brandName, modelName) []Model
|
||
}
|
||
class Brand {
|
||
+id : int
|
||
+name : string
|
||
}
|
||
class Model {
|
||
+id : int
|
||
+brandName : string
|
||
+name : string
|
||
+form : *string
|
||
+rig : *string
|
||
+source : *string
|
||
+eqKey : *string
|
||
+createAt : time
|
||
}
|
||
BrandRepository --> Brand : "返回"
|
||
ModelRepository --> Model : "返回"
|
||
```
|
||
|
||
图表来源
|
||
- [internal/repository/brand.go:12-50](file://internal/repository/brand.go#L12-L50)
|
||
- [internal/repository/model.go:12-94](file://internal/repository/model.go#L12-L94)
|
||
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
|
||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||
|
||
章节来源
|
||
- [internal/repository/brand.go:16-50](file://internal/repository/brand.go#L16-L50)
|
||
- [internal/repository/model.go:16-94](file://internal/repository/model.go#L16-L94)
|
||
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
|
||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||
|
||
### Model 层
|
||
- 品牌模型(Brand)
|
||
- 字段:id、name
|
||
- 参考路径:[internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
|
||
- 型号模型(Model)
|
||
- 字段:id、brandName、name、form、rig、source、eqKey、createAt(可选字段使用指针)
|
||
- 参考路径:[internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||
|
||
章节来源
|
||
- [internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6)
|
||
- [internal/model/model.go:5-14](file://internal/model/model.go#L5-L14)
|
||
|
||
### Response 层
|
||
- 统一响应体(Body)
|
||
- 字段:code、message、data
|
||
- 方法:OK、Fail、BadRequest、InternalError
|
||
- 参考路径:[internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
Start(["进入处理器"]) --> Build["构造响应体<br/>OK/Fail/BadRequest/InternalError"]
|
||
Build --> Send["通过 Gin 写入 HTTP 响应"]
|
||
Send --> End(["完成"])
|
||
```
|
||
|
||
图表来源
|
||
- [internal/response/response.go:15-36](file://internal/response/response.go#L15-L36)
|
||
|
||
章节来源
|
||
- [internal/response/response.go:9-36](file://internal/response/response.go#L9-L36)
|
||
|
||
### 编码与日志
|
||
- Base64 编码器(pkg/encode/base64.go)
|
||
- 用途:在处理器中对响应进行 Base64 编码后输出字符串。
|
||
- 使用场景:品牌与型号列表的可选 Base64 输出。
|
||
- 参考路径:[internal/handler/brand.go:37-44](file://internal/handler/brand.go#L37-L44),[internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47),[internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
|
||
- 日志(pkg/logger/logger.go)
|
||
- 用途:全局日志初始化与结构化日志记录。
|
||
- 参考路径:[cmd/server/main.go:32-36](file://cmd/server/main.go#L32-L36),[internal/handler/brand.go:32-34](file://internal/handler/brand.go#L32-L34),[internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35),[internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41),[internal/handler/device.go:47-49](file://internal/handler/device.go#L47-L49),[internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
|
||
|
||
章节来源
|
||
- [internal/handler/brand.go:37-44](file://internal/handler/brand.go#L37-L44)
|
||
- [internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47)
|
||
- [internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
|
||
- [cmd/server/main.go:32-36](file://cmd/server/main.go#L32-L36)
|
||
- [internal/handler/brand.go:32-34](file://internal/handler/brand.go#L32-L34)
|
||
- [internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35)
|
||
- [internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41)
|
||
- [internal/handler/device.go:47-49](file://internal/handler/device.go#L47-L49)
|
||
- [internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
|
||
|
||
## 依赖分析
|
||
- 启动与依赖注入
|
||
- 配置加载:[internal/config/config.go:18-64](file://internal/config/config.go#L18-L64)
|
||
- 数据库连接与池:[internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||
- Redis 客户端:[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-95](file://cmd/server/main.go#L22-L95)
|
||
|
||
- 处理器与仓库的依赖
|
||
- 品牌处理器依赖品牌仓库:[internal/handler/brand.go:19-23](file://internal/handler/brand.go#L19-L23) → [internal/repository/brand.go:16](file://internal/repository/brand.go#L16)
|
||
- 型号处理器依赖型号仓库:[internal/handler/model.go:19-23](file://internal/handler/model.go#L19-L23) → [internal/repository/model.go:16](file://internal/repository/model.go#L16)
|
||
- 型号搜索处理器依赖搜索引擎客户端:[internal/handler/model_list.go:19-23](file://internal/handler/model_list.go#L19-L23) → [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
|
||
- 设备上报处理器依赖 Redis 客户端:[internal/handler/device.go:19-23](file://internal/handler/device.go#L19-L23) → [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||
|
||
```mermaid
|
||
graph LR
|
||
MAIN["cmd/server/main.go"] --> CFG["internal/config/config.go"]
|
||
MAIN --> DB["internal/database/mysql.go"]
|
||
MAIN --> RDS["internal/cache/redis.go"]
|
||
MAIN --> RT["internal/router/router.go"]
|
||
RT --> H_BRAND["internal/handler/brand.go"]
|
||
RT --> H_MODEL["internal/handler/model.go"]
|
||
RT --> H_MLIST["internal/handler/model_list.go"]
|
||
RT --> H_DEV["internal/handler/device.go"]
|
||
H_BRAND --> REPO_BRAND["internal/repository/brand.go"]
|
||
H_MODEL --> REPO_MODEL["internal/repository/model.go"]
|
||
H_MLIST --> SRCH["internal/search/meilisearch.go"]
|
||
H_DEV --> RDS
|
||
REPO_BRAND --> DB
|
||
REPO_MODEL --> DB
|
||
```
|
||
|
||
图表来源
|
||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||
- [internal/router/router.go:21-38](file://internal/router/router.go#L21-L38)
|
||
- [internal/handler/brand.go:19-23](file://internal/handler/brand.go#L19-L23)
|
||
- [internal/handler/model.go:19-23](file://internal/handler/model.go#L19-L23)
|
||
- [internal/handler/model_list.go:19-23](file://internal/handler/model_list.go#L19-L23)
|
||
- [internal/handler/device.go:19-23](file://internal/handler/device.go#L19-L23)
|
||
- [internal/repository/brand.go:16](file://internal/repository/brand.go#L16)
|
||
- [internal/repository/model.go:16](file://internal/repository/model.go#L16)
|
||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||
|
||
章节来源
|
||
- [cmd/server/main.go:22-95](file://cmd/server/main.go#L22-L95)
|
||
- [internal/router/router.go:14-41](file://internal/router/router.go#L14-L41)
|
||
- [internal/handler/brand.go:19-23](file://internal/handler/brand.go#L19-L23)
|
||
- [internal/handler/model.go:19-23](file://internal/handler/model.go#L19-L23)
|
||
- [internal/handler/model_list.go:19-23](file://internal/handler/model_list.go#L19-L23)
|
||
- [internal/handler/device.go:19-23](file://internal/handler/device.go#L19-L23)
|
||
- [internal/repository/brand.go:16](file://internal/repository/brand.go#L16)
|
||
- [internal/repository/model.go:16](file://internal/repository/model.go#L16)
|
||
- [internal/database/mysql.go:14-46](file://internal/database/mysql.go#L14-L46)
|
||
- [internal/cache/redis.go:10-16](file://internal/cache/redis.go#L10-L16)
|
||
|
||
## 性能考量
|
||
- 数据库连接与池
|
||
- 最大并发连接数、最大空闲连接数、连接生命周期设置,有助于避免连接争用与资源泄漏。
|
||
- 参考路径:[internal/database/mysql.go:33-35](file://internal/database/mysql.go#L33-L35)
|
||
- 上下文与超时
|
||
- 仓库层使用 QueryContext 与 PingContext,确保超时控制与取消传播。
|
||
- 参考路径:[internal/repository/model.go:42-46](file://internal/repository/model.go#L42-L46),[internal/database/mysql.go:37-43](file://internal/database/mysql.go#L37-L43)
|
||
- Redis 并发安全
|
||
- 单个 Redis 客户端实例在 Go 中是并发安全的,可在多个 goroutine 中共享。
|
||
- 参考路径:[internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
|
||
- 响应体积与 Base64
|
||
- 对于大列表响应,可启用 Base64 输出以减少传输体积,但会增加 CPU 开销。
|
||
- 参考路径:[internal/handler/brand.go:37-44](file://internal/handler/branch.go#L37-L44),[internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47),[internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
|
||
- 搜索性能
|
||
- 搜索结果数量限制(count)可有效控制响应规模,避免过量数据传输。
|
||
- 参考路径:[internal/handler/model_list.go:30-35](file://internal/handler/model_list.go#L30-L35)
|
||
|
||
章节来源
|
||
- [internal/database/mysql.go:33-35](file://internal/database/mysql.go#L33-L35)
|
||
- [internal/repository/model.go:42-46](file://internal/repository/model.go#L42-L46)
|
||
- [internal/database/mysql.go:37-43](file://internal/database/mysql.go#L37-L43)
|
||
- [internal/handler/device.go:70-78](file://internal/handler/device.go#L70-L78)
|
||
- [internal/handler/brand.go:37-44](file://internal/handler/brand.go#L37-L44)
|
||
- [internal/handler/model.go:38-47](file://internal/handler/model.go#L38-L47)
|
||
- [internal/handler/model_list.go:30-35](file://internal/handler/model_list.go#L30-L35)
|
||
- [internal/handler/model_list.go:44-53](file://internal/handler/model_list.go#L44-L53)
|
||
|
||
## 故障排查指南
|
||
- 常见错误类型与处理
|
||
- 数据库查询失败:在仓库层包装错误并在处理器记录日志与返回统一错误响应。
|
||
- 参考路径:[internal/repository/model.go:43-44](file://internal/repository/model.go#L43-L44),[internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35)
|
||
- 编码失败:在处理器捕获编码错误并返回统一错误响应。
|
||
- 参考路径:[internal/handler/brand.go:40-43](file://internal/handler/brand.go#L40-L43),[internal/handler/model.go:40-43](file://internal/handler/model.go#L40-L43)
|
||
- Redis 写入失败:记录错误并返回统一错误响应。
|
||
- 参考路径:[internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
|
||
- 搜索失败:记录错误并返回统一错误响应。
|
||
- 参考路径:[internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41)
|
||
- 日志定位
|
||
- 使用结构化日志记录关键上下文(如远程 IP、时间戳),便于问题追踪。
|
||
- 参考路径:[internal/handler/device.go:47-50](file://internal/handler/device.go#L47-L50)
|
||
|
||
章节来源
|
||
- [internal/repository/model.go:43-44](file://internal/repository/model.go#L43-L44)
|
||
- [internal/handler/model.go:33-35](file://internal/handler/model.go#L33-L35)
|
||
- [internal/handler/brand.go:40-43](file://internal/handler/brand.go#L40-L43)
|
||
- [internal/handler/model.go:40-43](file://internal/handler/model.go#L40-L43)
|
||
- [internal/handler/device.go:71-77](file://internal/handler/device.go#L71-L77)
|
||
- [internal/handler/model_list.go:39-41](file://internal/handler/model_list.go#L39-L41)
|
||
- [internal/handler/device.go:47-50](file://internal/handler/device.go#L47-L50)
|
||
|
||
## 结论
|
||
本项目通过清晰的分层与职责分离,实现了可维护、可扩展且具备良好性能特征的 API 服务:
|
||
- Handler 专注于业务编排与响应封装;
|
||
- Repository 将数据访问细节抽象化;
|
||
- Model 明确数据契约;
|
||
- Response 提供统一的对外接口;
|
||
- 配合中间件、日志与统一错误处理,形成完整的可观测与可诊断体系;
|
||
- 在数据库连接池、上下文超时、Redis 并发安全与可选 Base64 响应等方面体现了工程化细节。
|
||
|
||
## 附录
|
||
- 扩展新模块的最佳实践
|
||
- 新增处理器:在 internal/handler 下创建处理器文件,定义结构体与依赖注入函数,实现业务方法并调用仓库或外部服务。
|
||
- 参考路径:[internal/handler/brand.go:19-24](file://internal/handler/brand.go#L19-L24),[internal/handler/model.go:19-24](file://internal/handler/model.go#L19-L24)
|
||
- 新增仓库:在 internal/repository 下创建仓库文件,实现查询方法、参数拼装与结果扫描,使用上下文与错误包装。
|
||
- 参考路径:[internal/repository/brand.go:20-50](file://internal/repository/brand.go#L20-L50),[internal/repository/model.go:20-94](file://internal/repository/model.go#L20-L94)
|
||
- 新增模型:在 internal/model 下定义结构体,注意可选字段使用指针;在仓库扫描函数中正确映射 NullString。
|
||
- 参考路径:[internal/model/brand.go:3-6](file://internal/model/brand.go#L3-L6),[internal/model/model.go:5-14](file://internal/model/model.go#L5-L14),[internal/repository/model.go:63-86](file://internal/repository/model.go#L63-L86)
|
||
- 统一响应:优先使用 internal/response 提供的方法,保持前后端一致性。
|
||
- 参考路径:[internal/response/response.go:15-36](file://internal/response/response.go#L15-L36)
|
||
- 参数与编码:利用 pkg/encode/base64.go 实现可选的 Base64 响应;在处理器中进行必要的参数校验与日志记录。
|
||
- 参考路径:[internal/handler/brand.go:27-29](file://internal/handler/brand.go#L27-L29),[internal/handler/model.go:27-29](file://internal/handler/model.go#L27-L29),[internal/handler/model_list.go:26-28](file://internal/handler/model_list.go#L26-L28),[pkg/encode/base64.go](file://pkg/encode/base64.go)
|
||
- 资源管理:在入口程序中集中初始化外部依赖(数据库、Redis、搜索引擎),并在退出时优雅关闭。
|
||
- 参考路径:[cmd/server/main.go:38-62](file://cmd/server/main.go#L38-L62),[cmd/server/main.go:87-94](file://cmd/server/main.go#L87-L94) |