告别繁琐集成!这个 Spring Boot Pulsar Starter 让消息队列开发效率翻倍

7 阅读5分钟

前言

Apache Pulsar 作为新一代云原生消息队列,凭借其多租户、持久化、高可用等特性,正在被越来越多的企业采用。然而,原生的 Pulsar Java 客户端集成到 Spring Boot 项目时,往往需要大量样板代码——连接管理、序列化、重试逻辑、健康检查……每个团队都在重复"造轮子"。

今天给大家介绍一个开源项目:seven-spring-mq-pulsar-starter,它的目标只有一个:让 Spring Boot 接入 Pulsar,像用 Spring Data 一样简单

GitHub:github.com/qwzhang01/s… Maven:io.github.qwzhang01:seven-spring-mq-pulsar-starter


一、为什么需要这个 Starter?

先来看看直接使用 Pulsar 原生客户端的痛点:

场景原生 Pulsar 客户端本 Starter
初始化连接手动 new PulsarClient,管理生命周期自动装配,零代码
消费者注册手动创建 Consumer,写轮询循环@PulsarListener 一个注解搞定
多租户切换每个消费者手动提取 metadata、切换上下文拦截器自动传播
消息路由在业务代码里写 if/switch 判断消息类型msgRoute 声明式路由
失败重试自己实现退避算法配置即用,支持指数退避
死信队列手动实现 DLQ topic 和转发逻辑自动处理,可自定义 Handler

二、核心功能一览

🚀 一键启用

只需在启动类加一个注解:

@SpringBootApplication
@EnablePulsar
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

然后在 application.yml 里配置连接地址:

spring:
  pulsar:
    enabled: true
    service-url: pulsar://localhost:6650
    admin-url: http://localhost:8080

完成。开始写业务代码。


📨 消息发送:同步、异步、延迟,随你选

@Service
public class OrderService {
    @Autowired
    private PulsarMessageSender messageSender;

    // 同步发送
    public void sendOrder(Order order) {
        messageSender.send("order-events", order);
    }

    // 异步发送,不阻塞主线程
    public void sendOrderAsync(Order order) {
        messageSender.sendAsync("order-events", order)
            .thenAccept(id -> log.info("发送成功: {}", id));
    }

    // 延迟消息,30秒后投递
    public void sendDelayed(Order order) {
        messageSender.sendDelayed("order-events", order, 30_000);
    }
}

👂 消息监听:注解声明,极致简洁

@Component
public class OrderEventListener {

    @PulsarListener(topic = "order-events", subscription = "order-processor")
    public void handleOrderEvent(Order order) {
        orderService.process(order);
    }

    // 共享订阅,多实例并行消费
    @PulsarListener(
        topic = "payment-requests",
        subscription = "payment-processor",
        subscriptionType = "Shared"
    )
    public void processPayment(PaymentRequest request) {
        paymentGateway.process(request);
    }
}

🛣️ 亮点功能:消息路由(msgRoute)

这是本 Starter 最有特色的功能之一

在传统做法里,同一个 topic 下有不同业务类型的消息,消费者需要:

  1. 拿到消息
  2. 判断消息类型
  3. 手动 dispatch 到不同处理逻辑

样板代码多,且容易出 Bug。

本 Starter 的方案:发送时在元数据里打标,消费时根据标记自动路由到对应的方法。

发送端

MsgContext.setMsgRoute("order.created");
pulsarTemplate.send("order-events", event);
MsgContext.remove();

消费端:声明式绑定,一个方法只处理一种业务类型

@PulsarListener(topic = "order-events", subscription = "order-processor", msgRoute = "order.created")
public void handleOrderCreated(OrderEvent event) {
    orderService.processNewOrder(event);
}

@PulsarListener(topic = "order-events", subscription = "order-processor", msgRoute = "order.cancelled")
public void handleOrderCancelled(OrderEvent event) {
    orderService.processCancelledOrder(event);
}

也支持一个监听器处理多种路由(multiRoute = true):

@PulsarListener(topic = "business-events", subscription = "multi-route-processor", multiRoute = true)
public void handleMultiRoute(Message<BusinessEvent> message) {
    String msgRoute = message.getProperties().get(MsgMetaKey.MSG_ROUTE.getCode());
    switch (msgRoute) {
        case "user.registration": handleUserRegistration(message.getValue()); break;
        case "order.payment":     handleOrderPayment(message.getValue()); break;
        case "inventory.update":  handleInventoryUpdate(message.getValue()); break;
    }
}

