docs(docs): 新增 0020 Portal Shell 架构文档(C4+4+1+ADR) + 设计 spec v2.1 + 更新 0010/004 指向新架构
This commit is contained in:
@@ -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 Mesh(Istio)配合,可以在架构图中补上。
|
||||
你提到了 WAF、Gateway、Kafka、异构存储,但没有提到统一的配置中心与服务发现(如 Consul/Nacos/K8s Service)。在微服务体系下,服务动态扩缩容、配置热更新(如限流阈值、功能开关)必须同步规划,否则运维会变得困难。这一层通常与 Service Mesh(Istio)配合,可以在架构图中补上。
|
||||
|
||||
Reference in New Issue
Block a user