微服务拆分最容易做的事情,是按照页面菜单或数据库表建立多个服务;最难的事情,是判断哪些业务应该放在一起,哪些能力值得独立变化和部署。
在 HAOVP 的设计中,我把认证、用户、内容、评论、推荐和管理等能力分开。这个方案适合当前项目的学习和实验目标,但并不意味着所有在线视频平台都应该采用相同拆法。
先看业务能力,不先看表
数据库表是实现结构,服务边界应该优先围绕业务能力。
例如,“视频内容”不仅是一张视频表,还可能包括:
- 视频基础信息;
- 分类和标签;
- 上传与文件状态;
- 内容审核状态;
- 播放和收藏相关入口;
- 与对象存储和媒体处理的协作。
如果按表拆服务,一个完整的视频操作可能需要跨越多个服务,调用链会变得很长。
业务目标
-> 核心规则
-> 数据归属
-> 对外能力
-> 服务边界哪些内容应该放在一起
我会重点看几个判断条件:
- 是否围绕同一个业务对象;
- 是否由同一组规则约束;
- 是否经常一起修改;
- 是否需要在一个本地事务内完成;
- 是否由同一类角色负责;
- 是否具有相近的性能和扩展需求。
例如,用户身份凭证与用户业务资料有关联,但变化原因不同。认证更关注登录、凭证和失效控制;用户资料更关注昵称、头像、关注关系和设置。把它们分开,可以让认证边界更清楚,但也会增加注册初始化和用户状态同步的协作成本。
数据归属必须明确
服务拆分后,每类核心数据需要有明确的负责方。
认证服务 -> 登录凭证与认证状态
用户服务 -> 用户资料与用户关系
内容服务 -> 视频、分类、标签与内容状态
评论服务 -> 评论、回复与评论互动
管理服务 -> 管理员、角色和治理入口这是一份脱敏的项目设计示例。真正重要的不是名称,而是避免多个服务直接修改同一份核心数据。
如果一个字段的归属不清,就容易出现:
- 多个服务都能修改;
- 状态变化没有唯一入口;
- 一个服务绕过另一个服务的规则;
- 出现差异时不知道以谁为准。
跨服务调用不能无限增长
拆分后,一个业务流程可能需要多个服务协作。调用不是越多越“微服务化”。
我会画出关键请求链路:
客户端
-> 网关
-> 内容服务
-> 用户服务
-> 返回结果然后继续检查:
- 同步调用是否真的必要;
- 是否可以由调用方只保存业务标识;
- 某些展示信息能否异步更新或适当冗余;
- 下游失败时上游怎样处理;
- 是否形成循环依赖;
- 一个请求跨越了多少边界。
如果两个服务总是同时调用、同时发布和同时修改,拆分可能没有带来实际收益。
事务边界会影响服务边界
强一致业务如果被拆到多个服务,处理难度会明显增加。
例如一个操作需要同时写入两类数据,可以先问:
- 它们是否属于同一业务聚合;
- 是否必须同时成功或失败;
- 能否调整数据归属,让操作在单一服务完成;
- 是否允许短暂不一致;
- 失败后是否有明确补偿方式。
必须立即一致
-> 优先收敛到单一服务与本地事务
允许最终一致
-> 考虑事件通知和补偿
只是查询展示
-> 接口查询或适当冗余不能因为已经选择消息队列,就把所有跨服务事务都交给异步消息。
独立扩展也是拆分依据
视频上传和媒体处理可能比普通查询消耗更多资源;推荐计算和评论写入也有不同特征。如果某类能力需要独立扩容、限流或故障隔离,它更适合拥有清楚边界。
但“未来可能扩展”不能成为无限拆分的理由。第一版数据量和调用关系还不明确时,可以先保持边界清晰、实现简单,再根据实际压力调整。
管理端不是所有业务的复制品
管理服务容易被写成一个可以直接操作所有表的“大后台”。这样虽然开发方便,却会绕过各业务服务自己的规则。
更合适的方向是:
- 管理服务负责管理员认证、角色和治理入口;
- 具体业务状态仍由对应业务服务处理;
- 管理端通过清晰接口执行审核、禁用或删除;
- 操作日志记录谁在什么时间执行了什么动作。
管理权限更高,但不应该意味着可以跳过业务约束。
服务边界需要通过代码验证
画完架构图后,我会在开发中继续观察:
- 公共模块是否越来越大;
- DTO 是否在多个服务间反复复制;
- 服务间调用是否过于频繁;
- 数据库是否仍被跨服务访问;
- 一个需求是否总要同时改多个服务;
- 测试时是否难以独立启动模块。
这些现象比图上的方框更能说明边界是否合理。
当前使用的检查表
| 维度 | 需要回答的问题 |
|---|---|
| 业务 | 是否围绕完整的业务能力 |
| 数据 | 核心数据由谁负责 |
| 事务 | 哪些操作必须在同一事务内 |
| 调用 | 是否出现过长或循环调用 |
| 变化 | 是否能够相对独立演进 |
| 部署 | 是否值得独立启动和扩展 |
| 故障 | 下游异常时影响范围是什么 |
服务边界不是一次确定后永远不变。我会先按当前业务和数据归属建立边界,再在实现、联调和部署过程中根据实际调用关系调整。
微服务拆分时,服务边界应该围绕业务能力、数据所有权、事务范围和独立变化来确定。拆得过粗会失去隔离意义,拆得过细会把复杂度转移到网络调用和一致性处理中。适合当前系统的边界,才是有价值的边界。