🔐 多租户支持:拦截器自动传播上下文

SaaS 系统的核心挑战之一是多租户隔离。本 Starter 通过 MetaMessageInterceptor 抽象,让租户上下文在消息收发过程中自动流转:

@Component
public class TenantContextInterceptor extends MetaMessageInterceptor {

    @Override
    public void buildSendContext() {
        // 发送时自动注入当前租户 ID 到消息元数据
        MsgContext.setCorpKey(TenantContext.getCurrentTenant());
    }

    @Override
    public boolean buildReceiveContext(String corpKey) {
        // 消费时根据元数据自动切换租户
        return tenantService.switchTenant(corpKey);
    }

    @Override
    public int getOrder() { return 1; }
}

不需要在每个 @PulsarListener 里手动提取和设置租户,彻底消除重复代码。


🔄 重试 + 💀 死信队列:开箱即用

spring:
  pulsar:
    retry:
      enabled: true
      max-retries: 3
      initial-delay: 1s
      multiplier: 2.0      # 指数退避
      max-delay: 30s

    dead-letter:
      enabled: true
      max-retries: 5
      retry:
        smart-strategy-enabled: true
        jitter-enabled: true          # 加随机抖动,避免惊群效应

死信消息还可以自定义处理逻辑,比如落库、告警:

@Component
public class CustomDeadLetterHandler implements DeadLetterQueueHandler {

    @Override
    public void handleDeadLetter(String originalTopic, Message<?> message, Exception exception) {
        // 存入数据库、发送告警通知……
        deadLetterRepository.save(buildRecord(originalTopic, message, exception));
        alertService.notify("消息处理失败:" + originalTopic);
    }
}

🎯 事务消息:@PulsarTransactional 一行搞定

@Service
public class MessageService {

    @PulsarTransactional
    public void sendMessages(String topic, List<String> messages) {
        Transaction transaction = PulsarTransactionUtils.getCurrentTransaction();
        for (String message : messages) {
            pulsarTemplate.send(topic, message, transaction);
        }
        // 正常返回自动提交,异常自动回滚
    }
}

💊 健康检查:与 Spring Actuator 无缝集成

@GetMapping("/health/pulsar")
public ResponseEntity<?> checkPulsarHealth() {
    Map<String, Object> health = pulsarHealthIndicator.health();
    return "UP".equals(health.get("status"))
        ? ResponseEntity.ok(health)
        : ResponseEntity.status(503).body(health);
}

三、快速上手

1. 引入依赖(Maven)

<dependency>
    <groupId>io.github.qwzhang01</groupId>
    <artifactId>seven-spring-mq-pulsar-starter</artifactId>
    <version>${pulsar-spring.version}</version>
</dependency>

2. 环境要求

  • Java 17+
  • Spring Boot 3.0+
  • Apache Pulsar 3.2.4+

3. 最小配置

spring:
  pulsar:
    enabled: true
    service-url: pulsar://localhost:6650
    admin-url: http://localhost:8080

4. 就这些了,开始写你的 @PulsarListener


四、适合哪些场景?

  • 电商系统:订单、支付、库存等多业务类型消息的统一路由处理
  • SaaS 平台:多租户架构下的消息上下文自动隔离传播
  • 微服务通信:各微服务通过 Pulsar 解耦,事件驱动架构
  • 高并发系统:批量异步发送 + Shared 订阅并行消费,提升吞吐

五、总结

seven-spring-mq-pulsar-starter 的核心理念是:把 Pulsar 集成的复杂性封装起来,把业务开发的简单性还给开发者

它不是对 Pulsar 的简单封装,而是在 Spring Boot 生态范式下(注解驱动、配置即用、自动装配)重新思考了 Pulsar 集成的最佳实践,特别是 msgRoute 消息路由和 MetaMessageInterceptor 多租户拦截器这两个特性,在实际业务场景中能显著减少样板代码和降低出错概率。

项目目前在积极维护中,欢迎 Star、提 Issue 或贡献 PR。

项目地址github.com/qwzhang01/s…


如果这个项目对你有帮助,别忘了点个 ⭐ 支持一下!