Spring Boot项目集成Pulsar

在分布式系统和实时数据处理不断发展的背景下,高效、可扩展和可靠的消息中间件的需求变得日益重要。Apache Pulsar作为一个强大的解决方案应运而生,提供了许多针对现代数据密集型应用的功能。在本文中,我们将探索Pulsar的关键特性、使用场景和优势。

Apache Pulsar是什么?

Apache Pulsar是一个分布式消息和事件流平台,旨在解决实时处理海量数据的挑战。由Yahoo开发,并随后作为Apache软件基金会的一部分开源,Pulsar拥有独特的架构,将消息存储和消息处理分开,实现了出色的可扩展性和可靠性。

Apache Pulsar的关键特性:

  1. 多租户性能: Pulsar支持多租户性能,允许组织在保持不同租户之间隔离的同时共享集群。这一功能对于云环境和拥有多样化数据处理需求的大型企业至关重要。

  2. 水平扩展性: Pulsar的架构天然具有可扩展性,支持无缝扩展集群以满足不断增长的工作负载。它采用分布式架构,可以动态添加或删除代理节点,而不会影响系统的可用性。

  3. 地理复制: Pulsar支持地理复制,实现数据在多个地理区域的冗余。这确保了高可用性和灾难恢复能力,对于需要严格SLA的关键应用至关重要。

  4. 统一的消息和流: 与传统的消息系统不同,Pulsar无缝集成了消息和事件流的能力。它支持传统的发布-订阅消息模式和现代事件流范式,满足各种使用情况。

  5. 持久化消息存储: Pulsar提供由Apache BookKeeper支持的持久化消息存储,确保消息即使在节点故障或系统崩溃时也能安全持久化。

  6. 分层存储: Pulsar提供分层存储,允许组织根据其访问模式和保留策略将消息存储在不同的存储层中。这一功能通过将较旧或不经常访问的数据转移到更便宜的存储解决方案来优化存储成本。

Apache Pulsar的使用场景:

  1. 实时分析: Pulsar非常适用于实时分析应用,其中需要处理来自各种来源的流数据,并在接近实时的时间内进行分析。它使组织能够从流数据流中获取有价值的见解,支持欺诈检测、异常检测和预测性维护等用例。

  2. 微服务通信: Pulsar作为微服务架构的有效通信层,实现了分布式服务之间的无缝交互。它提供了可靠的消息传递和事件驱动通信,支持可伸缩和具有韧性的微服务部署。

  3. 物联网数据接入: 随着物联网设备生成海量数据的增加,Pulsar为物联网应用提供了一个理想的平台,用于实时接收、处理和分析物联网数据流。它可以处理物联网应用的高吞吐量和低延迟要求,帮助组织利用物联网数据进行可行动的见解和决策。

  4. 日志聚合和监控: Pulsar可用于日志聚合和监控,将分布式系统和应用程序的日志集中到一个中央存储库中。它提供了实时日志处理能力,使组织能够实时监控系统健康状况、检测异常并主动解决问题。

Apache Pulsar的优势:

  1. 可扩展性: Pulsar的可扩展架构使其能够轻松处理海量工作负载,使其适用于小规模部署和大规模企业应用。

  2. 可靠性: Pulsar确保可靠的消息传递和容错,这得益于其分布式和韧性的架构。

  3. 灵活性: Pulsar支持广泛的消息模式和使用情况,为各种应用需求提供了灵活性。

  4. 性能: Pulsar提供高吞吐量和低延迟,非常适用于实时数据处理和事件驱动应用。

  5. 社区和生态系统: 作为Apache软件基金会的一部分,Pulsar受益于充满活力的社区和丰富的集成和扩展生态系统。

总而言之,Apache Pulsar作为现代数据密集型应用的强大消息中间件解决方案崛起。凭借其可扩展的架构、可靠的消息传递和灵活的特性,Pulsar使组织能够构建强大的实时数据处理管道,推动创新和价值创造。

1、引用Maven依赖

<dependency>
    <groupId>org.apache.pulsar</groupId>
    <artifactId>pulsar-client</artifactId>
    <version>2.11.0</version>
</dependency>

2、YAML配置

test:
  pulsar:
    url: pulsar://127.0.0.1:6650
    topics:
      test: persistent://public/test/test

3、pulsar配置类

/**
 * @author Lucas
 * date 2024/3/6 10:56
 * description pulsar 配置文件,主要声明了无事务client 和有事务client
 */
@Configuration
@RefreshScope
public class PulsarConfig {

