ABP vNext + Debezium CDC:从事务库到事件流的最小侵入落地 🧩
📚 目录
- ABP vNext + Debezium CDC:从事务库到事件流的最小侵入落地 🧩
-
- TL;DR 🧠
- 1) 为什么选 CDC(而非直接写事件) ❓
- 2) 目标架构与数据流(总览图) 🗺️
- 3) 最小侵入准备(PostgreSQL) 🛠️
- 4) Compose 一键起(PostgreSQL + Redpanda + Kafka Connect + Console) ⚙️
- 5) 初始化表与样例数据 🧪
- 6) 注册 Source Connector(白名单 + 脱敏 + 解包 + 路由 + 信号 + 心跳) 📡
- 7) 增量快照 🔁
- 8) ABP CDC-Consumer 模块 🧑💻
- 9) Schema 演进策略 🔄
- 10) 安全过滤与合规 🔐
- 11) 可观测性(JMX/Prometheus)与 SLO 📊
- 12) 失败与回放 ♻️
- 13) 压测与验收 ✅
- 14) 与 Outbox 的取舍(对照) ⚖️
- 15) Debezium Server(替代 Kafka Connect,二选一) 🪶
TL;DR 🧠
- 零侵入业务代码:仅开启数据库逻辑复制(Postgres
wal_level=logical等),Debezium 从变更日志捕获行级变更,天然与事务原子 - 至少一次语义:消费者需幂等(Inbox + Upsert),并采用手动提交 offset——业务成功后再提交
- 安全最小化:PG15 publication 行/列过滤从源头裁剪;连接器端再配 表/列白名单 + SMT 脱敏 🔒
- 演进友好:通过信号表触发增量快照补历史;使用 ExtractNewRecordState 扁平化事件,并用新版
delete.tombstone.handling.mode处理删除 - 观测:Connect/Debezium 暴露 JMX 指标;可加 heartbeat 主题检测延迟,Prometheus 转发可选 📈
1) 为什么选 CDC(而非直接写事件) ❓
- 最小侵入:不改老系统/第三方库代码即可获得行级变更流
- 补历史不中断:首次 initial snapshot + 运行期 incremental snapshot(信号触发)
- 边界:交付语义为至少一次;大事务可能造成捕获延迟,需监控与调优 ⚠️
2) 目标架构与数据流(总览图) 🗺️
要点:
- 每张表通常对应一个主题;可使用
RegexRouter统一命名前缀 - 心跳主题被消费者侧订阅/观测,用于活性与端到端延迟检测
3) 最小侵入准备(PostgreSQL) 🛠️
3.1 数据库参数(postgresql.conf)
wal_level=logicalmax_wal_senders>=4、max_replication_slots>=4(按规模调)- 复制用户:仅授予必要库/表与复制权限(避免 superuser)🔒
3.2 PG15 publication 行/列过滤(强烈推荐)
-- 仅发布 orders 的部分列,并按租户过滤
CREATE PUBLICATION cdc_pub FOR TABLE
public.orders (id, tenant_id, email, amount) WHERE (tenant_id IN ('A','B')),
public.order_items;
要点与限制:
- 语法使用
WHERE (...)括号 - 行过滤在服务器端生效(降低出库与网络开销)
- 过滤表达式需可稳定评估(避免不确定函数)
- UPDATE/DELETE 所需的标识列需在发布列中(通常主键即可)
3.3 信号表(无默认表名 → 自建并配置) 🔔
Debezium 没有默认信号表名;本文示例使用
public.debezium_signals。你可以自定义,但必须在连接器里用signal.data.collection写完整限定名,且把信号表加入 publication(特别是在publication.autocreate.mode=filtered/disabled时)。
CREATE TABLE IF NOT EXISTS public.debezium_signals(
id varchar(64) primary key,
type varchar(32) not null,
data varchar(2048)
);
ALTER PUBLICATION cdc_pub ADD TABLE public.debezium_signals;
4) Compose 一键起(PostgreSQL + Redpanda + Kafka Connect + Console) ⚙️
⚠️ Redpanda
--mode dev-container/--overprovisioned仅用于本地开发/CI;生产请按官方指南规划 CPU/内存/磁盘与副本
docker-compose.yml
version: "3.8"
services:
postgres:
image: debezium/postgres:16
environment:
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=inventory
ports: ["5432:5432"]
redpanda:
image: redpandadata/redpanda:latest
command: >
redpanda start --mode dev-container --smp 1 --memory 1G
--overprovisioned --check=false --node-id 0
ports: ["9092:9092","8081:8081"] # 8081: Schema Registry(若启用 Avro/Protobuf)
connect:
image: debezium/connect:2.6
environment:
- BOOTSTRAP_SERVERS=redpanda:9092
- GROUP_ID=1
- CONFIG_STORAGE_TOPIC=_connect_configs
- OFFSET_STORAGE_TOPIC=_connect_offsets
- STATUS_STORAGE_TOPIC=_connect_status
# JSON(schemaless)方案 ↓
- KEY_CONVERTER=org.apache.kafka.connect.json.JsonConverter
- VALUE_CONVERTER=org.apache.kafka.connect.json.JsonConverter
- KEY_CONVERTER_SCHEMAS_ENABLE=false
- VALUE_CONVERTER_SCHEMAS_ENABLE=false
# 若选 Avro,请改为(并启用 Schema Registry 8081):
# - KEY_CONVERTER=io.confluent.connect.avro.AvroConverter
# - VALUE_CONVERTER=io.confluent.connect.avro.AvroConverter
# - KEY_CONVERTER_SCHEMAS_ENABLE=true
# - VALUE_CONVERTER_SCHEMAS_ENABLE=true
# - KEY_CONVERTER_SCHEMA_REGISTRY_URL=http://redpanda:8081
# - VALUE_CONVERTER_SCHEMA_REGISTRY_URL=http://redpanda:8081
- JMX_PORT=9010
ports: ["8083:8083","9010:9010"]
depends_on: [redpanda]
console:
image: redpandadata/console:latest
volumes:
- ./console.yaml:/etc/console
326



被折叠的 条评论
为什么被折叠?



