← 返回学习台
D1 · 摄取与转换 34%

Ch05 · EventBridge 事件总线 + 调度

EventBridge 现在是三个东西:Bus、Scheduler、Pipes。考试经常混淆,分清楚就拿分。

🎯 先试试

japanese-climb 的 src/jclimb/core_scheduler.py 现在做的事:每天早上 6 点(按用户本地时区),扫所有用户的 mastery_review_state,挑出今天要复习的话题推送提醒。每个用户可能在不同时区。搬 AWS 选哪个?

💡 讲透

🎣 钩子:定时跑 Lambda——CloudWatch Events 不就行了?为啥 AWS 还要单独搞个 EventBridge Scheduler?

🏠 生活类比:你要给 100 万个朋友每人每天早上发 "起床啦"。
A CW Events:你只有一个全球闹钟,所有人按 UTC 同时收到——日本朋友 0:00 半夜被吵醒。
B Scheduler:你给每个人单独设一个闹钟,写上他们的本地时区,谁该几点响系统替你算。
C Sleep 循环:你 24 小时干瞪着钟,啥都不干就守着 6 点——还把你算工时。
D EC2 cron:你雇了个保姆专门守钟——工资照付,保姆还经常请假(机器要维护)。

👶 三件事一次说清楚

1. EventBridge Scheduler(新独立 service)

替代老 EB Rule 的定时功能。原生时区。每用户可独立 schedule(百万级)。一次性 + 重复都支持。

2. EventBridge Bus + Rules

事件路由:S3 PUT → 触发 Lambda;CloudTrail 事件 → 通知 SNS。基于事件 pattern 匹配。

3. EventBridge Pipes

source → (可选 filter / transform) → target。替代手写 Lambda 当胶水。如 SQS → 过滤 → Step Functions。

graph LR CS[core_scheduler.py
用户注册时
CreateSchedule API] -->|每用户独立| EBS[EventBridge Scheduler
cron + tz=Asia/Tokyo] EBS -->|6am 本地时间| L[Lambda
build_reminder] L --> DDB[DynamoDB
读 mastery_review_state] L --> SNS[SNS
推送给用户] style EBS fill:#fff4ef,stroke:#ff6f3c

🎯 每个选项为什么对/错

❌ A · CloudWatch Events
它能做这事但是 legacy——AWS 已经把它迁移到 EventBridge 旗下了。不支持时区,你只能写 UTC cron。
真实后果:要按用户本地时区?得在 Lambda 里查时区数据库自己算偏移——啰嗦又容易出错(夏令时陷阱)。而且老 EB Rule 上限 ~300/region,百万用户每人独立 schedule 撑不住。
❌ C · Lambda sleep 循环
反模式 — Lambda 是短任务无状态不是常驻服务。"睡到 6 点" = Lambda 计费在 sleep 上烧钱 + 撞 15 分钟上限肯定被砍。
真实后果:你以为省事,账单和 timeout 两头炸。Lambda sleep 这种代码碰到代码审查会被打回。
❌ D · EC2 cron
倒退到运维 EC2:开关机、补丁、监控、HA 全你来。serverless 路线全废。
真实后果:每月多花 $5–20,加上隔三差五 ssh 上去看 cron 跑没跑——或者哪天机器挂了你 24 小时不知道。
✅ B · EventBridge Scheduler
AWS 2022 年专门抽出来的服务,做"什么时间触发什么"。时区原生cron(0 6 * * ? *) + Asia/Tokyo),动态创建/更新/删除百万级 schedule(API 调用),一次性 + 重复都支持,直接触发 200+ AWS 目标。

📌 考点速记

  • 三个 EventBridge 功能分清楚(必考):
    · Scheduler:定时(时区原生、百万动态)
    · Bus + Rules:事件路由(模式匹配)
    · Pipes:source → filter → target(替代胶水 Lambda)
  • Bus:default bus 不能跨账户;custom bus 可以
  • 事件模式语法(content-based filtering):{"detail-type": ["Object Created"]};数组里是 OR;支持 prefix/suffix/numeric/anything-but
  • Schema Registry:自动从事件推 schema,生成 code binding
  • Archive + Replay:默认 archive 关;开了之后可重放某时段事件(关键:考前查灾难恢复题)
  • 跟 SNS 区别:SNS 简单 pub/sub;EventBridge 有模式过滤+多 bus+Schema+Replay+200+ 直接 target
  • EventBridge 传递语义:"通常 at-least-once,极少 best-effort 可能跳过"——生产系统不能假设"每分钟必跑",要补偿机制

🛠 回到 japanese-climb

对应代码:src/jclimb/core_scheduler.py + src/jclimb/mastery_review_params.py/models.py/store.py/evidence.py/profile.py

当前实现:FastAPI 进程内的 APScheduler 之类,单进程跑,多实例时调度去重复杂。

搬 AWS 完整链路:

  1. 用户注册时 → 后端调 EventBridge Scheduler CreateSchedule API:
    Name: reminder-{userId}
    ScheduleExpression: "cron(0 6 * * ? *)"
    ScheduleExpressionTimezone: "Asia/Tokyo"
    Target: arn:aws:lambda:...:build-reminder
            
  2. 用户改时区 → UpdateSchedule 改 timezone
  3. 用户注销 → DeleteSchedule
  4. Lambda 触发时读 DynamoDB mastery_review_state,拼提醒,推 SNS

关键:百万用户每人独立 schedule,AWS 替你管定时精度+重试,你的代码只关心"6 点要提醒什么"。比 APScheduler 多用户场景稳得多。

📌 闪卡

EventBridge Scheduler vs 传统 EB Rule 的本质区别?
Scheduler 是独立服务,原生时区支持、支持百万级动态 schedule、支持一次性触发。Rule 是 bus 上的事件路由(多对多匹配),上限 ~300/region,无时区。新项目用 Scheduler。
EventBridge Pipes 适合什么场景?
把 "source → filter → transform → target" 做成声明式,省去为简单转发场景写 Lambda 当胶水。常见:
· SQS → 过滤 priority=high → Step Functions
· DynamoDB Streams → 过滤特定表 → EventBridge Bus
· Kinesis → 转换格式 → Firehose
怎么写事件模式"detail.userId 等于 abc"?
{"detail": {"userId": ["abc"]}}——数组里是 OR(多值匹配);支持 prefix/suffix/numeric/anything-but/exists 等匹配器。
EventBridge 跨账户传事件怎么做?
在源账户配 cross-account resource policy,目标账户的 custom bus 接收(default bus 不行)。常见模式:组织有"中央安全账户"接所有子账户的 CloudTrail 事件。

🔁 变体题

变体 1:SQS 消息进队列后,要过滤掉 priority="low" 的,剩下传给 Step Functions 启动工作流。最直接实现?

✅ BPipes 就是为这场景设计的——source=SQS, filter="priority": [{"anything-but":"low"}], target=Step Functions。零代码、零 Lambda、零运维。C 错在:EB Rule 监听的是 EB Bus 上的事件,不能直接以 SQS 为 source(要么 Pipes,要么 SQS event source mapping 给 Lambda)。

变体 2:你设 EventBridge Schedule 每分钟跑一次 Lambda。监控发现一周内有 3 次"该跑没跑"。最可能解释?

✅ B:AWS 文档明说:事件传递通常 at-least-once 但极少情况下可能 best-effort 跳过。生产系统不能假设"每分钟必跑一次"——要补偿机制(比如下次跑时检查"上次有没有漏数据")。这是 DEA 喜欢考的 nuance,区分"懂表象 vs 懂分布式系统"。