    @Value("${test.pulsar.url}")
    private String serviceUrl;

    @Bean("PulsarClient")
    public PulsarClient getPulsarClient() {
        try {
            PulsarClient client = PulsarClient.builder()
                    .serviceUrl(serviceUrl)
                    .build();
            return client;
        } catch (PulsarClientException e) {
            System.out.println(e);
            throw new RuntimeException("初始化Pulsar Client失败");
        }
    }

    @Bean("PulsarTransactionClient")
    public PulsarClient getPulsarTransactionClient() {
        try {
            PulsarClient client = PulsarClient.builder()
                    .serviceUrl(serviceUrl)
                    .enableTransaction(true)
                    .build();
            return client;
        } catch (PulsarClientException e) {
            System.out.println(e);
            throw new RuntimeException("初始化Pulsar Client失败");
        }
    }
}

4、读取topic配置

/**
 * @author Lucas
 * date 2024/3/6 10:48
 * description pulsar topic配置
 */
@Configuration
@ConfigurationProperties(prefix = "test")
public class SystemConfig {

    @Getter
    private final Pulsar pulsar = new Pulsar();

    public static class Pulsar {
        @Getter
        private final Topics topics = new Topics();
    }
    @Data
    public static class Topics {
        private String test;
    }

}

5、pulsar公用方法

/**
 * @author Lucas
 * date 2024/3/6 10:55
 * description pulsar 公共方法
 */
@Component
public class PulsarCommon {
    @Qualifier("PulsarClient")
    @Resource
    private PulsarClient client;

    @Qualifier("PulsarTransactionClient")
    @Resource
    private PulsarClient transactionClient;

    /**
     * 创建一个生产者
     * @param topic     topic name
     * @param schema    schema方式
     * @param <T>       泛型
     * @return          Producer生产者
     */
    public <T> Producer<T> createProducer(String topic, Schema<T> schema) {

        try {
            return client.newProducer(schema)
                    .topic(topic)
                    .batchingMaxPublishDelay(10, TimeUnit.MILLISECONDS)
                    .sendTimeout(10, TimeUnit.SECONDS)
                    .blockIfQueueFull(true)
                    .create();
        } catch (PulsarClientException e) {
            throw new RuntimeException("初始化Pulsar Producer失败: " + topic, e);
        }
    }

    /**
     * @param topic             topic name
     * @param subscription      sub name
     * @param messageListener   MessageListener的自定义实现类
     * @param schema            schema消费方式
     * @param <T>               泛型
     * @return                  Consumer消费者
     */
    public <T> Consumer<T> createConsumer(String topic, String subscription,
                                          MessageListener<T> messageListener, Schema<T> schema) {
        try {
            return client.newConsumer(schema)
                    .topic(topic)
                    .subscriptionName(subscription)
                    .ackTimeout(10, TimeUnit.SECONDS)
                    .subscriptionType(SubscriptionType.Shared)
                    .messageListener(messageListener)
                    .subscribe();
        } catch (PulsarClientException e) {
            throw new RuntimeException("初始化Pulsar Consumer失败: " + topic, e);
        }
    }

    /**
     *
     * @param topic             topic name
     * @param subscription      sub name
     * @param messageListener   MessageListener的自定义实现类
     * @param schema            schema消费方式
     * @param <T>               泛型
     * @return                  Consumer消费者
     */
    public <T> Consumer<T> createConsumerDelay(String topic, String subscription,
                                               MessageListener<T> messageListener, Schema<T> schema,
                                               Integer ackRedeliveryTime, TimeUnit ackRedeliveryTimeUnit,
                                               Integer negativeAckRedeliveryTime, TimeUnit negativeAckRedeliveryTimeUnit) {
        try {
            return client.newConsumer(schema)
                    .topic(topic)
                    .subscriptionName(subscription)
                    .ackTimeout(ackRedeliveryTime,ackRedeliveryTimeUnit)
                    .negativeAckRedeliveryDelay(negativeAckRedeliveryTime,negativeAckRedeliveryTimeUnit)
                    .subscriptionType(SubscriptionType.Shared)
                    .messageListener(messageListener)
                    .subscribe();
        } catch (PulsarClientException e) {
            throw new RuntimeException("初始化Pulsar Consumer失败: " + topic, e);
        }
    }
}

6、生产者配置

/**
 * @author Lucas
 * date 2024/2/22 18:40
 * description 生产者
 */
@Component
public class PulsarProducerInit {
    @Resource
    private PulsarCommon pulsarCommon;

    @Resource
    private SystemConfig systemConfig;

    @Bean(name = "testProducer")
    public Producer<String> testProducer() {
        return pulsarCommon.createProducer(systemConfig.getPulsar().getTopics().getTest(), AvroSchema.of(String.class)/*StringSchema.utf8()*/);
    }
}

7、消费者配置

/**
 * @author Lucas
 * date 2024/2/22 18:45
 * description 消费者
 */
@Component
public class PulsarConsumerInit {

    @Resource
    private PulsarCommon pulsarCommon;

    @Resource
    private SystemConfig systemConfig;

    @Resource
    private TestListener testListener;

    @Bean(name = "testConsumer")
    public Consumer<String> testConsumer(){
        return pulsarCommon.createConsumerDelay(systemConfig.getPulsar().getTopics().getTest(),
                "test",
                testListener, AvroSchema.of(String.class)/*StringSchema.utf8()*/,10,TimeUnit.SECONDS,20,TimeUnit.SECONDS);
    }
}

8、生产者生产消息

public class test {

    @Resource(name = "testProducer")
    private Producer<String> testProducer;

    /**
     * 发送pulsar消息
     */
    public void test(){
        String id = "CS123456789";
        log.info("测试发送Pulsar异步通知,id:{}", id);
        try {
            testProducer.newMessage().value(id).send();
        } catch (PulsarClientException e) {
            log.error("测试发送Pulsar异步通知,ID:{},请重试:{}",id, e);
        }
    }

    /**
     * 发送pulsar延时消息
     */
    public void testDelay(){
        String id = "CS123456789";
        Date pulsarTime = new Date();
        log.info("测试发送Pulsar异步延迟通知,id:{}", id);
        try {
            long timeMillis = System.currentTimeMillis();
            long time = pulsarTime.getTime();
            testProducer.newMessage().value(id).deliverAfter(time - timeMillis, TimeUnit.MILLISECONDS).send();
        } catch (PulsarClientException e) {
            log.error("测试发送Pulsar异步延迟通知,ID:{},请重试:{}",id, e);
        }
    }
}

9、消费者消费消息

/**
 * @author Lucas
 * date 2024/2/22 18:36
 * description 测试消费者
 */
@Slf4j
@Component
public class TestListener implements MessageListener<String> {

    @Override
    public void received(Consumer<String> consumer, Message<String> msg) {
        log.info("测试,交易订单ID:{}", msg.getValue());
        try {
            testService.orderTodayIncome(msg.getValue())
                    .doOnSuccess(success -> {
                        consumer.acknowledgeAsync(msg);
                    }).doOnError(error -> {
                        log.error("测试,发生错误", error);
                        consumer.negativeAcknowledge(msg);
                    }).subscribe(logs -> {
                        consumer.acknowledgeAsync(msg.getMessageId());
                        log.info("测试,订单号:{}", msg.getValue());
                    });
        } catch (Exception e) {
            log.error("测试,发生错误", e);
            consumer.acknowledgeAsync(msg.getMessageId());
        }
    }
}

  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
pulsar-java-spring-boot-starter是一个用于在Spring Boot应用程序中集成Apache Pulsar消息队列的开源库。Apache Pulsar是一个可扩展的、低延迟的分布式消息传递平台,它具有高吞吐量和高可靠性的特点。 pulsar-java-spring-boot-starter允许开发人员在Spring Boot应用程序中轻松地发送和接收Pulsar消息。它提供了一组容易使用的注解和工具类,简化了与Pulsar集群的交互。 使用pulsar-java-spring-boot-starter,开发人员可以通过添加依赖和配置一些属性来快速集成Pulsar到他们的Spring Boot应用程序中。一旦集成完成,开发人员可以使用注解来定义消息的生产者和消费者。通过生产者注解,开发人员可以将消息发送到Pulsar集群,并指定消息的主题和内容。通过消费者注解,开发人员可以订阅Pulsar主题,并定义接收和处理消息的方法。 除了基本的生产者和消费者功能,pulsar-java-spring-boot-starter还提供了一些其他特性。例如,它支持失败重试机制,当消息发送或接收出现问题时,可以自动重试。它还支持消息过滤器,可以按条件过滤接收的消息。而且,它还提供了一些监控和管理功能,可以方便地监控消息的生产和消费情况。 总之,pulsar-java-spring-boot-starter为Spring Boot开发人员提供了一种方便、快捷地集成Apache Pulsar消息队列的方法。它简化了与Pulsar集群的交互,提供了易于使用的注解和工具类,让开发人员可以更专注于业务逻辑的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值