云原生基础与微服务
从 CNCF 定义与四大要素出发,理解 12 要素应用、单体到微服务的演进、服务拆分/通信/发现/治理,以及熔断、限流、降级等容错模式。
🎯学习目标
- 掌握 CNCF 对云原生的定义及四大核心要素;
- 了解 12 要素应用(12Factor App)的核心原则;
- 对比单体架构与微服务架构,理解服务拆分策略与原则;
- 掌握微服务通信方式(REST / gRPC / 消息队列)及选型;
- 理解服务注册与发现、负载均衡、API 网关;
- 掌握熔断器、限流、降级等容错模式与 Docker Compose 编排。
1云原生的定义(CNCF)
拆解理解:
• Cloud:应用长在云上(具备云计算五大本质:按需自服务、弹性扩展、资源池化、网络访问、按量计费);
• Native:应用从写代码第一天起,就是为适应云环境而设计的。
2四大核心要素 ⭐
容器化
Containerization微服务
Microservices声明式 API
Declarative APIs不可变基础设施
Immutable Infra可变 vs 不可变基础设施
| 对比 | 可变基础设施 | 不可变基础设施 |
|---|---|---|
| 更新方式 | SSH 登录服务器手动修改 | 构建新镜像,滚动替换 |
| 环境一致性 | 低(易配置漂移、"雪花服务器") | 高(镜像统一) |
| 回滚 | 困难 | 简单(用旧版本镜像) |
| 可审计性 | 弱 | 强(镜像版本化管理) |
3十二要素应用(12Factor App)
由 Heroku 联合创始人 Adam Wiggins 于 2011 年提出,为构建现代 SaaS 应用提供最佳实践指南。
| 要素 | 核心思想 |
|---|---|
| 基准代码 Codebase | 一份代码库对应多份部署 |
| 依赖 Dependencies | 显式声明并隔离依赖 |
| 配置 Config ⭐ | 将配置存储在环境变量中(K8s ConfigMap / Docker 环境变量) |
| 后端服务 Backing Services | 把后端服务当作附加资源 |
| 构建/发布/运行 | 严格分离构建和运行阶段 |
| 进程 Processes ⭐ | 以无状态进程运行(反模式:Session Sticky 会话粘滞) |
| 端口绑定 Port Binding | 通过端口绑定提供服务 |
| 并发 Concurrency | 通过进程模型横向扩展 |
| 易处理 Disposability ⭐ | 快速启动、优雅终止(SIGTERM 后完成当前请求再退出) |
| 开发/生产等价 ⭐ | 尽可能保持各环境一致(Docker + CI/CD) |
| 日志 Logs | 把日志当作事件流 |
| 管理进程 | 后台管理任务作为一次性进程运行 |
4单体架构 vs 微服务架构 ⭐
单体架构:一个紧密耦合的整体,开发快、部署简单,但难以独立扩展和迭代。
微服务(Martin Fowler & James Lewis, 2014):将应用构建为一组小型、自治的服务,每个围绕特定业务能力构建,独立部署,通过轻量级机制(通常 HTTP API)通信。
核心特征与对比
| 维度 | 单体架构 | 微服务架构 |
|---|---|---|
| 代码组织 | 所有功能一个代码库 | 每个服务独立代码库 |
| 部署 | 整体打包部署 | 各服务独立部署 |
| 扩展 | 整体扩展 | 按需扩展特定服务 |
| 技术栈 | 统一 | 可混合多语言/框架(技术异构) |
| 数据库 | 共享数据库 | 每服务独立数据库 |
| 故障影响 | 一模块故障可能整体崩溃 | 单服务故障不影响整体 |
| 开发速度 | 初期快、后期急剧变慢 | 初期慢(基础设施复杂)、后期持续高效 |
微服务核心特征:单一职责、独立部署、独立扩展、技术异构、轻量级通信、去中心化治理、去中心化数据(Database per Service)、容错设计(熔断/降级/重试)。
5服务拆分策略与原则
如何确定服务边界?
- ① 按业务领域拆分(DDD):基于领域驱动设计的限界上下文(Bounded Context),每个上下文对应一个微服务。例:电商系统 = 用户服务 + 商品服务 + 订单服务 + 支付服务 + 库存服务。
- ② 按数据边界拆分:每服务拥有自己的数据库,服务间不直接访问对方数据库,通过 API 或事件交换数据。
- ③ 按变更频率拆分:变更频率高的功能独立为服务,稳定功能保持在一起。
拆分原则
| 原则 | 说明 |
|---|---|
| 高内聚 | 相关功能放在同一服务内 |
| 低耦合 | 服务间依赖最小化 |
| 可独立部署 | 改一个服务不需重新部署其他服务 |
| 适当粒度 | 既不过粗(变成小单体)也不过细(网络开销大) |
6微服务通信方式:REST vs gRPC
同步通信
| 对比 | REST | gRPC |
|---|---|---|
| 协议 | HTTP/1.1(文本) | HTTP/2(二进制帧) |
| 数据格式 | JSON(可读性好) | Protobuf(二进制,体积小 3~10 倍) |
| 接口定义 | OpenAPI/Swagger(可选) | .proto 文件(强制 IDL) |
| 代码生成 | 可选 | 自动生成多语言客户端/服务端 |
| 流式 | 不原生支持 | 支持四种模式(含双向流) |
| 浏览器 | 完美支持 | 需 gRPC-Web 代理 |
| 适用 | 对外 API、Web 前端调用 | 内部微服务间高性能通信 |
syntax = "proto3";
service UserService {
rpc GetUser (GetUserRequest) returns (User) {}
rpc ListUsers (ListUsersRequest) returns (stream User) {} // 服务端流式
}
message GetUserRequest { string user_id = 1; }
message User { string id = 1; string name = 2; string email = 3; }
异步通信:消息队列
以消息队列为核心(Kafka、RabbitMQ),将生产者消息暂存并异步交付给消费者,实现服务解耦。优势:削峰填谷、保障最终一致性。适用于事件通知、异步处理、跨服务数据同步。
7服务发现与注册
微服务实例 IP/端口动态变化(扩缩容、故障重启、迁移),硬编码地址行不通,需动态发现服务位置。
| 模式 | 核心流程 | 优点 | 缺点 |
|---|---|---|---|
| 客户端发现 | 服务 A 直接查注册中心拿实例列表,本地负载均衡后调用 | 无额外网络跳转、延迟低 | 客户端需集成发现/负载逻辑,与语言耦合 |
| 服务端发现 | 服务 A 请求发给网关/负载均衡器,由其查注册中心并转发 | 客户端逻辑简单、语言无关、策略统一 | 多一跳延迟,网关需高可用 |
主流服务注册中心
| 注册中心 | 一致性模型 | 特点 |
|---|---|---|
| etcd | 强一致(Raft) | K8s 默认使用,键值存储 |
| Consul | 强一致(Raft) | 内置服务发现、健康检查、KV |
| ZooKeeper | 强一致(ZAB) | 老牌,配置管理 |
| Nacos | AP/CP 可切换 | 阿里开源,服务发现 + 配置管理 |
8负载均衡
将流量/负载分发到多个实例,提高可用性、提升性能、避免单点过载。
| 算法 | 原理 | 适用场景 |
|---|---|---|
| 轮询 Round Robin | 按顺序依次分发 | 实例性能相同 |
| 加权轮询 | 按权重比例分发 | 实例性能不均 |
| 最少连接 | 分发到连接数最少的实例 | 长连接场景 |
| 随机 | 随机选择 | 简单场景 |
| 一致性哈希 | 相同请求哈希到相同实例 | 缓存命中率优化 |
| IP 哈希 | 按客户端 IP 哈希 | Session 亲和性 |
| 层次 | 层级 | 说明 |
|---|---|---|
| L4 负载均衡 | TCP/UDP 层 | 基于 IP+端口转发,速度快 |
| L7 负载均衡 | HTTP 层 | 基于 URL/Header 智能路由,功能丰富 |
9容错模式:熔断 / 限流 / 降级 ⭐
问题:级联故障(雪崩效应)
A 调 B、B 调 C,若 C 崩溃 → B 线程阻塞 → 线程池耗尽 → A 也阻塞 → 整条链路崩溃。
熔断器三种状态
| 状态 | 行为 |
|---|---|
| 关闭 Closed | 正常转发,统计失败率;失败率达阈值切到 Open |
| 打开 Open | 直接返回降级响应(fast-fail),不调用下游;超时后进入 HalfOpen |
| 半开 HalfOpen | 放少量探测请求;成功则 Closed,失败则回 Open |
配套容错模式
重试 Retry(配合指数退避)、超时 Timeout(防长时间阻塞)、舱壁 Bulkhead(资源隔离,独立线程池/连接池)、降级 Fallback(返回默认值或缓存)。
限流算法
| 算法 | 原理 | 特点 |
|---|---|---|
| 固定窗口计数器 | 窗口内计数,超阈值拒绝 | 简单,有边界突刺问题 |
| 滑动窗口计数器 | 滑动窗口平滑限流 | 更平滑 |
| 令牌桶 Token Bucket | 固定速率生成令牌,请求消耗令牌 | 允许突发流量 |
| 漏桶 Leaky Bucket | 请求入桶,固定速率流出 | 严格平滑流量 |
降级策略
返回默认值(推荐服务降级→热门商品)、返回缓存(用户画像降级→缓存画像)、功能裁剪(高峰关闭评论/推荐)、流量排队(秒杀排队)。
10API 网关与 Docker Compose
API 网关
微服务架构的统一入口,接收所有客户端请求,进行路由、认证、限流、协议转换后转发到后端微服务。功能:请求路由、认证鉴权、限流熔断、负载均衡、协议转换(外部 REST → 内部 gRPC)、请求聚合、日志监控。
Docker Compose 多容器编排
用于定义和运行多容器 Docker 应用,使用 YAML 描述服务、网络和卷,一次声明、一键拉起整个集群(docker-compose up)。五大顶级 key:services、networks、volumes、configs、secrets。
services:
gateway:
build: ./gateway
ports: ["8080:80"]
depends_on: [userservice]
networks: [frontend, backend]
userservice:
image: user:latest
environment: [DB_HOST=userdb]
networks: [backend]
userdb:
image: postgres:15
volumes: [./data:/var/lib/postgresql/data]
networks: [backend]
networks:
frontend: # 外部可访问
driver: bridge
backend: # 内部服务网络
driver: bridge
internal: true # 禁止外部访问
userdb:5432 访问数据库。⭐重点例题
🎯自测(点击展开)
云原生的四大核心要素是什么?
12 要素中"配置"应该存在哪里?
微服务为什么要"去中心化数据"?
熔断器三种状态及转换?
限流的令牌桶和漏桶有何区别?
Docker Compose 中容器如何互相找到对方?
📝强化题库
选择题点选即时判分;填空题输入后"检查"或"显示答案"。