Skip to content

4.1 整体架构概览 ​

概述

系统采用分层架构 + 声明式基座 + 全局钩子横切 + gmeta 反射注解的组合。本节给出总架构图、模块依赖方向(允许/禁止)与启动编排,是理解全部机制的地图。

系统总架构图 ​

text
┌─────────────────────────────  客户端  ─────────────────────────────┐
│  ui/(Vue3 + Element Plus,baseURL=/api)   其他 API 消费方        │
└──────────────────────────────────┬─────────────────────────────────┘
                                   │ HTTP(Bearer JWT)
╔══════════════════════════════════▼═════════════════════════════════╗
║  ghttp Server(:8000)                                               ║
║  ┌────────────────── 中间件链(顺序执行)──────────────────┐        ║
║  │ CORS → Response → RateLimit → Demo → JWT → Tenant       │        ║
║  │                → OperationLog                           │        ║
║  └──────────────────────────┬──────────────────────────────┘        ║
║  ┌──────────────────────────▼──────────────────────────────┐        ║
║  │ Bind 反射包装层(gmeta):权限校验 → 参数解析 → 分发     │        ║
║  │ 路由元数据表 meta(权限/日志 注解即事实,补注册 goai)    │        ║
║  └──────────────────────────┬──────────────────────────────┘        ║
║  controller(薄)→ service 接口(手维护)→ logic(ModuleSpec 基座)  ║
║       │ 侧路:utility/{jwt,captcha,cache,upload,excel,ip2region…}   ║
║       │ 侧路:gcron 调度器(job daemon + CleanTemp)                ║
║  ┌────▼─────────────────────────────────────────────────────┐       ║
║  │ dao.Xxx.Ctx(ctx) —— 唯一查询入口                          │       ║
║  │   hooks.ApplyCtx:del_flag=0 + 租户级表 tenant_id IN(0,x) │       ║
║  │   hooks.Handler:Insert 盖章 / Update 盖章 / Delete→软删   │       ║
║  └────┬─────────────────────────────────────────────────────┘       ║
╚══════╪══════════════════════════════════════════════════════════════╝
       │ gdb(五驱动运行时切换)
┌──────▼────────┐   ┌──────────────┐   ┌─────────────────────────────┐
│ MySQL/PgSQL/… │   │ Redis(缓存) │   │ 磁盘 resource/upload + xdb  │
└───────────────┘   └──────────────┘   └─────────────────────────────┘

模块依赖方向图(允许 / 禁止) ​

text
api/v1  ◀── controller ◀── logic ──▶ service(接口注册)
                      │
                      ├──▶ dao ──▶ model/entity · model/hooks ──▶ gdb
                      ├──▶ utility/*(无业务依赖)
                      └──▶ consts

internal/task ──▶ internal/logic        ✅ 允许(任务复用 base 能力)
internal/logic ──▶ internal/task        ❌ 禁止(反向依赖)
internal/middleware ──▶ 业务包           ❌ 禁止(经 wire.go 函数变量接线)
internal/migrate ──▶ dao/logic          ❌ 禁止(gdb 裸连,隔离钩子)
base.go ──▶ 模块文件                    ❌ 禁止(只依赖 dao/utility/consts)

启动编排(internal/cmd) ​

text
main.go(注册五数据库驱动 + Redis 适配器 + blank import internal/logic)
  └─ internal/cmd.Run(ctx)
       ├─ 1) utility/cache.Init            Redis 探测,失败降级进程内存
       ├─ 2) wireDependencies              校验中间件依赖是否已由业务包 init 接线
       ├─ 3) g.Server("easygoadmin") + router.Register(s)
       │      中间件链注册 + 404/500 状态处理器 + SetServerRoot("resource")
       │      + /api/health + /swagger → 逐个 Bind 全部控制器
       ├─ 4) go DaemonInit(延时 2s)      定时任务调度器加载 status=1 任务
       ├─ 5) gcron 注册 CleanTemp          每日 03:30 清理上传临时目录
       └─ 6) s.Run()                       阻塞运行 HTTP 服务

延时 2s 的原因:等 HTTP 监听就绪(任务可能是 HTTP 调自身接口)。

业务调用链(标准 CRUD) ​

text
Bind 包装(gmeta 权限/日志元数据)
  → controller.CXxx(薄层,仅转发 service.Xxx())
    → service.IXxx 接口(internal/service/{模块}.go,手维护)
      → logic.sXxx 实现(internal/logic/{模块}.go,ModuleSpec 基座或手写)
        → dao.Xxx.Ctx(ctx)(唯一查询入口:挂全局钩子 + 注入 del_flag/租户条件)
          → gdb → 数据库

五个关键设计决策 ​

决策理由
目录平铺:api/controller/logic/service 均单包,每模块一文件跨模块直接同包调用(如 user 调 ResolveCityNames 无需 import);生成器目标路径唯一
service 接口手维护接口即文档;禁止 gf gen service 整体覆盖
logic 同包 init() 注册无需 blank import,包内全量加载
中间件不依赖业务层IdentityLoader/TenantLoader/LogSink 以函数变量接线(wire.go),cmd 启动期检查告警
dao.Ctx 唯一查询入口软删/租户/审计三条红线在钩子层强制执行,业务零感知

分层职责速查 ​

层位置职责禁止
api/v1api/v1/{模块}.go请求响应结构体 + gmeta 注解业务逻辑
controllerinternal/controller/{模块}.go薄层透传业务/dao/手写响应
serviceinternal/service/{模块}.go接口契约(手维护)实现
logicinternal/logic/{模块}.go业务实现(基座+钩子+手写)反向依赖 task
daointernal/dao/查询入口(钩子+红线条件)绕过直连 DB
hooksinternal/model/hooks/审计盖章/软删/租户业务判断

小蚂蚁云团队 · 提供技术支持