架构风格与模式58 条

微服务架构风格

按业务能力把系统拆成可独立部署的小服务,各自拥有数据存储并通过轻量协议通信;带来独立演进与弹性收益,同时引入分布式事务、运维与治理成本。

微服务是什么

微服务把系统按业务能力拆成一组可独立部署的小服务,每个服务拥有自己的数据存储,通过轻量协议(HTTP/JSON、gRPC、消息)通信,并可由独立团队端到端负责。它换来独立发布、按需伸缩与技术异构的自由度,代价是把进程内调用换成网络调用,一致性问题、运维复杂度和调试难度随之上升。评价一个系统是否“微服务”,看的是能否独立部署与独立演进,而不是服务数量多少。

基本信息

划分依据业务能力与限界上下文,而非技术分层
通信方式同步 REST/gRPC 与异步消息并存,按场景选择
数据归属服务自管数据,禁止跨服务直接读写他人库表
部署单元一个服务一个可独立发布的制品,通常跑在容器编排平台上
前提条件成熟的 CI/CD、集中日志与链路追踪、自动化测试与灰度能力

典型使用场景

  • 团队规模增长后发布互相阻塞:把高频变更的业务域拆出独立发布链路
  • 资源画像差异大:订单写入重、报表查询重,分开后可各自伸缩
  • 技术异构需求:推荐模块用 Python 生态,交易模块保持 Java
  • 故障隔离诉求:非核心模块异常不应拖垮主交易链路
  • 多端多区域部署:把需要就近部署的能力独立成服务
  • 外部集成频繁:为每个第三方对接建立独立边界,避免污染核心模型

关键特征

特征说明
独立部署每个服务可单独发布与回滚,发布节奏由团队自定
业务能力划分边界对齐业务域,避免按技术层切分带来的跨域改动
数据去中心化服务自管数据,避免共享库造成的事实耦合
基础设施自动化依赖流水线、监控告警、弹性调度,靠人肉运维不可持续
面向失败设计超时、重试、熔断、降级是默认配置而不是事后补丁

代价与对策

代价表现常见对策
分布式事务跨服务写操作无法用本地事务保证Saga、事件驱动最终一致、对账与补偿
运维复杂度服务数量与实例数量成倍增长容器编排、统一日志、指标与追踪三件套
调试困难一次请求跨多个进程,本地断点失效关联 ID 贯穿全链路,集中式链路追踪
契约演进一个接口多个消费者,改字段就出事接口版本化、消费者驱动契约测试
组织成本团队边界与业务边界错位导致反复协调先对齐团队与业务域,再定服务边界
服务边界往往与团队沟通结构互相塑造,先想清楚谁负责哪个业务域,再决定切几刀,比先画架构图更有效。
多个服务共用一套库表时,schema 变更会同时影响所有服务,这种系统通常只是“分布式单体”,拆分的收益拿不到,复杂度却全部承担。

拆分前的检查

检查项判断标准不通过时的建议
发布独立性单个服务能否独立构建、发布与回滚先补流水线与环境隔离
数据边界每个服务的表能否自成一簇、少联表先完成表归属梳理再谈拆分
观测能力能否按请求追踪跨服务的调用链先建关联 ID 与链路追踪
运维承载故障时是否有人能在分钟级定位先建监控告警与值班机制
团队边界每个服务是否有明确负责的团队先调整组织与职责再造服务

易错点

  • 按技术层拆服务(用户服务、文件服务、消息服务),一次业务改动仍要跨多个服务发布
  • 团队规模与自动化能力不足时上微服务,得到的是分布式单体:复杂度上升,发布效率没提高
  • 忽略超时与重试设计,某个下游变慢时线程池被占满,故障沿调用链向上扩散
  • 服务间共享数据库以图方便,schema 成为隐式契约,任何改动都得全体协调
  • 没有端到端可观测性就拆分,线上定位一个问题要逐个服务翻日志,排障时间显著变长

数据来源与参考

  • James Lewis & Martin Fowler《Microservices》(2014)
  • Sam Newman《Building Microservices》(2nd Edition, O'Reilly)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