E8 - 部署 + FaaS + 集群架构
事件驱动微服务怎么部署——Hosted Service vs 自建 Cluster vs CMS 集成;FaaS 作为部署形态;CI/CD 流水线。
一句话
部署 3 大选择 = Hosted Service / 自建 Cluster / CMS 集成;FaaS = Serverless 函数即服务;CI/CD = 流水线自动化——选择取决于规模 + 团队能力 + 成本。
这本书在这一层说了什么
本层融合 EDM Ch 9(FaaS 部分)+ Ch 11(集群架构)+ Ch 14(基础设施程序化)+ Ch 16(CI/CD)。
Bellemare Ch 16 关键论断:
"An organization managing only a few dozen services can get away with a few custom deployment processes, but any organization seriously invested in microservices, event-driven or otherwise, must invest in standardization and streamlining its deployment processes."
核心论点 5 个:
- Deployment 3 大架构选择
- FaaS(Functions-as-a-Service)
- 容器编排系统(CMS)集成
- 基础设施程序化(Infrastructure as Code)
- CI/CD 流水线
是什么
1. 部署架构 3 大选择
选择 1: Hosted Service(托管服务)
Bellemare 关键论断:
"The first, and simplest, way to manage a cluster is to just pay someone to do it for you... This is usually the most expensive option in terms of dollars spent when compared to the projected costs of starting your own cluster, but it significantly reduces the operational overhead and removes the need for in-house expertise."
特征:
- 第三方托管(AWS / GCP / Azure)
- 监控 / 运维外包
- 全 serverless 化趋势
代表服务:
- Amazon Managed Flink / Spark
- Google Cloud Dataflow(Beam Runner)
- Databricks Spark
适用:
- 团队小 + 无基础设施能力
- 业务快速增长
- 短期项目选择 2: 自建 Full Cluster(自建集群)
Bellemare 关键论断:
"This deployment is the historical norm for heavyweight clusters, as it closely models the original Hadoop distributions. It is common in situations where the heavyweight framework will be used by services requiring a large number (hundreds or thousands) of worker nodes."
特征:
- 独立的 scalable 资源集群
- 与 CMS 解耦
- 历史 Hadoop 风格
适用:
- 大规模(数百/数千节点)
- 稳定业务
- 有基础设施能力选择 3: CMS 集成(容器编排集成)
Bellemare 关键论断:
"A cluster can also be created in conjunction with the container management system... Some of the major benefits of deploying your cluster on the CMS is that you gain the monitoring, logging, and resource management it provides."
模式 A:CMS 部署 Cluster
- Cluster 部署在 CMS 资源上
- 受益于 CMS 监控 + 日志
模式 B:CMS 调度作业
- CMS 直接调度单个作业
- 无独立 Cluster
- Spark/Flink 原生支持 K8s2. FaaS(Functions-as-a-Service)
Bellemare Ch 9 关键定义:
"Functions-as-a-Service (FaaS) is a 'serverless' solution that has become increasingly popular in recent years. FaaS solutions enable individuals to build, manage, deploy, and scale application functionality without having to manage infrastructural overhead."
特征:
特征:
- 函数触发即执行
- 执行完即终止
- 无服务器管理
- 自动按负载扩缩容Bellemare 关键洞察:
"It may be helpful to think of a FaaS solution as a basic consumer/producer implementation that regularly fails. A function will always end after a predetermined amount of time, and any connections and state associated with it will go away. Keep this in mind as you design your functions."
关键洞察:FaaS = 周期失败的消费者——任何持久状态必须外置。
FaaS 适用场景:
- 简单数据转换
- 事件过滤
- 触发下游动作
- 中等复杂度业务逻辑
FaaS 不适用:
- 长时间运行(小时级)
- 复杂状态管理
- 高频低延迟要求
3. FaaS BC 边界
Bellemare Ch 9 关键论断:
"The functions and internal event streams composing a solution must strictly belong to a bounded context, such that the owner of the function and data is clearly identified."
维护 BC 边界的 4 大实践:
1. 数据存储对外 BC 私有
2. 与其他 BC 通信用标准接口(REST / 事件)
3. 维护"函数属于哪个 BC"的元数据
4. 函数代码放在按 BC 映射的仓库4. FaaS Offset 提交策略
Bellemare Ch 9 关键论断:
"Committing offsets only after processing has completed for a given event or batch of events is a FaaS best practice."
两种策略:
| 策略 | 时机 | 风险 |
|---|---|---|
| 处理完成后 commit(推荐) | 函数完成后 | 低(标准 At-Least-Once) |
| 函数开始时 commit(危险) | 函数启动后 | 高(数据丢失可能) |
Bellemare 关键警告:
"Committing offsets before processing has completed can be problematic, however. If the function is unable to successfully process an event, and numerous retries fail, then data loss is likely."
5. 基础设施程序化(Infrastructure as Code)
Bellemare Ch 14 关键论断:
"Programmatic bringup of event brokers... programmatic bringup of compute resources."
程序化的 4 大领域:
1. Brokers 程序化部署
- Terraform / Pulumi / Ansible
- 跨云一致性
2. 计算资源程序化
- K8s manifest
- Helm chart
3. 跨集群数据复制
- MirrorMaker 2 (Kafka)
- 灾备 / 多活
4. 工具部署程序化
- 监控 / 告警 / 日志6. CI/CD 流水线
Bellemare Ch 16 关键论断:
"Continuous integration (CI) is the practice of automating the integration of code changes from multiple contributors into a single software project."
CI/CD 4 大原则:
1. 团队部署自治
- 团队控制自己的测试 + 部署
- 自主决定何时部署
2. 标准化部署流程
- 所有服务用同一流程
- 新服务自动继承流程
3. 必要支持工具
- 重置 consumer offsets
- 清理 state stores
- 检查 schema 演化
- 删除内部事件流
4. 考虑事件流重处理影响
- 重处理可能很慢
- 可能产生下游 spike
- 注意副作用(如重发邮件)Bellemare 关键警告:
"Microservices should be independently deployable, and it is an anti-pattern if they are not. If a particular microservice deployment regularly requires other microservices to synchronize their deployments, it is an indicator that their bounded contexts are ill-defined and should be reviewed."
为什么
为什么 FaaS 部署要注意"周期失败"?
根因:FaaS 平台可能在任意时刻终止函数(资源回收 / 超时)。
修复:
- 状态外置(Redis / DynamoDB)
- 假设"进程随时会消失"
- 设计幂等(重试无副作用)
为什么 Offset 必须在处理完成后提交?
根因:At-Least-Once 需要"先处理后 commit"。
反例(先 commit 后处理):
- 函数启动 → commit offset
- 函数执行失败(3 次重试都失败)
- offset 已 commit → 数据丢失
为什么部署要标准化?
根因:微服务税 = 每个微服务都要部署。
反例(无标准化):
- 每个微服务有自定义部署脚本
- 团队离职 → 脚本无人维护
- 新微服务启动慢(写部署脚本)
修复:CI/CD 模板 + 标准化部署流水线。
为什么部署影响 SLA?
Bellemare 关键洞察:
"Deployments may be disruptive to other services. For instance, rebuilding state stores can result in a significant amount of downtime, while reprocessing input event streams may generate a significant number of events."
修复:
- 蓝绿部署(参考 E10 测试中的部署策略)
- 金丝雀发布
- 流重处理时通知下游
怎么做
Step 1:选择部署架构
决策树:
Q1: 团队规模 < 5 + 业务早期?
是 → Hosted Service(Confluent Cloud / AWS MSK)
否 ↓
Q2: 有 K8s / Docker 能力?
是 → CMS 集成(K8s + Kafka Operator)
否 ↓
Q3: 业务稳定 + 大规模?
是 → 自建 ClusterStep 2:FaaS 函数设计
# AWS Lambda 处理事件
import json
import boto3
def handler(event, context):
# 假设函数随时会被终止
# 状态必须外置
table = boto3.resource('dynamodb').Table('order-state')
for record in event['Records']:
# 处理单个事件
order_id = record['key']
# 幂等检查
existing = table.get_item(Key={'order_id': order_id})
if existing.get('processed'):
continue
# 业务逻辑
order = json.loads(record['value'])
process_order(order)
# 标记处理完成
table.put_item(Item={
'order_id': order_id,
'processed': True,
'result': 'success'
})Step 3:K8s + Kafka 部署(CMS 集成模式)
# kafka-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: kafka
spec:
serviceName: kafka
replicas: 3
selector:
matchLabels:
app: kafka
template:
metadata:
labels:
app: kafka
spec:
containers:
- name: kafka
image: confluentinc/cp-kafka:7.0.0
env:
- name: KAFKA_BROKER_ID
valueFrom:
fieldRef:
fieldPath: metadata.labels['statefulset.kubernetes.io/pod-name']
- name: KAFKA_ZOOKEEPER_CONNECT
value: zookeeper:2181
ports:
- containerPort: 9092Step 4:CI/CD 流水线
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [master]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build & Test
run: |
npm install
npm run lint
npm run test
- name: Compatibility Check
run: |
# Schema 兼容性检查
./scripts/check-schema-compat.sh
- name: Build Image
run: docker build -t myservice:${{ github.sha }} .
- name: Deploy to K8s
run: |
kubectl set image deployment/myservice \
myservice=myservice:${{ github.sha }}Step 5:基础设施即代码
# Terraform: 创建 Kafka Cluster
resource "aws_msk_cluster" "kafka" {
cluster_name = "my-kafka"
kafka_version = "3.5.1"
number_of_broker_nodes = 3
broker_node_group_info {
instance_type = "kafka.m5.large"
ebs_volume_size = 100
client_subnets = [aws_subnet.private_a.id, aws_subnet.private_b.id]
security_groups = [aws_security_group.kafka.id]
}
}什么时候用 / 什么时候不用
用 Hosted Service 的 2 大场景
| 场景 | 关键判断 |
|---|---|
| 小团队 + 业务早期 | 基础设施外包 |
| 短期项目 / 验证期 | 不需要长期投资 |
用 CMS 集成的 2 大场景
| 场景 | 关键判断 |
|---|---|
| 有 K8s 能力 + 中等规模 | 受益于 CMS 监控 + 日志 |
| 微服务数量 > 20 | 标准化部署流程 |
用 FaaS 的 2 大场景
| 场景 | 关键判断 |
|---|---|
| 简单事件处理 / 过滤 | FaaS 适合 stateless 短任务 |
| 负载波动大 | FaaS 自动扩缩容 |
不用 FaaS 的 2 大场景
| 场景 | 原因 |
|---|---|
| 长时间运行任务 | FaaS 15 分钟限制 |
| 复杂状态管理 | FaaS 无持久状态 |
看不见的地方
失效模式 1:FaaS 函数无状态
症状:函数执行失败 → 状态丢失 → 业务错误。
根因:函数依赖本地状态(变量、文件、内存)。
修复:状态外置(Redis / DynamoDB / S3)。
失效模式 2:先 commit offset 后处理
症状:函数处理失败 → offset 已 commit → 数据丢失。
根因:违反 At-Least-Once 原则。
修复:处理成功后才 commit offset。
失效模式 3:部署破坏 SLA
症状:部署期间事件积压 / 服务不可用 → SLA 违反。
根因:未考虑部署的副作用。
修复:蓝绿部署 + 金丝雀 + 部署窗口选择。
失效模式 4:部署未考虑 Schema 兼容性
症状:新版本部署 → 旧消费者崩溃。
根因:新版本事件 Schema 与旧消费者不兼容。
修复:CI 集成 Schema 兼容性检查 + Full Compatibility。
失效模式 5:FaaS 冷启动延迟
症状:FaaS 冷启动 1-5 秒 → 用户首次请求超时。
根因:FaaS 平台首次启动慢。
修复:预热 + provisioned concurrency。
失效模式 6:FaaS 滥用导致成本失控
症状:每事件一个 Lambda → 100万次/月 → 账单爆炸。
根因:未评估 FaaS 单位成本。
修复:低频长任务用 FaaS,高频短任务用长驻服务。
失效模式 7:跨服务同步部署
症状:部署服务 A 必须等服务 B 部署完成。
根因:BC 边界不清晰。
修复:重新审视 BC 边界 + 解耦部署。
相关节点
骨架 A — 世界观
| 节点 | 关联 | 解释 |
|---|---|---|
| wonder-02-emergence-action | 中 | 部署 = "涌现作为"的物理基础设施——决定作为能力 |
| wonder-04-encounter | 中 | FaaS = "照面"的瞬态版本——按需照面事件 |
骨架 B — 工程实践
| 节点 | 关联 | 解释 |
|---|---|---|
| change-management | 强 | 部署 = 变更管理的最终落地 |
| value-stream | 中 | FaaS = 价值流的弹性节点——按负载伸缩 |
状态
E8 概念递进落地完成(融合原书 ch09 + ch11 + ch14 + ch16 = 134KB)。
- 5 个核心论点(3 大部署选择 / FaaS / BC 边界 / IaC / CI/CD)
- 5 步怎么做(含 K8s YAML + Terraform + GitHub Actions)
- 7 个失效模式
- 骨架 A/B 完整映射