层级:速记 01-styles / 深入 d01-styles / 本页=详解。每阶段:背景痛点 → 核心机制 → 代码 → 考点。
背景痛点:2000s 企业并购/信息化烟囱,ERP/CRM/OA 各自独立,重复建设、数据孤岛。需求不是「快」,是「打通」。
核心机制:服务注册-发现-绑定;ESB(企业服务总线)承担路由、协议转换、消息变换、编排。
代码(WebService/SOAP 时代的服务契约,XML 一统天下):
<!-- SOAP 报文:跨语言但重协议 -->
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns:queryCustomer xmlns:ns="http://erp.example.com/">
<custId>10086</custId>
</ns:queryCustomer>
</soap:Body>
</soap:Envelope>
// ESB 思想在 Spring Integration 里的影子:消息路由中枢
@Bean
public IntegrationFlow erpGateway() {
return IntegrationFlow.from("customerChannel")
.enrichHeaders(h -> h.header("SYSTEM", "ERP"))
.<String, String>transform(String::toUpperCase)
.route("headers.SERVICE_NAME", m -> m
.channelMapping("CRM", "crmChannel")
.channelMapping("OA", "oaChannel"))
.get();
}
为什么衰落:ESB 集中治理=集中瓶颈与单点;所有服务经过总线,改总线要全体停机;粗粒度服务复用价值低于预期。
考试考法:SOA 三基本构件(服务注册表/服务/ESB)、「SOAP vs REST」对比、SOA 与微服务的区别表(年年考)。
背景痛点:互联网规模下,单体=发布列车互相等待、一个团队的小改动要全量回归、故障影响整站。
核心机制:按业务能力拆分、每服务独立库、去中心化治理、轻量通信(REST/gRPC/消息)、独立部署、围绕服务组织团队(康威定律的主动利用)。
代码(拆分后的服务间调用——与单体最大的区别:跨网络):
// 订单服务通过 OpenFeign 调库存服务——一次远程调用,必须防御失败
@FeignClient(name = "inventory-service", fallback = InventoryFallback.class)
public interface InventoryClient {
@PostMapping("/api/stock/deduct")
StockResult deduct(@RequestBody DeductReq req);
}
// 降级兜底:库存服务挂了也要能下单(可营销后补扣)
@Component
public class InventoryFallback implements InventoryClient {
public StockResult deduct(DeductReq req) {
return StockResult.later("库存繁忙,已登记延迟扣减");
}
}
拆分是否正确的检验代码(跨服务事务=拆错了的信号):
// 反模式:订单库里直接 JOIN 库存表 = 没拆干净(分布式单体)
@Select("SELECT o.*, s.qty FROM t_order o JOIN t_stock s ON o.item_id=s.item_id")
List<OrderVo> listOrders(); // 禁止!库存表属于库存服务
// 正确姿势:各自查自己库,订单侧只存冗余快照
@Select("SELECT * FROM t_order")
List<Order> listOrders(); // 库存数量通过 API 或事件同步到本地快照
考试考法:拆分原则、微服务 vs SOA 对比、注册中心 CP/AP 选型、熔断降级(Sentinel 术语:熔断规则/降级策略)、分布式事务选型。
背景痛点:几百个微服务的部署/扩缩/自愈/灰度,靠人肉运维不可能。复杂度必须由「平台」吸收。
核心机制:容器(不可变交付物)+ K8s(声明式调度)+ DevOps/CI/CD(流水线)+ 服务网格(治理下沉)。
代码(声明式:你写「终态」,控制器负责收敛):
# deployment.yaml —— 声明「我要3个副本」,不写「怎么启动」
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
spec:
replicas: 3
strategy:
rollingUpdate: { maxSurge: 1, maxUnavailable: 0 } # 滚动发布零停机
template:
spec:
containers:
- name: order
image: registry.cn-hangzhou.aliyuncs.com/timesake/order:v2.1.0
resources:
requests: { cpu: 250m, memory: 512Mi }
limits: { cpu: "1", memory: 1Gi }
readinessProbe: # 就绪探针:没就绪不接流量
httpGet: { path: /actuator/health/readiness, port: 8080 }
就绪探针的架构意义(考试可写的深度点):
# K8s 明明进程活着却不给流量——「存活」与「可服务」分离
livenessProbe: # 进程死了 -> 重启容器(自愈)
httpGet: { path: /actuator/health/liveness, port: 8080 }
readinessProbe: # 依赖的DB没就绪 -> 摘除流量但不重启(区分两类故障)
httpGet: { path: /actuator/health/readiness, port: 8080 }
服务网格(治理从 SDK 下沉到 Sidecar):
# Istio:业务代码零改动,路由规则生效
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: order-vs
spec:
hosts: [order-service]
http:
- route:
- destination:
host: order-service
subset: v2
weight: 10 # 灰度:10%流量进新版
- destination:
host: order-service
subset: v1
weight: 90
考试考法:云原生定义(容器+微服务+DevOps+持续交付的组合方法论)、K8s 核心对象(Pod/Deployment/Service/Ingress)、声明式 vs 命令式、不可变基础设施、滚动发布/灰度发布/蓝绿发布的区别(高频)。
背景痛点:连「容量规划」都不想要了。低频长尾服务(一年调用 100 次)养一个常驻容器纯浪费。
核心机制:事件触发函数实例、按调用计费、平台自动伸缩(含缩到零)。
代码(阿里云函数计算:一个函数即服务):
// 无服务器:HTTP 触发的对账文件校验函数
public class ReconcileHandler implements StreamRequestHandler {
@Override
public void handleRequest(InputStream in, OutputStream out, Context ctx) {
String diff = reconcileService.checkToday(); // 每天凌晨触发一次
if (!diff.isEmpty()) {
ctx.getLogger().warn("对账差异: " + diff);
dingtalk.alert(diff); // 差异告警
}
}
}
代价:冷启动延迟(实例从零拉起百毫秒到秒级)、长任务/有状态受限、厂商锁定。
考试考法:选择题考特性(自动弹性伸缩/按需付费/事件驱动),辨析「Serverless 不是没有服务器,是不用管服务器」。
四阶段一句话串联:
单体慢在「发布耦合」→ 微服务解耦了发布权;
微服务苦在「运维爆炸」→ 云原生用平台吸收运维复杂度;
云原生贵在「常驻资源」→ Serverless 把成本颗粒度切到单次调用。
每一代解决上一代制造的主要矛盾,同时引入新矛盾——这个叙事框架可用于几乎所有架构论文:
| 阶段 | 主要矛盾 | 解决方案 | 新引入的矛盾 |
|---|---|---|---|
| SOA | 系统孤岛 | ESB 集成 | 总线单点+性能 |
| 微服务 | 发布耦合 | 服务自治 | 分布式复杂度 |
| 云原生 | 运维爆炸 | 平台化声明式 | 平台学习成本 |
| Serverless | 资源浪费 | 缩容到零 | 冷启动+锁定 |
你的支付/ERP/PLC 素材映射: