docs(docs): 新增 0020 Portal Shell 架构文档(C4+4+1+ADR) + 设计 spec v2.1 + 更新 0010/004 指向新架构

This commit is contained in:
SpecialX
2026-07-14 18:34:40 +08:00
parent 9db7fd917e
commit 0b858d9069
4 changed files with 2964 additions and 309 deletions

View File

@@ -8,13 +8,13 @@
code
Mermaid
graph TB
subgraph ClientLayer["1. 多端访问层 (Micro-Frontends)"]
direction LR
MFE1[Teacher Portal]
MFE2[Student Portal]
MFE3[Parent App]
MFE4[Admin Console]
end
subgraph ClientLayer["1. 多端访问层 (Micro-Frontends)"]
direction LR
MFE1[Teacher Portal]
MFE2[Student Portal]
MFE3[Parent App]
MFE4[Admin Console]
end
subgraph EdgeLayer["2. 边缘与网关层 (API Gateway & BFF)"]
WAF[WAF / CDN / 防火墙]
@@ -49,25 +49,26 @@ graph TB
WAF --> Gateway
Gateway --> BFF1 & BFF2 & BFF3
BFF1 & BFF2 & BFF3 --> ServiceLayer
%% 服务与存储的交互
CoreEdu --> MySQL
IAM --> MySQL
Content --> Neo4j
DataAna --> ClickHouse
ServiceLayer --> Redis
%% CDC 与总线
MySQL -- "CDC (Debezium)<br/>捕获变更" --> Kafka
ServiceLayer -- "发布领域事件<br/>Outbox Pattern" --> Kafka
Kafka -- "消费事件" --> ServiceLayer
Kafka -- "同步读视图" --> ClickHouse
Kafka -- "索引同步" --> ES
二、 彻底解耦的四大核心设计模式
在最优架构中,系统通过以下企业级模式解决耦合问题:
1. 读写分离 (CQRS):解决“上帝模块”与复杂聚合查询
在当前的 Next_Edu 中Dashboard仪表盘需要查询所有模块。在企业级架构中写入逻辑和查询逻辑是完全物理隔离的。
在当前的 Next_Edu 中Dashboard仪表盘需要查询所有模块。在企业级架构中写入逻辑和查询逻辑是完全物理隔离的。
Command (写) 链路:教师批改作业,请求只打到 CoreEdu 微服务,该服务只更新 MySQL 中的作业表,并迅速返回。
@@ -78,7 +79,7 @@ Query (读) 链路:系统背后通过 CDC如 Debezium监听 MySQL 的 bi
收益:前端 Dashboard 请求 BFF 时BFF 只查 ClickHouse 中的那一张宽表,毫秒级返回。没有 Join没有跨服务调用系统彻底解耦。
2. 发件箱模式 (Transactional Outbox):解决跨模块数据一致性
如果模块 A 成功了,模块 B 失败了怎么办?企业级系统绝对不允许跨服务的数据库事务 (如 2PC),因为会拖垮性能。
如果模块 A 成功了,模块 B 失败了怎么办?企业级系统绝对不允许跨服务的数据库事务 (如 2PC),因为会拖垮性能。
设计教师发布考试时CoreEdu 服务在同一个本地事务中做两件事:
@@ -91,19 +92,37 @@ Query (读) 链路:系统背后通过 CDC如 Debezium监听 MySQL 的 bi
收益:实现了 100% 保证的不丢消息的最终一致性。业务逻辑无需关心外部模块是否存活。
3. 编排与协同 (Orchestration vs. Choreography)
企业级架构处理复杂业务流(例如:考试创建 -> 智能组卷 -> 题目查重 -> 通知分发 -> 家长推送)必须区分两种模式:
企业级架构处理复杂业务流(例如:考试创建 -> 智能组卷 -> 题目查重 -> 通知分发 -> 家长推送)必须区分两种模式:
协同 (Choreography - 基于事件):适用于低耦合业务。发完作业后,发出 HomeworkCreated 事件,通知服务、积分服务各自监听,互相不知道对方存在。
编排 (Orchestration - 基于工作流):适用于强状态依赖的业务。引入工作流引擎(如 Temporal 或 Camunda。由一个中央 Coordinator 负责指挥:“先调 AI 生成题目,成功后再调试卷服务,如果失败就执行补偿逻辑回滚”。
4. 前端微前端化 (Micro-Frontends)
后端的解耦如果不配合前端的解耦,依然是一场灾难。
后端的解耦如果不配合前端的解耦,依然是一场灾难。
设计:通过 Module Federation模块联邦或 qiankun将巨大的前端应用拆解。
收益:“排课组”的前端和后端可以独立发版,“题库组”的前端和后端可以独立发版。页面的组装在运行时由宿主框架完成。
> **⚠️ 架构演进说明2026-07-14**
>
> 本节描述的 MF 微前端方案已在实施评估中被**取代**。经过对 Module Federation + 独立 widget 容器方案的深入分析发现存在部署运维复杂8+ 容器)、与 Next.js SSR 兼容性差、首屏瀑布流等问题。
>
> **新方案**:采用 **Modular Monolith + Micro-kernel** 架构(单 Next.js + dynamic import + 配置驱动),在保留"前端解耦 + 独立发版"核心目标的同时大幅降低部署复杂度1 容器并提升首屏性能RSC 服务端预取)。
>
> 详见:[0020 Portal Shell 架构文档](./0020_portal_shell_architecture.md)
>
> **演进对比**
>
> | 维度 | 本节MF 微前端) | 新方案Modular Monolith |
> | ---------- | -------------------- | -------------------------- |
> | 部署 | 8+ 独立容器 | 1 容器 |
> | 首屏 | MF 远程加载慢 | RSC 服务端预取秒开 |
> | 跨前端通信 | EventBus状态黑盒 | URL + Zustand可追踪 |
> | 独立发版 | widget 可独立发版 | 插件随 Shell 发版 |
> | 第三方扩展 | 天然支持 | 二期 iframe 沙箱 |
三、 基础设施与扩展性设计
统一 API 网关 (API Gateway)
@@ -122,23 +141,23 @@ SSE 或 WebSocket 不再由业务容器承载。设立专门的 Push Gateway 服
题库检索:题目内容实时同步到 Elasticsearch支持分词、拼音、公式模糊全文搜索而不是 MySQL 的 FULLTEXT。
四、 对比:为什么这是“最优”?
维度 当前的单体/模块化 (Next_Edu V3) 现代企业级架构 结果差异
模块依赖 物理隔离,但代码级强引用 (import) 纯事件通信与 API 契约 任意微服务宕机/重构,完全不影响其他服务
聚合查询 并行查 5 个模块的 DB 再在内存拼装 后台预计算,直接查 ClickHouse 宽表 Dashboard 响应从 1.5s 降至 50ms
技术栈绑定 全部被绑死在 TypeScript + Next.js 异构。AI网关用Python高并发网关用Go 能够根据业务特性选择最优技术
实时推送 Next.js SSE连接数多了容易爆内存 独立的 Push Gateway + Redis PubSub 支持全校十万人同时在线答题的广播推送
容灾与扩容 只能整个应用一起扩容 核心教学扩 50 个 Pod后台审计缩至 1 个 Pod 资源利用率极高,抗高并发能力呈指数级提升
维度 当前的单体/模块化 (Next_Edu V3) 现代企业级架构 结果差异
模块依赖 物理隔离,但代码级强引用 (import) 纯事件通信与 API 契约 任意微服务宕机/重构,完全不影响其他服务
聚合查询 并行查 5 个模块的 DB 再在内存拼装 后台预计算,直接查 ClickHouse 宽表 Dashboard 响应从 1.5s 降至 50ms
技术栈绑定 全部被绑死在 TypeScript + Next.js 异构。AI网关用Python高并发网关用Go 能够根据业务特性选择最优技术
实时推送 Next.js SSE连接数多了容易爆内存 独立的 Push Gateway + Redis PubSub 支持全校十万人同时在线答题的广播推送
容灾与扩容 只能整个应用一起扩容 核心教学扩 50 个 Pod后台审计缩至 1 个 Pod 资源利用率极高,抗高并发能力呈指数级提升
总结
企业级架构的本质是承认分布式环境下的不完美,用基础设施的复杂性来换取业务代码的简单性。
业务模块不再需要操心“谁要我的数据”、“如何拼装别人的数据”、“事务失败怎么回滚”。它们只做一件事:接收指令 -> 改变自身领域模型 -> 将改变广播给全宇宙Event Bus.
蓝图设计的合理性(几乎全对,但有几个地方需要微调)
1. 各层选型精准,但有一处“过度理想”
API Gateway + BFF + GraphQL
Gateway 做统一鉴权限流BFF 做面向前端的聚合GraphQL 允许不同端按需取数——这在多端下非常正确。
✅ 唯一需要警惕的是 GraphQL 的 N+1 和深度嵌套,必须在 BFF 层用 DataLoader 批量化解,否则可能引入严重的下游放大调用。
API Gateway + BFF + GraphQL
Gateway 做统一鉴权限流BFF 做面向前端的聚合GraphQL 允许不同端按需取数——这在多端下非常正确。
✅ 唯一需要警惕的是 GraphQL 的 N+1 和深度嵌套,必须在 BFF 层用 DataLoader 批量化解,否则可能引入严重的下游放大调用。
事件总线选 Kafka/Pulsar
对业务事件和 CDC 均用同一总线,完全可行。
@@ -157,7 +176,7 @@ Push Gateway 独立 + Redis Pub/Sub
✅ 注意Redis Pub/Sub 不持久化,如果有消息可靠性要求(离线再上线收不到历史推送),需要引入一个持久化队列或消息主题,由 Push Gateway 消费后推送给在线用户,同时标记已读。
2. 四大核心模式评价
CQRS正确这是消除“上帝模块”的根本解。
CQRS正确这是消除“上帝模块”的根本解。
Transactional Outbox + CDC
这是 唯一能保证最终一致性的分布式事务方案,比 2PC 和 Saga 都更适合高并发教育场景。
@@ -171,4 +190,4 @@ Choreography vs Orchestration
在多团队并行开发下必要,但教育产品交互一致性要求高,需要强约束的设计系统和跨应用状态共享机制(如通过 BFF 或客户端共享 token + 用户上下文)。模块联邦 + 统一 UI 库是标配。
3. 基础设施层的一个潜在疏漏
你提到了 WAF、Gateway、Kafka、异构存储但没有提到统一的配置中心与服务发现如 Consul/Nacos/K8s Service。在微服务体系下服务动态扩缩容、配置热更新如限流阈值、功能开关必须同步规划否则运维会变得困难。这一层通常与 Service MeshIstio配合可以在架构图中补上。
你提到了 WAF、Gateway、Kafka、异构存储但没有提到统一的配置中心与服务发现如 Consul/Nacos/K8s Service。在微服务体系下服务动态扩缩容、配置热更新如限流阈值、功能开关必须同步规划否则运维会变得困难。这一层通常与 Service MeshIstio配合可以在架构图中补上。

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff