3.异步、同步生产消费、批量处理

同步

生产

 /**
     * 同步-生产消息
     * @param msg
     * @throws PulsarClientException
     */
    @GetMapping("/model/sendMsgBySync")
    public MessageId sendMsgBySync(String msg) throws PulsarClientException {
        PulsarClient pulsarFactory = pulsarConf.pulsarFactory();

        Producer<byte[]> producer = pulsarFactory.newProducer()
                .topic("my-topic")
                .create();
        // 然后你就可以发送消息到指定的broker 和topic上:
        return producer.send(msg.getBytes());
    }

消费

/**
     * 手动执行同步获取消息
     * @throws PulsarClientException
     */
    @GetMapping("/model/comsumerBySync")
    public void comsumerByArtificialBySync() throws PulsarClientException {
        PulsarClient pulsarFactory = pulsarConf.pulsarFactory();
        Consumer<byte[]> consumer = pulsarFactory.newConsumer()
                .topic("my-topic")
                .subscriptionName("my-subscription")
                .subscribe();
        Message<byte[]> receive = consumer.receive();
        System.out.println(new String(receive.getData()));
        consumer.acknowledge(receive);//确认消息被消费
        consumer.close();
    }

异步

生产

/**
     * 异步-生产消息
     * @param msg
     * @throws PulsarClientException
     */
    @GetMapping("/model/sendMsgAsync")
    public void sendMsgAsync(String msg) throws PulsarClientException {
        PulsarClient pulsarFactory = pulsarConf.pulsarFactory();

        Producer<byte[]> producer = pulsarFactory.newProducer()
                .topic("my-topic")
                .create();
        // 然后你就可以发送消息到指定的broker 和topic上:
        producer.sendAsync(msg.getBytes()).thenAccept(msgId -> {
            System.out.println("Message with ID " + msgId + " successfully sent");
        });
    }

消费

/**
     * 手动执行异步获取消息
     * @throws PulsarClientException
     */
    @GetMapping("/model/comsumerByASync")
    public void comsumerByArtificialByASync() throws PulsarClientException {
        PulsarClient pulsarFactory = pulsarConf.pulsarFactory();
        Consumer<byte[]> consumer = pulsarFactory.newConsumer()
                .topic("my-topic")
                .subscriptionName("my-subscription")
                .subscribe();
        CompletableFuture<Message<byte[]>> asyncMessage = consumer.receiveAsync();
        asyncMessage.thenAccept(message -> {
            System.out.println(new String(message.getData()));
            try {
                consumer.acknowledge(message.getMessageId());
                consumer.close();
            } catch (PulsarClientException e) {
                e.printStackTrace();
            }
        });
    }

批量处理

生产

Pulsar生产者默认用的是"消息块"来实现批量发送,但没有想到应用场景,先挂个链接,有个印象,以后遇到了再看

消费

/**
     * 批量消费消息
     * 累计消息数量|累计消息大小|指定时间拉取一次满足其一即执行
     * @throws PulsarClientException
     */
    @GetMapping("/model/comsumerByBatch")
    public void comsumerByBatch() throws PulsarClientException {
        PulsarClient pulsarFactory = pulsarConf.pulsarFactory();
        Consumer<byte[]> consumer = pulsarFactory.newConsumer()
                .topic("my-topic")
                .subscriptionName("my-subscription")
                .batchReceivePolicy(BatchReceivePolicy.builder()
                        .maxNumMessages(5) //累计消息数量,默认-1,不限制
                        .maxNumBytes(1024 * 1024)//累计消息大小,默认 10 * 1024 * 1024
                        .timeout(200, TimeUnit.MILLISECONDS)//指定时间拉取一次,默认 100
                        .build())
                .subscribe();
        Messages<byte[]> messages = consumer.batchReceive();
//        consumer.batchReceiveAsync();//异步同理
        System.out.println("本次接收"+messages.size()+"条");
        for (Message<byte[]> message : messages) {
            System.out.println(new String(message.getData()));
        }
        consumer.acknowledge(messages);//确认消息被消费
        consumer.close();
    }

取消消费

假设,消费者调用acknowledge消费消息后程序报错,数据回滚,但Pulsar不知道回滚了,导致数据无法再次消费,所以需要回滚消费标识

/**
     * 取消消费
     * @throws PulsarClientException
     */
    @GetMapping("negativeAcknowledgement")
    public void negativeAcknowledgement() throws PulsarClientException {
        PulsarClient pulsarFactory = pulsarConf.pulsarFactory();
        Consumer<byte[]> consumer = pulsarFactory.newConsumer()
                .topic("my-topic")
                .subscriptionName("my-subscription")
                .subscribe();
        Message<byte[]> receive = consumer.receive();
        MessageId messageId = receive.getMessageId();
        try {
            System.out.println(new String(receive.getData()));
            consumer.acknowledge(receive);//确认消息被消费
        } catch (PulsarClientException e) {
            consumer.negativeAcknowledge(messageId);//消息取消消费,会被重新消费
            e.printStackTrace();
        }
        consumer.close();
    }

代码下载

代码见此messageModel包下

posted @ 2021-09-20 17:12  RollBack2010  阅读(735)  评论(0编辑  收藏  举报