第4章:整体架构分层——拆开KMS的五层蛋糕
说到知识管理系统的架构,我见过很多团队一上来就堆功能,结果半年后发现改不动、测不了、扩展无门。说白了,一个能撑住组织级体量的KMS,必须先把层分清楚。
这一章我们就聊透这五层:展示层、业务层、服务层、数据层、基础设施层。每层该放什么、不该放什么,我踩过的坑会一并交代。
4.1 展示层——用户看到的那个“面子”
展示层就是用户能摸到的所有界面。门户、搜索框、个人工作台、移动端H5,都算。
但这里有个常见的错——把业务逻辑也塞进前端。我在一个项目中就遇到过:前端直接写死了“文档审批流程”的判断条件,导致后端改了策略后前端还得跟着发版。这叫什么?这是把架构建在了沙滩上。
展示层该干的事:
- 渲染UI组件,响应交互事件
- 调用业务层的API,把数据展示出来
- 做简单的格式验证(比如字段是否为空)
- 缓存一些用户偏好(如布局、主题)
嗯,这里要注意:展示层不应该直接访问数据库。哪怕只是读一条“分类名称”,也得走业务层。我自己的习惯是,在前端项目里单独建一个 services/ 目录,专门放API调用,绝不掺杂SQL或业务计算。
4.2 业务层——真正有“脑子”的地方
业务层是KMS的大脑。权限判断、知识审核流程、标签自动推荐、文档版本管理……这些都得在这里完成。
为什么不在服务层做?服务层偏技术通用,而业务层关注的是组织特有的规则。比如一个合同知识库,审批链可能是“员工→主管→法务→归档”;换了另一个团队,可能只需要“员工→归档”。这种变化就该封装在业务层。
我曾经接手过一个系统,业务逻辑散落在服务层和展示层,光梳理“一个知识发布到底经过哪些校验”就花了两周。后来我们强制要求:所有业务规则必须写在 business/ 模块,并且用单元测试覆盖。从那以后,改动再也不怕炸到别的地方了。
| 层 | 典型职责 | 反例(我在项目中见过) |
|---|---|---|
| 展示层 | 界面渲染、交互反馈 | 前端直接拼接SQL |
| 业务层 | 组织策略、审批流、业务校验 | 业务规则写在存储过程里 |
| 服务层 | 通用技术能力、消息推送、文件处理 | 服务层硬编码业务字段 |
| 数据层 | 数据CRUD、索引、事务 | 数据层做业务计算 |
| 基础设施层 | 网络、存储、容器、监控 | 业务代码直接操作容器API |
4.3 服务层——通用的“工具箱”
服务层放的是跟具体业务无关的技术能力。比如全文检索引擎(Elasticsearch)、文件转码(Office预览)、消息通知(邮件/钉钉/企微)、日志收集。
你想想看,如果每个业务模块都自己写一套“发送钉钉通知”的逻辑,是不是很蠢?所以服务层要做的是把这类能力抽象成 API,业务层只管调。
但请注意:服务层不能理解业务。比如一个“知识发布成功”的消息,服务层只负责投递,至于哪些人该收到、用什么模板渲染,那是业务层的事。我在项目里看到过服务层里写死了“部门经理”的收件逻辑,结果换了个部门结构就崩了。避坑指南:服务层所有入参和出参都应该是通用类型,业务字段用 Map 或 JSON 透传,别做解析。
4.4 数据层——最老实的“仓库管理员”
数据层只管三件事:存、读、查。索引优化、分库分表、事务隔离,都是这里的事。
很多时候架构出问题,就是因为数据层兼任了“业务计算”角色——用存储过程写复杂的报表逻辑,用触发器做状态流转。你猜后果是什么?数据库 CPU 跑满,迁移时没人敢动。
我个人的习惯是:数据层只提供简单的 CRUD 和最基本的过滤(按 ID、按时间范围)。任何需要 JOIN 三张表以上的复杂查询,都往服务层或业务层的搜索引擎走。为什么?因为数据库是扩展性最差的组件,别把压力堆在那里。
数据层的典型组件:
- 关系数据库(MySQL/PostgreSQL)——存知识条目、用户、权限
- 对象存储(MinIO/S3)——存文档原文、图片、附件
- 缓存(Redis)——存热点知识、会话数据
- 搜索引擎(Elasticsearch)——存倒排索引,支撑全文检索
4.5 基础设施层——地基和“水电煤”
这一层最容易被忽略,直到某个凌晨服务器宕了、磁盘满了、证书过期了,你才会发现它有多重要。
基础设施层包括:容器编排(K8s)、Service Mesh、API 网关、监控告警(Prometheus + Grafana)、日志管道(ELK)、CI/CD 流水线、DNS 和 CDN。
我记得有一次,团队花了两天排查“KMS 偶尔变慢”的问题,最后发现是同一台宿主机上另一个任务的 IO 打满了。从那以后,我们给每个 K8s Pod 都加了资源限制(requests/limits),并且把知识存储的磁盘挂载成独立的 SSD。
4.6 五层架构的核心逻辑
光记住这五层还不够,关键要理解它们之间的依赖方向:展示层依赖业务层,业务层依赖服务层,服务层依赖数据层,数据层依赖基础设施层。反过来,下层不能依赖上层。这个单向依赖原则,是架构可维护性的命根子。
下面这张图你可以存下来,提醒团队的所有人:
4.7 层间通信的黄金法则
光分层不行,还得定规矩。我一般会在项目初期就写下这些约定:
- 展示层 → 业务层:只通过 REST 或 gRPC 调用,不得携带 SQL。
- 业务层 → 服务层:通过 SDK 或内部 API,需要签名和超时熔断。
- 服务层 → 数据层:通过 ORM 或 Repository 模式,禁止裸写 JDBC。
- 数据层 → 基础设施层:通过配置中心获取连接串,不得硬编码。
分层架构checklist.md 记录这些规则。每次 Code Review 时对着 check,违反的退回。坚持一个月,团队就养成习惯了。
4.8 避坑总结——我亲手踩过的三个雷
- 展示层直接调数据层。 某次为了“缩短搜索响应时间”,前端直接连了 Elasticsearch 的查询端口。后来权限泄露,内部知识被人爬了一天才发现。——现在我的原则:任何写在前端的数据库地址都是安全漏洞。
- 业务层和服务层混在一起。 有个版本把“知识发布”的业务校验和“文件转码”的服务逻辑写在一个模块里。结果转码服务升级,业务层也受影响一起重启。——拆干净,每个模块有独立的部署单元。
- 基础设施层没有声明式配置。 上面提过的 Nginx 配置未版本管理,导致扩容时手忙脚乱。现在所有基础设施定义(Dockerfile、Helm Chart、Prometheus Rule)都跟代码走同一个仓库。
好了,这五层框架就是你搭建或改造KMS的骨架。记住:架构的目的是让未来的人(包括三个月后的你自己)能快速定位问题、放心改动。下一层怎么落地?第5章我们会讲具体的技术选型和组件取舍。不过别着急,先把这几层的边界刻在脑子里。