企业业务系统架构选型与渐进式演进
一句话理解架构选型不是“微服务一定先进”而是根据业务边界、规模、团队、交付周期、运维能力和一致性要求在当前约束下选择总成本最低、还能继续演进的方案。一、先判断问题再选择架构架构设计前先回答判断维度需要确认的问题业务边界模块之间是否有清晰的职责边界是否存在稳定的业务域规模用户数、并发量、数据量和峰值是否已经超过单体承载能力团队是否有足够的人力维护多个服务、部署链路和监控体系交付项目是快速交付还是需要多个团队长期独立迭代数据模块之间是否强依赖同一事务跨库一致性是否可接受运维是否具备容器、服务发现、链路追踪、灰度发布等能力演进哪些模块未来可能独立扩容或独立发布不要先决定“用微服务”再反过来找理由。先把约束写清楚结论才可解释。二、三种架构形态形态特点适用场景主要代价传统单体一个应用、一个部署单元模块边界较弱小型系统、快速验证、业务简单代码容易耦合发布影响面大模块化单体一个部署单元但按业务域分包、分层和隔离企业内部系统、中等规模、交付优先需要团队遵守模块边界微服务多个业务服务独立部署和扩展边界稳定、团队较大、模块需独立演进调用、事务、部署、监控和运维复杂模块化单体不是“没有架构”而是在一个进程内维护清晰的业务边界。它可以是微服务之前的稳健阶段也可以是长期合理的终态。三、为什么企业内部系统不一定要微服务以 SRM、ERP、政企办公等内部管理系统为例常见约束是用户规模和并发量相对可控业务模块之间存在较强事务关联项目交付周期有限团队规模不大客户更关心稳定交付和问题响应多服务部署会增加运维和现场交付成本。这类系统可以采用Vue3 / React 前端 ↓ HTTP/REST Nginx ↓ Spring Boot 模块化单体 ├── supplier 供应商 ├── sourcing 寻源 ├── purchase 采购订单 ├── receiving 收货与质检 ├── settlement 对账结算 └── common 鉴权、日志、异常、导出 ↓ MySQL Redis MQ前后端分离、模块化和统一工程规范已经可以解决很多问题不需要为了“架构先进”引入分布式事务和服务治理成本。四、模块化单体怎么设计才不会变成大泥球1. 按业务模块分包不要只按 Controller、Service、Mapper 全局分成三个大目录可以在业务域内保持分层order/ ├── controller/ ├── service/ ├── domain/ ├── mapper/ └── dto/2. 明确模块依赖方向Controller 只处理协议、鉴权和参数校验Service 负责用例编排Domain 承载核心业务规则Mapper 负责数据访问模块之间通过明确的接口交互不直接修改对方数据公共模块只放真正通用的能力避免变成新的耦合中心。3. 预留拆分边界如果未来可能拆分应提前做好模块自己的业务包和数据访问边界业务对象与外部 DTO 的隔离跨模块操作通过应用服务或领域事件不依赖对方内部表结构记录模块调用和消息契约。五、什么时候适合拆成微服务出现以下信号时才考虑拆分某个模块需要独立扩容某个模块发布频繁已经影响其他模块业务边界稳定团队可以独立负责某个模块需要不同的技术栈或资源配置数据规模和访问模式明显不同故障隔离收益超过分布式复杂度。拆分不是一次性重写可以按以下路径演进传统单体 ↓ 整理依赖与模块边界 模块化单体 ↓ 识别独立扩展/发布的稳定业务域 优先拆出边界清晰的服务 ↓ 补齐注册、配置、监控、链路和发布能力 渐进式微服务六、服务拆得过细会带来什么问题一次业务请求跨越多个服务链路变长网络超时、重试和熔断成为业务必须处理的问题跨服务事务需要最终一致性或分布式事务本地调试和测试成本增加发布、配置、监控和告警数量增加服务数量超过团队维护能力后系统稳定性反而下降。因此服务拆分的原则不是“越细越好”而是业务内高内聚、业务间低耦合、拆分后有独立收益。七、DDD 在架构选型中的作用DDD 不等于把项目目录改成domain就完成了。它的实际价值是帮助团队识别限界上下文建立统一语言找到聚合根和业务边界区分领域规则与技术实现决定哪些边界适合成为模块或服务。例如采购系统可以识别供应商、寻源、订单、收货质检、结算等业务上下文。是否拆成微服务还要继续结合规模和运维约束判断。