
lua
graph TD
%% 外部系统
PubSub[(Pub/Sub: RabbitMQ / Kafka / Redis)]
%% Dapr Sidecar
subgraph DAPR["Dapr Sidecar"]
DaprPubSub["Pub/Sub Adapter"]
GRPCStream["gRPC Stream"]
end
%% 应用程序
subgraph APP["Your App Service"]
SDK["Dapr SDK Client"]
GoroutineReceive["Subscribe goroutine (Receive loop)"]
Listener["WorkflowEventListener"]
Handler["processCreated / processStop / ..."]
end
%% Publish 流程
AppPub["PublishEvent() 调用"]
AppPub --> SDK
SDK --> DaprPubSub
DaprPubSub --> PubSub
%% Subscribe 流程
PubSub --> DaprPubSub
DaprPubSub --> GRPCStream
GRPCStream --> GoroutineReceive
GoroutineReceive --> Listener
Listener --> Handler
Handler --> GoroutineReceive
GoroutineReceive --> DaprPubSub
DaprPubSub --> PubSub

js
sequenceDiagram
participant PubSub as 外部 Pub/Sub 系统
participant Dapr as Dapr Sidecar
participant SDK as Dapr Go SDK
participant Goroutine as Subscribe goroutine
participant Handler as 业务 Handler (e.g. processCreated)
Note over PubSub,Handler: 🟢 消息从发布到消费的全过程
PubSub->>Dapr: 推送消息 (topic)
Dapr->>SDK: gRPC 推送事件流
SDK->>Goroutine: 启动 goroutine (for { s.Receive() })
Goroutine->>Handler: 为每条消息再启动新的 handler goroutine
Handler-->>Goroutine: 处理完成 (成功 / 失败)
Goroutine->>SDK: 调用 respondStatus()
SDK->>Dapr: Ack 消息状态
Dapr->>PubSub: 确认消费完成
Note over SDK,Handler: SDK 内部常驻 goroutine 循环 Receive(),<br>每条消息再开新 goroutine 并发执行 handler。
🧩 流程说明
- Pub/Sub → Dapr Sidecar
外部消息系统(如 RabbitMQ、Kafka、Redis Streams)把消息推给 Dapr sidecar。 - Dapr Sidecar → SDK (gRPC 流)
Dapr 通过 gRPC 双向流,把消息推送到你的应用。 - SDK → goroutine (接收循环)
SubscribeWithHandler()内部启动一个 goroutine,循环执行Receive()。 - 每条消息再开 goroutine 调用 handler
当消息到达时,SDK 再为该消息启动一个新的 goroutine 调用你的 handler(如processCreated)。 - handler 执行完成后 ack
handler 执行完,SDK 通过respondStatus()向 Dapr 返回 ack。 - Dapr 通知外部系统确认消费
Dapr 发送 ack 给 Pub/Sub 确认这条消息被成功处理。
🔑 关键特征
| 阶段 | 并发模型 | 是否阻塞 |
|---|---|---|
| SDK 启动订阅循环 | goroutine 常驻 | 阻塞在 Receive() |
| handler 执行 | 每条消息独立 goroutine | 不阻塞主循环 |
| ack 流程 | 异步返回 | 非阻塞 |