383 lines
20 KiB
Markdown
383 lines
20 KiB
Markdown
|
|
# 组件交互机制
|
|||
|
|
|
|||
|
|
<cite>
|
|||
|
|
**本文引用的文件**
|
|||
|
|
- [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/handler/model_list.go](file://internal/handler/model_list.go)
|
|||
|
|
- [internal/repository/model.go](file://internal/repository/model.go)
|
|||
|
|
- [internal/repository/brand.go](file://internal/repository/brand.go)
|
|||
|
|
- [internal/database/mysql.go](file://internal/database/mysql.go)
|
|||
|
|
- [internal/search/meilisearch.go](file://internal/search/meilisearch.go)
|
|||
|
|
- [internal/cache/redis.go](file://internal/cache/redis.go)
|
|||
|
|
- [internal/response/response.go](file://internal/response/response.go)
|
|||
|
|
- [internal/middleware/logger.go](file://internal/middleware/logger.go)
|
|||
|
|
- [internal/middleware/request_id.go](file://internal/middleware/request_id.go)
|
|||
|
|
- [pkg/encode/base64.go](file://pkg/encode/base64.go)
|
|||
|
|
</cite>
|
|||
|
|
|
|||
|
|
## 目录
|
|||
|
|
1. [简介](#简介)
|
|||
|
|
2. [项目结构](#项目结构)
|
|||
|
|
3. [核心组件](#核心组件)
|
|||
|
|
4. [架构总览](#架构总览)
|
|||
|
|
5. [详细组件分析](#详细组件分析)
|
|||
|
|
6. [依赖关系分析](#依赖关系分析)
|
|||
|
|
7. [性能考量](#性能考量)
|
|||
|
|
8. [故障排查指南](#故障排查指南)
|
|||
|
|
9. [结论](#结论)
|
|||
|
|
10. [附录](#附录)
|
|||
|
|
|
|||
|
|
## 简介
|
|||
|
|
本文件面向 Luxsin 应用 API 项目,系统性梳理从请求接收到响应返回的完整数据流路径,重点覆盖 Router → Handler → Repository → Database 的调用链路与参数传递;解释各组件间的解耦机制与接口设计原则;文档化错误传播机制与异常处理策略;提供组件交互的时序图与数据流图;说明异步处理与并发控制的实现方式,并给出性能优化与监控建议。
|
|||
|
|
|
|||
|
|
## 项目结构
|
|||
|
|
该项目采用分层与按功能域组织的混合结构:
|
|||
|
|
- 入口层:cmd/server/main.go 负责配置加载、服务启动与优雅停机。
|
|||
|
|
- 路由层:internal/router/router.go 定义路由组与中间件栈。
|
|||
|
|
- 处理器层:internal/handler/* 提供业务端点逻辑,负责参数解析、调用仓库与外部服务、封装响应。
|
|||
|
|
- 仓储层:internal/repository/* 实现数据库访问与查询封装。
|
|||
|
|
- 数据库层:internal/database/mysql.go 提供 MySQL 连接与连接池配置。
|
|||
|
|
- 搜索层:internal/search/meilisearch.go 封装 Meilisearch 客户端。
|
|||
|
|
- 缓存层:internal/cache/redis.go 封装 Redis 客户端。
|
|||
|
|
- 响应与编码:internal/response/response.go、pkg/encode/base64.go 提供统一响应体与可选的自定义 Base64 编码。
|
|||
|
|
- 中间件:internal/middleware/* 提供日志、CORS、请求 ID 等横切能力。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
graph TB
|
|||
|
|
subgraph "入口"
|
|||
|
|
MAIN["cmd/server/main.go"]
|
|||
|
|
end
|
|||
|
|
subgraph "路由与中间件"
|
|||
|
|
ROUTER["internal/router/router.go"]
|
|||
|
|
MID_REQ["internal/middleware/request_id.go"]
|
|||
|
|
MID_LOG["internal/middleware/logger.go"]
|
|||
|
|
end
|
|||
|
|
subgraph "处理器"
|
|||
|
|
H_BRAND["internal/handler/brand.go"]
|
|||
|
|
H_MODEL["internal/handler/model.go"]
|
|||
|
|
H_MODEL_LIST["internal/handler/model_list.go"]
|
|||
|
|
H_DEVICE["internal/handler/device.go"]
|
|||
|
|
end
|
|||
|
|
subgraph "仓储"
|
|||
|
|
R_BRAND["internal/repository/brand.go"]
|
|||
|
|
R_MODEL["internal/repository/model.go"]
|
|||
|
|
end
|
|||
|
|
subgraph "数据库/搜索/缓存"
|
|||
|
|
DB["internal/database/mysql.go"]
|
|||
|
|
MS["internal/search/meilisearch.go"]
|
|||
|
|
RD["internal/cache/redis.go"]
|
|||
|
|
end
|
|||
|
|
RESP["internal/response/response.go"]
|
|||
|
|
ENC["pkg/encode/base64.go"]
|
|||
|
|
MAIN --> ROUTER
|
|||
|
|
ROUTER --> MID_REQ
|
|||
|
|
ROUTER --> MID_LOG
|
|||
|
|
ROUTER --> H_BRAND
|
|||
|
|
ROUTER --> H_MODEL
|
|||
|
|
ROUTER --> H_MODEL_LIST
|
|||
|
|
ROUTER --> H_DEVICE
|
|||
|
|
H_BRAND --> R_BRAND
|
|||
|
|
H_MODEL --> R_MODEL
|
|||
|
|
H_MODEL_LIST --> MS
|
|||
|
|
H_DEVICE --> RD
|
|||
|
|
R_BRAND --> DB
|
|||
|
|
R_MODEL --> DB
|
|||
|
|
H_BRAND --> RESP
|
|||
|
|
H_MODEL --> RESP
|
|||
|
|
H_MODEL_LIST --> RESP
|
|||
|
|
H_DEVICE --> RESP
|
|||
|
|
H_BRAND --> ENC
|
|||
|
|
H_MODEL --> ENC
|
|||
|
|
H_MODEL_LIST --> ENC
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96)
|
|||
|
|
- [internal/router/router.go:1-42](file://internal/router/router.go#L1-L42)
|
|||
|
|
- [internal/handler/brand.go:1-50](file://internal/handler/brand.go#L1-L50)
|
|||
|
|
- [internal/handler/model.go:1-51](file://internal/handler/model.go#L1-L51)
|
|||
|
|
- [internal/handler/model_list.go:1-57](file://internal/handler/model_list.go#L1-L57)
|
|||
|
|
- [internal/handler/device.go:1-85](file://internal/handler/device.go#L1-L85)
|
|||
|
|
- [internal/repository/brand.go:1-51](file://internal/repository/brand.go#L1-L51)
|
|||
|
|
- [internal/repository/model.go:1-95](file://internal/repository/model.go#L1-L95)
|
|||
|
|
- [internal/database/mysql.go:1-47](file://internal/database/mysql.go#L1-L47)
|
|||
|
|
- [internal/search/meilisearch.go:1-46](file://internal/search/meilisearch.go#L1-L46)
|
|||
|
|
- [internal/cache/redis.go:1-17](file://internal/cache/redis.go#L1-L17)
|
|||
|
|
- [internal/response/response.go:1-37](file://internal/response/response.go#L1-L37)
|
|||
|
|
- [pkg/encode/base64.go:1-52](file://pkg/encode/base64.go#L1-L52)
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [cmd/server/main.go:1-96](file://cmd/server/main.go#L1-L96)
|
|||
|
|
- [internal/router/router.go:1-42](file://internal/router/router.go#L1-L42)
|
|||
|
|
|
|||
|
|
## 核心组件
|
|||
|
|
- 入口与服务生命周期:main 负责加载配置、初始化日志、数据库、搜索引擎与缓存客户端,构建 Gin 引擎并启动 HTTP 服务器,同时注册信号量以支持优雅停机。
|
|||
|
|
- 路由与中间件:路由层集中注册各业务路由与全局中间件(恢复、请求 ID、日志、CORS),确保所有请求具备一致的横切能力。
|
|||
|
|
- 处理器:按业务域拆分,分别处理品牌、型号、型号列表(搜索)、设备上报(Redis)等端点,统一使用上下文传递取消/超时信号。
|
|||
|
|
- 仓储:封装 SQL 查询细节,提供类型安全的数据读取与扫描逻辑,向上游处理器暴露清晰的领域模型集合。
|
|||
|
|
- 数据库:集中配置连接池大小、空闲连接数与连接最大生命周期,确保高并发下的稳定性。
|
|||
|
|
- 搜索与缓存:Meilisearch 用于全文检索,Redis 用于设备信息的快速写入与存储。
|
|||
|
|
- 响应与编码:统一响应体结构与错误码语义;可选自定义 Base64 编码以降低传输体积或满足特定协议要求。
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/handler/brand.go:19-50](file://internal/handler/brand.go#L19-L50)
|
|||
|
|
- [internal/handler/model.go:19-51](file://internal/handler/model.go#L19-L51)
|
|||
|
|
- [internal/handler/model_list.go:19-57](file://internal/handler/model_list.go#L19-L57)
|
|||
|
|
- [internal/handler/device.go:19-85](file://internal/handler/device.go#L19-L85)
|
|||
|
|
- [internal/repository/brand.go:16-51](file://internal/repository/brand.go#L16-L51)
|
|||
|
|
- [internal/repository/model.go:16-95](file://internal/repository/model.go#L16-L95)
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [internal/search/meilisearch.go:17-46](file://internal/search/meilisearch.go#L17-L46)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)
|
|||
|
|
- [pkg/encode/base64.go:13-52](file://pkg/encode/base64.go#L13-L52)
|
|||
|
|
|
|||
|
|
## 架构总览
|
|||
|
|
下图展示一次典型请求从进入路由到返回响应的全链路交互,涵盖 Router、Handler、Repository、Database、Search、Cache 以及响应与编码模块。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
sequenceDiagram
|
|||
|
|
participant C as "客户端"
|
|||
|
|
participant G as "Gin 路由"
|
|||
|
|
participant M1 as "请求ID中间件"
|
|||
|
|
participant M2 as "日志中间件"
|
|||
|
|
participant H as "处理器"
|
|||
|
|
participant R as "仓储"
|
|||
|
|
participant D as "数据库"
|
|||
|
|
participant S as "搜索引擎"
|
|||
|
|
participant K as "缓存"
|
|||
|
|
participant E as "编码/响应"
|
|||
|
|
C->>G : "HTTP 请求"
|
|||
|
|
G->>M1 : "注入/透传请求ID"
|
|||
|
|
M1->>M2 : "继续处理"
|
|||
|
|
M2->>H : "匹配路由并调用处理器"
|
|||
|
|
alt "品牌/型号查询"
|
|||
|
|
H->>R : "List(ctx, filters)"
|
|||
|
|
R->>D : "QueryContext(ctx, sql, args)"
|
|||
|
|
D-->>R : "Rows"
|
|||
|
|
R-->>H : "领域模型列表"
|
|||
|
|
else "型号列表搜索"
|
|||
|
|
H->>S : "ModelList(ctx, key, count)"
|
|||
|
|
S-->>H : "搜索结果"
|
|||
|
|
else "设备上报"
|
|||
|
|
H->>K : "HSet(ctx, key, field, value)"
|
|||
|
|
K-->>H : "OK"
|
|||
|
|
end
|
|||
|
|
H->>E : "根据参数选择JSON或Base64编码"
|
|||
|
|
E-->>C : "HTTP 响应"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50)
|
|||
|
|
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
|
|||
|
|
- [internal/handler/model_list.go:26-57](file://internal/handler/model_list.go#L26-L57)
|
|||
|
|
- [internal/handler/device.go:26-85](file://internal/handler/device.go#L26-L85)
|
|||
|
|
- [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51)
|
|||
|
|
- [internal/repository/model.go:20-95](file://internal/repository/model.go#L20-L95)
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [internal/search/meilisearch.go:22-46](file://internal/search/meilisearch.go#L22-L46)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [pkg/encode/base64.go:35-52](file://pkg/encode/base64.go#L35-L52)
|
|||
|
|
- [internal/response/response.go:15-37](file://internal/response/response.go#L15-L37)
|
|||
|
|
|
|||
|
|
## 详细组件分析
|
|||
|
|
|
|||
|
|
### 路由与中间件
|
|||
|
|
- 路由注册:在路由层集中注册健康检查、品牌、型号、型号列表、设备上报等端点,并通过分组划分版本与业务域。
|
|||
|
|
- 中间件栈:恢复、请求 ID、日志、CORS 依次执行,确保异常不中断服务、请求具备唯一标识、日志包含耗时与状态码、跨域策略生效。
|
|||
|
|
- 请求 ID 设计:若客户端未提供 X-Request-ID,则生成随机十六进制字符串并回传,便于端到端追踪。
|
|||
|
|
- 日志中间件:记录状态码、方法、路径、延迟、客户端 IP、请求 ID、查询参数与错误集合,按状态分级输出。
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)
|
|||
|
|
- [internal/middleware/request_id.go:10-31](file://internal/middleware/request_id.go#L10-L31)
|
|||
|
|
- [internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
|
|||
|
|
### 处理器层
|
|||
|
|
- 品牌处理器:接收品牌名称过滤参数,调用品牌仓储查询,支持可选 Base64 响应编码。
|
|||
|
|
- 型号处理器:接收品牌与型号名称过滤参数,调用型号仓储查询,支持可选 Base64 响应编码。
|
|||
|
|
- 型号列表处理器:接收关键词与数量参数,调用搜索引擎客户端查询,支持可选 Base64 响应编码。
|
|||
|
|
- 设备上报处理器:接收 MAC、型号、版本与 X-Forwarded-For 等参数,进行参数校验与日志记录,将设备信息序列化后写入 Redis Hash。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
classDiagram
|
|||
|
|
class Router {
|
|||
|
|
+New(log, db, search, redis) Engine
|
|||
|
|
}
|
|||
|
|
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)
|
|||
|
|
}
|
|||
|
|
Router --> BrandHandler : "注册路由"
|
|||
|
|
Router --> ModelHandler : "注册路由"
|
|||
|
|
Router --> ModelListHandler : "注册路由"
|
|||
|
|
Router --> DeviceHandler : "注册路由"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [internal/router/router.go:21-25](file://internal/router/router.go#L21-L25)
|
|||
|
|
- [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/brand.go:26-50](file://internal/handler/brand.go#L26-L50)
|
|||
|
|
- [internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)
|
|||
|
|
- [internal/handler/model_list.go:26-57](file://internal/handler/model_list.go#L26-L57)
|
|||
|
|
- [internal/handler/device.go:26-85](file://internal/handler/device.go#L26-L85)
|
|||
|
|
|
|||
|
|
### 仓储层
|
|||
|
|
- 品牌仓储:支持模糊过滤的品牌列表查询,返回领域模型集合。
|
|||
|
|
- 型号仓储:支持按品牌名精确过滤或按型号名模糊过滤,返回领域模型集合;默认无过滤时返回空列表。
|
|||
|
|
- 扫描逻辑:统一使用数据库 Rows 扫描,将 Null 字段转换为指针类型,避免空值污染。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
flowchart TD
|
|||
|
|
Start(["进入仓储方法"]) --> Normalize["标准化输入参数"]
|
|||
|
|
Normalize --> BuildQuery{"构建查询条件"}
|
|||
|
|
BuildQuery --> |品牌过滤| QBrand["SQL: 按品牌名过滤"]
|
|||
|
|
BuildQuery --> |型号过滤| QModel["SQL: 模糊匹配型号名"]
|
|||
|
|
BuildQuery --> |无过滤| Empty["返回空列表"]
|
|||
|
|
QBrand --> Exec["QueryContext(ctx, sql, args)"]
|
|||
|
|
QModel --> Exec
|
|||
|
|
Exec --> ScanLoop["逐行扫描并构造领域模型"]
|
|||
|
|
ScanLoop --> Done(["返回模型列表"])
|
|||
|
|
Empty --> Done
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51)
|
|||
|
|
- [internal/repository/model.go:20-95](file://internal/repository/model.go#L20-L95)
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51)
|
|||
|
|
- [internal/repository/model.go:20-95](file://internal/repository/model.go#L20-L95)
|
|||
|
|
|
|||
|
|
### 数据库层
|
|||
|
|
- 连接配置:基于 DSN 设置字符集、时区、时间解析等参数。
|
|||
|
|
- 连接池:设置最大打开连接数、最大空闲连接数与连接最大生命周期,降低连接抖动与资源占用。
|
|||
|
|
- 健康检查:启动阶段通过 PingContext 验证连通性,失败则关闭并报错。
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
|
|||
|
|
### 搜索层
|
|||
|
|
- 客户端封装:基于配置创建索引管理器实例,限定检索字段集合。
|
|||
|
|
- 检索流程:接收关键词与数量参数,调用搜索接口返回命中项,解码为映射列表。
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [internal/search/meilisearch.go:17-46](file://internal/search/meilisearch.go#L17-L46)
|
|||
|
|
|
|||
|
|
### 缓存层
|
|||
|
|
- 客户端封装:基于配置创建 Redis 客户端实例,支持密码与数据库选择。
|
|||
|
|
- 设备上报:处理器将设备信息序列化后写入 Redis Hash,键为 devices,field 为 MAC 地址。
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [internal/handler/device.go:52-85](file://internal/handler/device.go#L52-L85)
|
|||
|
|
|
|||
|
|
### 响应与编码
|
|||
|
|
- 统一响应体:包含 code、message、data 字段;提供 OK、Fail、BadRequest、InternalError 等便捷函数。
|
|||
|
|
- Base64 编码:支持将任意 JSON 结构先 JSON 编码,再进行自定义字符映射的 Base64 转换;解析时默认开启 Base64 响应。
|
|||
|
|
- 处理器侧:根据参数决定直接返回 JSON 或返回 Base64 字符串。
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)
|
|||
|
|
- [pkg/encode/base64.go:13-52](file://pkg/encode/base64.go#L13-L52)
|
|||
|
|
- [internal/handler/brand.go:38-50](file://internal/handler/brand.go#L38-L50)
|
|||
|
|
- [internal/handler/model.go:38-50](file://internal/handler/model.go#L38-L50)
|
|||
|
|
- [internal/handler/model_list.go:44-56](file://internal/handler/model_list.go#L44-L56)
|
|||
|
|
|
|||
|
|
## 依赖关系分析
|
|||
|
|
- 组件耦合度:处理器仅依赖仓储接口或外部客户端,仓储仅依赖 sql.DB 或搜索/缓存客户端,保持低耦合。
|
|||
|
|
- 接口设计原则:统一使用 context 传递取消/超时信号;查询方法返回 error 以便上层统一处理;响应体结构固定,便于前端消费。
|
|||
|
|
- 错误传播:仓储与外部客户端均返回包装后的错误,处理器捕获后统一记录日志并返回内部错误响应。
|
|||
|
|
- 并发控制:数据库连接池由 sql.DB 统一管理;Redis 客户端为线程安全;Gin 默认并发处理请求。
|
|||
|
|
|
|||
|
|
```mermaid
|
|||
|
|
graph LR
|
|||
|
|
H1["BrandHandler"] --> R1["BrandRepository"]
|
|||
|
|
H2["ModelHandler"] --> R2["ModelRepository"]
|
|||
|
|
H3["ModelListHandler"] --> S1["Search.Client"]
|
|||
|
|
H4["DeviceHandler"] --> K1["Redis.Client"]
|
|||
|
|
R1 --> DB["sql.DB"]
|
|||
|
|
R2 --> DB
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
图表来源
|
|||
|
|
- [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/handler/model_list.go:19-24](file://internal/handler/model_list.go#L19-L24)
|
|||
|
|
- [internal/handler/device.go:19-24](file://internal/handler/device.go#L19-L24)
|
|||
|
|
- [internal/repository/brand.go:16-18](file://internal/repository/brand.go#L16-L18)
|
|||
|
|
- [internal/repository/model.go:16-18](file://internal/repository/model.go#L16-L18)
|
|||
|
|
- [internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- [internal/search/meilisearch.go:17-20](file://internal/search/meilisearch.go#L17-L20)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [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/handler/model_list.go:19-24](file://internal/handler/model_list.go#L19-L24)
|
|||
|
|
- [internal/handler/device.go:19-24](file://internal/handler/device.go#L19-L24)
|
|||
|
|
- [internal/repository/brand.go:16-18](file://internal/repository/brand.go#L16-L18)
|
|||
|
|
- [internal/repository/model.go:16-18](file://internal/repository/model.go#L16-L18)
|
|||
|
|
|
|||
|
|
## 性能考量
|
|||
|
|
- 连接池与生命周期:数据库连接池参数已配置,建议结合压测结果调整最大打开/空闲连接数与连接最大生命周期。
|
|||
|
|
- 上下文超时:处理器统一使用请求上下文,建议在路由层或中间件为长耗时操作设置合理超时。
|
|||
|
|
- 编码优化:Base64 编码会增加体积,仅在必要场景启用;可考虑压缩或分页策略。
|
|||
|
|
- 搜索限制:搜索端 count 参数默认上限为 100,建议根据业务需求与索引规模动态调整。
|
|||
|
|
- 缓存写入:Redis 写入为单键写入,建议评估批量写入或管道命令以减少 RTT。
|
|||
|
|
- 日志开销:日志中间件会记录请求详情,生产环境建议降低采样率或使用异步日志。
|
|||
|
|
|
|||
|
|
## 故障排查指南
|
|||
|
|
- 数据库连接失败:检查 DSN 参数、网络连通性与 Ping 超时;查看连接池配置是否合理。
|
|||
|
|
- 搜索异常:确认索引存在、API Key 正确、Host 可达;关注搜索返回的错误码与消息。
|
|||
|
|
- Redis 写入失败:确认地址、密码、数据库编号正确;检查键空间与过期策略。
|
|||
|
|
- 处理器错误:查看处理器日志中记录的错误堆栈;确认参数校验与编码流程是否正常。
|
|||
|
|
- 响应异常:确认响应体结构与编码开关;核对前端是否正确解析 Base64。
|
|||
|
|
|
|||
|
|
章节来源
|
|||
|
|
- [internal/database/mysql.go:37-47](file://internal/database/mysql.go#L37-L47)
|
|||
|
|
- [internal/search/meilisearch.go:22-46](file://internal/search/meilisearch.go#L22-L46)
|
|||
|
|
- [internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|
|||
|
|
- [internal/handler/brand.go:30-36](file://internal/handler/brand.go#L30-L36)
|
|||
|
|
- [internal/handler/model.go:31-44](file://internal/handler/model.go#L31-L44)
|
|||
|
|
- [internal/handler/model_list.go:37-42](file://internal/handler/model_list.go#L37-L42)
|
|||
|
|
- [internal/handler/device.go:60-78](file://internal/handler/device.go#L60-L78)
|
|||
|
|
- [internal/response/response.go:30-37](file://internal/response/response.go#L30-L37)
|
|||
|
|
|
|||
|
|
## 结论
|
|||
|
|
该架构通过清晰的分层与职责分离,实现了 Router → Handler → Repository → Database 的稳定数据流;借助中间件统一横切能力、响应体与编码策略,提升了可观测性与兼容性;错误传播与异常处理遵循统一模式,便于维护与扩展。建议在生产环境中进一步完善超时控制、缓存批量写入与日志采样,以获得更优的吞吐与稳定性。
|
|||
|
|
|
|||
|
|
## 附录
|
|||
|
|
- 入口与服务生命周期:参考 [cmd/server/main.go:22-96](file://cmd/server/main.go#L22-L96)
|
|||
|
|
- 路由与中间件:参考 [internal/router/router.go:14-42](file://internal/router/router.go#L14-L42)、[internal/middleware/request_id.go:10-31](file://internal/middleware/request_id.go#L10-L31)、[internal/middleware/logger.go:10-46](file://internal/middleware/logger.go#L10-L46)
|
|||
|
|
- 处理器与响应编码:参考 [internal/handler/brand.go:26-50](file://internal/handler/brand.go#L26-L50)、[internal/handler/model.go:26-51](file://internal/handler/model.go#L26-L51)、[internal/handler/model_list.go:26-57](file://internal/handler/model_list.go#L26-L57)、[internal/handler/device.go:26-85](file://internal/handler/device.go#L26-L85)、[internal/response/response.go:9-37](file://internal/response/response.go#L9-L37)、[pkg/encode/base64.go:13-52](file://pkg/encode/base64.go#L13-L52)
|
|||
|
|
- 仓储与数据库:参考 [internal/repository/brand.go:20-51](file://internal/repository/brand.go#L20-L51)、[internal/repository/model.go:20-95](file://internal/repository/model.go#L20-L95)、[internal/database/mysql.go:14-47](file://internal/database/mysql.go#L14-L47)
|
|||
|
|
- 搜索与缓存:参考 [internal/search/meilisearch.go:17-46](file://internal/search/meilisearch.go#L17-L46)、[internal/cache/redis.go:10-17](file://internal/cache/redis.go#L10-L17)
|