Dapr pub/sub

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。

🧩 流程说明

  1. Pub/Sub → Dapr Sidecar
    外部消息系统(如 RabbitMQ、Kafka、Redis Streams)把消息推给 Dapr sidecar。
  2. Dapr Sidecar → SDK (gRPC 流)
    Dapr 通过 gRPC 双向流,把消息推送到你的应用。
  3. SDK → goroutine (接收循环)
    SubscribeWithHandler() 内部启动一个 goroutine,循环执行 Receive()
  4. 每条消息再开 goroutine 调用 handler
    当消息到达时,SDK 再为该消息启动一个新的 goroutine 调用你的 handler(如 processCreated)。
  5. handler 执行完成后 ack
    handler 执行完,SDK 通过 respondStatus() 向 Dapr 返回 ack。
  6. Dapr 通知外部系统确认消费
    Dapr 发送 ack 给 Pub/Sub 确认这条消息被成功处理。

🔑 关键特征

阶段 并发模型 是否阻塞
SDK 启动订阅循环 goroutine 常驻 阻塞在 Receive()
handler 执行 每条消息独立 goroutine 不阻塞主循环
ack 流程 异步返回 非阻塞
相关推荐
JustHappy4 小时前
古法编程秘籍(二):什么是代码模块化?别背概念,把房间收拾明白就够了
前端·后端
小江的记录本4 小时前
【JVM虚拟机】堆内存分代模型:年轻代(Eden+Survivor)、老年代、元空间Metaspace(附《思维导图》+《面试高频考点清单》)
java·前端·jvm·后端·python·spring·面试
IT_陈寒8 小时前
Python闭包里藏的这个坑,差点让我加班到凌晨
前端·人工智能·后端
IT_陈寒8 小时前
Java注解空指针?这个坑我踩得莫名其妙
前端·人工智能·后端
土狗TuGou9 小时前
SQL内功笔记 · 第8篇:事务的四大特性与隔离级别
数据库·笔记·后端·sql·mysql·oracle
ZengLiangYi9 小时前
React Query + REST API 最佳实践
javascript·后端·react.js
星浩AI9 小时前
项目实战:合同智能审批 · LangGraph + HITL 人机协同方案 [有源码]
后端·langchain·agent
JavaGuide9 小时前
Codex 接入第三方模型 DeepSeek、GLM、Kimi 教程:CC-Switch 和 Codex++ 两种方案对比
后端·ai编程
ZengLiangYi9 小时前
Fastify 加 Electron:把 Web 服务嵌进桌面应用
前端·javascript·后端
李白你好9 小时前
页面资产梳理 · 技术指纹识别 · Spring 端点探测
java·后端·spring