Files
2026-05-27 18:07:55 +08:00

14 KiB
Raw Permalink Blame History

分层架构设计

**本文档引用的文件** - [main.go](file://cmd/server/main.go) - [router.go](file://internal/router/router.go) - [config.go](file://internal/config/config.go) - [database.go](file://internal/config/database.go) - [meilisearch_config.go](file://internal/config/meilisearch.go) - [redis_config.go](file://internal/config/redis.go) - [mysql.go](file://internal/database/mysql.go) - [redis.go](file://internal/cache/redis.go) - [meilisearch.go](file://internal/search/meilisearch.go) - [health.go](file://internal/handler/health.go) - [brand.go](file://internal/handler/brand.go) - [model.go](file://internal/handler/model.go) - [brand_repository.go](file://internal/repository/brand.go) - [brand_model.go](file://internal/model/brand.go) - [logger_middleware.go](file://internal/middleware/logger.go)

目录

  1. 引言
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论

引言

本项目采用分层架构设计,围绕表现层(Router/Handler)、业务层(Repository)、数据访问层(Database/Cache/Search)与基础设施层(Middleware/Logger)进行职责分离。通过构造函数注入依赖的方式,实现清晰的依赖关系与可测试性。MVC 的变体实现体现在:表现层负责路由与请求响应;业务层封装领域逻辑与查询;数据访问层抽象数据库、缓存与搜索引擎;基础设施层提供横切关注点如日志、CORS、请求 ID 等。

项目结构

项目按功能域分层组织,核心目录如下:

  • cmd/server:应用入口,负责初始化配置、连接外部服务、启动 HTTP 服务器
  • internal/config:配置加载与校验,支持环境变量覆盖
  • internal/router:路由注册与中间件装配
  • internal/handlerHTTP 处理器,面向路由端点,调用仓库与工具
  • internal/repository:业务仓储,封装数据库查询与映射
  • internal/database:数据库连接与池化配置
  • internal/cacheRedis 客户端初始化
  • internal/searchMeilisearch 客户端初始化与搜索接口
  • internal/middlewareGin 中间件,统一处理日志、CORS、请求 ID
  • internal/model:领域模型定义
  • internal/response:统一响应封装
  • pkg/encode:编码工具(如 Base64
  • pkg/logger:日志初始化
graph TB
subgraph "表现层"
Router["Router<br/>internal/router/router.go"]
Handlers["Handlers<br/>internal/handler/*"]
end
subgraph "业务层"
Repositories["Repositories<br/>internal/repository/*"]
Models["Models<br/>internal/model/*"]
end
subgraph "数据访问层"
DB["MySQL 连接<br/>internal/database/mysql.go"]
Redis["Redis 客户端<br/>internal/cache/redis.go"]
Search["Meilisearch 客户端<br/>internal/search/meilisearch.go"]
end
subgraph "基础设施层"
Middleware["中间件<br/>internal/middleware/*"]
LoggerPkg["日志包<br/>pkg/logger/*"]
Encode["编码工具<br/>pkg/encode/*"]
end
subgraph "入口"
Main["主程序<br/>cmd/server/main.go"]
Config["配置<br/>internal/config/*"]
end
Main --> Config
Main --> DB
Main --> Redis
Main --> Search
Main --> Router
Router --> Middleware
Router --> Handlers
Handlers --> Repositories
Repositories --> DB
Handlers --> Redis
Handlers --> Search
Handlers --> Encode
Handlers --> LoggerPkg

图示来源

章节来源

核心组件

  • 表现层(Router/Handler
    • 路由器负责注册路由组与中间件,将 HTTP 请求映射到处理器
    • 处理器接收请求参数,调用仓库或外部服务,返回统一响应
  • 业务层(Repository
    • 封装数据库查询逻辑,负责数据读取与映射
  • 数据访问层(Database/Cache/Search
    • 提供数据库连接池、Redis 客户端与 Meilisearch 客户端
  • 基础设施层(Middleware/Logger
    • 提供日志、CORS、请求 ID 等横切能力

章节来源

架构总览

下图展示了从入口到各层的完整调用链路与依赖方向:

sequenceDiagram
participant Client as "客户端"
participant Main as "主程序<br/>cmd/server/main.go"
participant Router as "路由器<br/>internal/router/router.go"
participant Handler as "处理器<br/>internal/handler/*"
participant Repo as "仓库<br/>internal/repository/*"
participant DB as "数据库<br/>internal/database/mysql.go"
participant Redis as "Redis<br/>internal/cache/redis.go"
participant Search as "Meilisearch<br/>internal/search/meilisearch.go"
Client->>Main : 启动进程
Main->>Main : 加载配置/初始化日志
Main->>DB : 打开数据库连接
Main->>Redis : 创建客户端
Main->>Search : 创建客户端
Main->>Router : 注册路由与中间件
Client->>Router : 发起 HTTP 请求
Router->>Handler : 调用对应处理器
Handler->>Repo : 执行业务查询
Repo->>DB : 执行 SQL 查询
DB-->>Repo : 返回结果集
Repo-->>Handler : 返回领域对象列表
Handler-->>Client : 统一响应

图示来源

详细组件分析

表现层(Router/Handler

  • 路由器在入口中被创建,并注入日志、数据库、搜索与 Redis 客户端
  • 注册健康检查、品牌、型号、设备等路由组与端点
  • 处理器通过构造函数注入数据库连接与日志实例,确保单一职责与可测试性
classDiagram
class Router {
+New(log, db, searchClient, redis) Engine
}
class HealthHandler {
+Check(c)
}
class BrandHandler {
-repo BrandRepository
-log Logger
+GetBrand(c)
}
class ModelHandler {
-repo ModelRepository
-log Logger
+GetModel(c)
}
Router --> HealthHandler : "注册路由"
Router --> BrandHandler : "注册路由"
Router --> ModelHandler : "注册路由"

图示来源

章节来源

业务层(Repository

  • 仓库封装数据库查询逻辑,使用上下文传递取消信号与超时控制
  • 支持条件查询与排序,将结果映射到领域模型
  • 通过构造函数注入数据库连接,保持与底层实现解耦
classDiagram
class BrandRepository {
-db sql.DB
+NewBrandRepository(db)
+List(ctx, brandName) []Brand
}
class BrandModel {
+ID int
+Name string
}
BrandRepository --> BrandModel : "返回领域对象"

图示来源

章节来源

数据访问层(Database/Cache/Search

  • 数据库连接通过 DSN 配置,设置连接池大小与生命周期,并进行健康检查
  • Redis 客户端基于配置创建,用于后续缓存操作
  • Meilisearch 客户端封装搜索请求,限制检索字段并解码结果
flowchart TD
Start(["初始化数据访问层"]) --> DBInit["创建数据库连接<br/>internal/database/mysql.go"]
DBInit --> DBPool["设置连接池参数"]
DBPool --> DBPing["执行健康检查"]
DBPing --> RedisInit["创建 Redis 客户端<br/>internal/cache/redis.go"]
DBPing --> SearchInit["创建 Meilisearch 客户端<br/>internal/search/meilisearch.go"]
RedisInit --> End(["完成"])
SearchInit --> End

图示来源

章节来源

基础设施层(Middleware/Logger

  • 日志中间件记录状态码、路径、耗时、IP、请求 ID 等信息,并按级别输出
  • 请求 ID 中间件为每个请求生成唯一标识,便于追踪
  • CORS 中间件允许跨域访问
flowchart TD
Req["请求进入"] --> ReqID["生成/获取请求ID"]
ReqID --> LogMW["日志中间件记录"]
LogMW --> CORS["CORS 中间件"]
CORS --> Handler["处理器执行"]
Handler --> Resp["响应返回"]

图示来源

章节来源

配置管理(Config

  • 配置加载支持环境变量覆盖,分别加载数据库、Meilisearch、Redis 的配置
  • 在生产环境与开发环境之间切换默认值
  • 提供地址格式化方法与环境变量读取辅助函数
flowchart TD
Load["加载配置"] --> Env["解析环境变量"]
Env --> DB["加载数据库配置"]
Env --> MS["加载 Meilisearch 配置"]
Env --> RD["加载 Redis 配置"]
DB --> ValidateDB["校验数据库配置"]
MS --> ValidateMS["校验 Meilisearch 配置"]
RD --> ValidateRD["校验 Redis 配置"]
ValidateDB --> Done["返回配置对象"]
ValidateMS --> Done
ValidateRD --> Done

图示来源

章节来源

依赖分析

  • 入口依赖配置、数据库、缓存与搜索引擎,然后构建路由器
  • 路由器依赖中间件与处理器,处理器依赖仓库与日志
  • 仓库依赖数据库连接,处理器可选依赖缓存与搜索引擎
  • 配置模块独立于业务层,提供环境化参数
graph LR
Main["cmd/server/main.go"] --> Config["internal/config/*"]
Main --> DB["internal/database/mysql.go"]
Main --> Redis["internal/cache/redis.go"]
Main --> Search["internal/search/meilisearch.go"]
Main --> Router["internal/router/router.go"]
Router --> Middleware["internal/middleware/*"]
Router --> Handlers["internal/handler/*"]
Handlers --> Repositories["internal/repository/*"]
Repositories --> DB
Handlers --> Redis
Handlers --> Search
Handlers --> Logger["pkg/logger/*"]

图示来源

章节来源

性能考虑

  • 数据库连接池:设置最大打开连接数、空闲连接数与连接生命周期,减少连接开销
  • 上下文超时:仓库查询使用上下文传递超时,避免阻塞
  • 编码优化:处理器支持 Base64 编码响应,降低传输体积但增加 CPU 开销,需按场景权衡
  • 中间件顺序:日志中间件应置于末尾以统计真实耗时

[本节为通用指导,无需特定文件来源]

故障排除指南

  • 数据库连接失败:检查配置中的主机、端口、用户名与密码;确认网络可达与安全组放行
  • Meilisearch 搜索异常:确认索引名称与 API Key 正确,检查网络连通性
  • Redis 连接问题:核对主机、端口与认证信息,验证目标数据库编号
  • 日志输出异常:确认日志初始化成功与环境变量设置正确
  • 响应编码错误:当启用 Base64 编码时,确保编码流程无异常并返回合适的状态码

章节来源

结论

该分层架构通过清晰的职责划分与依赖注入,实现了表现层、业务层、数据访问层与基础设施层的解耦。MVC 变体在本项目中体现为:路由与处理器承担表现层职责,仓库承载业务逻辑,数据库/缓存/搜索引擎作为数据访问层,中间件与日志作为基础设施。建议在扩展新功能时遵循“高层不依赖低层”的原则,保持构造函数注入与接口隔离,持续优化连接池与查询性能,并完善监控与告警体系。