很多团队一上来就问"要不要上微服务"。我们的答案通常是:先把单体写对。绝大多数企业管理系统的真实并发量和团队规模,一个结构良好的单体应用足以支撑很多年。真正决定系统寿命的,是代码内部的边界,而不是进程的数量。
第一阶段:分层清晰的单体
用 ASP.NET Core 起步时,坚持四条纪律:
- 按业务领域分包,而不是按技术分层分包。订单、库存、客户各自成模块,模块之间不直接引用对方的数据表;
- 依赖注入贯穿始终,业务服务只依赖接口,方便日后替换实现;
- EF Core 的 DbContext 按领域拆分,避免一个上千张表的巨型上下文;
- 所有写操作走显式事务,关键流程记录审计日志。
这一阶段的产出是一个部署简单、内部边界清晰的单体。它已经能覆盖大多数企业三五年的需求。
第二阶段:模块化单体
当某个模块明显变重——比如报表统计拖慢了订单写入——把单体升级为"模块化单体":
- 每个业务模块独立项目(class library),只暴露公开契约;
- 跨模块通信改用内存消息总线(如 MediatR),不再直接调用对方服务;
- 重查询场景引入读写分离:写走主库,报表查询走只读副本或预计算表;
- 热点数据进 Redis,缓存键按模块划分命名空间。
这一步不改变部署形态,但为拆分做好了全部准备。
第三阶段:按需拆分,而不是全部拆分
只有当某个模块出现独立的扩展需求——团队独立迭代、发布节奏不同、资源消耗悬殊——才把它拆成独立服务:
- 优先拆读多写少的模块(报表、门户 API),风险最低;
- 拆分前先把跨模块调用从内存总线切换为 HTTP/gRPC 契约,保证行为一致;
- 数据库同步拆分,禁止两个服务共享一张表;
- 补上分布式事务的功课:能用最终一致性就别用强事务。
一句话总结
架构演进的目标不是"先进",而是每一步都只引入当前需要的复杂度。单体写对,模块化做透,拆分就是水到渠成,而不是伤筋动骨。