微服务
微服务架构将大型应用拆分为独立部署的服务单元,通过 API 通信协作,解决单体应用的扩展性和维护性问题。
提示
微服务架构:选型、注册中心、治理
与单体架构对比
| 维度 | 单体架构 | 微服务架构 |
|---|---|---|
| 部署 | 整体部署 | 独立部署 |
| 扩展 | 整体扩展 | 按需扩展 |
| 技术栈 | 统一 | 灵活多样 |
| 故障隔离 | 一挂全挂 | 单服务故障不影响其他 |
| 复杂度 | 开发简单 | 运维复杂 |
核心问题
| 问题 | 说明 |
|---|---|
| 服务通信 | 服务如何发现彼此、互相调用 |
| 数据一致性 | 分布式下强一致性的代价急剧上升 |
| 故障应对 | 超时、熔断、限流是架构的一部分 |
| 配置管理 | 多个服务如何统一管理配置 |
服务拆分方法论(DDD)
微服务拆分最大的难题是「边界画在哪里」。业界通行的方法是 DDD(领域驱动设计):
限界上下文(Bounded Context)
一个限界上下文是一个显式边界,边界内部有统一的领域模型和语言(Ubiquitous Language)。微服务与限界上下文一一对应。
拆分原则:
按业务能力/限界上下文拆分,而非按技术层拆分
(不拆成 user-controller-service-dao 四个服务!)典型电商拆分示例:
| 限界上下文 | 微服务 | 独立数据 |
|---|---|---|
| 商品目录 | product-service | product 库 |
| 订单履约 | order-service | order 库 |
| 库存管理 | inventory-service | inventory 库 |
| 支付结算 | payment-service | payment 库 |
康威定律
设计系统的组织,其产生的设计等同于组织之间的沟通结构。——Melvin Conway, 1968
团队结构与系统架构互相塑造:两个必须频繁沟通的团队,其系统往往需要集成在同一模块/服务内。反过来,架构调整往往需要组织调整配合(逆康威操作)。所以微服务的划分应与团队所有权对齐:一个服务由一个 2-5 人小团队长期拥有。
拆分信号与粒度判断
| 信号 | 说明 |
|---|---|
| 部署耗时长 | 单体发布超过 30 分钟 |
| 回归成本高 | 一个模块变更需全量回归 |
| 团队协作冲突 | 10+ 人改同一代码库,冲突频繁 |
| 流量不均 | 某模块需要独立扩缩容 |
| 技术栈诉求 | 不同模块需要不同语言/框架 |
拆分过细的症状:两个服务必须同步发版、共享数据库表、服务间调用链超过 5 跳。服务数量不是荣誉,能独立演化的服务才是。
技术选型总览
服务注册与发现
| 组件 | CAP | 特点 | 适用场景 |
|---|---|---|---|
| Eureka | AP | 客户端注册,心跳检测 | Spring Cloud 首选 |
| Zookeeper | CP | 临时节点,watch 机制 | 需要强一致 |
| Nacos | AP/CP | 注册+配置二合一 | 阿里面向云原生 |
服务通信协议
| 协议 | 特点 | 适用场景 |
|---|---|---|
| HTTP/REST | 通用、跨语言 | Web 服务、轻量级 |
| gRPC | 二进制序列化、高性能 | 微服务内部、高并发 |
| Dubbo | RPC 高性能 | Java 生态、高吞吐 |
同步 vs 异步
| 模式 | 组件 | 说明 |
|---|---|---|
| 同步调用 | REST、gRPC、Dubbo | 请求等待响应 |
| 异步消息 | Kafka、RabbitMQ、RocketMQ | 发送后不等待,解耦业务 |
负载均衡
| 类型 | 组件 | 说明 |
|---|---|---|
| 客户端负载均衡 | Ribbon、Feign | 服务自己选择目标 |
| 服务端负载均衡 | Nginx | 请求先到 Nginx 再分发 |
配置管理
| 组件 | 特点 | 适用场景 |
|---|---|---|
| Nacos | 配置+注册二合一 | 轻量级、快速上手 |
| Apollo | 权限管理、环境隔离 | 企业级、大规模 |
| Spring Cloud Config | Git 后端 | 结合 Git 流程 |
熔断降级
| 组件 | 现状 | 隔离方式 | 限流 |
|---|---|---|---|
| Hystrix | 停止维护 | 线程池隔离 | 不支持 |
| Sentinel | 阿里活跃维护 | 信号量/并发数 | 支持 |
注意
选型建议
新项目使用 Sentinel,支持 QPS 和并发数限流,提供完善的控制台动态调整规则。
微服务治理
容错策略
| 策略 | 说明 | 触发条件 |
|---|---|---|
| 熔断 | 快速失败,阻止故障传播 | 失败率超过阈值 |
| 降级 | 返回兜底数据 | 熔断或主动开关 |
| 限流 | 控制单位时间请求量 | QPS 超限 |
| 隔离 | 资源隔离限制影响范围 | 舱壁模式 |
服务安全
| 问题 | 方案 |
|---|---|
| 身份认证 | OAuth2、JWT |
| 权限控制 | RBAC |
| 敏感数据 | 加密存储、脱敏输出 |
| 接口防护 | 签名验证、限流 |
可观测性
| 类型 | 工具 | 作用 |
|---|---|---|
| 日志 | ELK | 问题定位 |
| 监控 | Prometheus + Grafana | 指标可视化 |
| 链路追踪 | Zipkin、Jaeger | 请求全链路 |
治理优先级
微服务治理按「先保命、再体验、后合规」的顺序分层落地:
提示
先保证可用,再优化性能,最后完善安全。
Spring Cloud 组件
Spring Cloud 是最主流的微服务框架,核心组件详见 SpringCloud。
| 层级 | 组件 | 职责 |
|---|---|---|
| 服务构建 | Spring Boot | 微服务基础框架 |
| 服务治理 | Eureka / Nacos | 服务注册与发现 |
| 负载均衡 | Ribbon / OpenFeign | 客户端负载均衡 |
| 服务容错 | Hystrix / Sentinel | 断路器保护 |
| API 网关 | Zuul / Gateway | 智能路由、过滤 |
| 配置管理 | Config / Apollo / Nacos | 外部化配置 |
| 分布式事务 | Seata | 分布式事务解决方案 |
| 分布式跟踪 | Sleuth + Zipkin | 请求链路跟踪 |
跨服务数据一致性依赖 seata 的 AT/TCC/SAGA 方案,异步解耦与削峰填谷依赖 Kafka / RabbitMQ 消息队列,服务架构整体脉络见 架构设计 MOC。
部署技术
| 组件 | 说明 |
|---|---|
| Docker | 容器化镜像,统一环境 |
| Kubernetes | 容器编排、服务治理 |
| Jenkins | CI/CD 持续集成 |
微服务部署核心:容器化 + 自动化 + 弹性伸缩。
FAQ
Q: 微服务架构适合所有项目吗? A: 不适合。微服务引入分布式复杂性(网络、事务、观测),团队小于 10 人、单机可支撑、发布不频繁的项目用单体更高效。微服务的收益(独立部署、独立扩展、故障隔离)只有规模上来后才明显。判断标准:单体带来的痛苦是否超过分布式带来的成本。
Q: 数据去中心化后,跨服务查询怎么办? A: 三种方案:1) 服务间 API 调用聚合(实时但增加耦合);2) 读模型冗余——把需要的数据复制到本服务库(CQRS 读模型,常用);3) 引入数据同步中间件。禁止的做法是让多个服务直连同一张表,这会把服务边界退化回单体。
Q: 一个服务该多大? A: 没有标准行数,正确标准是「团队规模和业务内聚」。一个服务应该能由一个小团队(2-5 人)独立开发、测试、部署、运维,且修改不需要与其他服务同步发版。过大(上帝服务)失去微服务意义,过小(微过头的 nano-service)增加治理成本。