RocketMQ(六):跟着官网学习敲代码(备份)

 1 概述

        RocketMQ(一):领域模型(主题、队列、消息)

        RocketMQ(二):领域模型(生产者、消费者)

        RocketMQ(三):消息类型(普通、定时、顺序和事务消息)

        RocketMQ(四):功能特性

        RocketMQ(五):功能特性——消费管理

        上面5篇内容根据Apache RocketMQ官网,学习了理论方面的知识,内容中穿插的代码也仅仅配合基础知识。从本篇开始,真正通过代码实现上面的功能。

2 准备工作

        1、部署RocketMQ,建议在Linux环境部署使用。

        2、版本:jdk-8u401-linux-x64 、rocketmq-all-5.1.3-bin-release、RocketMQ Dashboard。

        3、如何部署请自行百度或参考官网,目前学习阶段部署单机版即可。

3 创建生产者公共方法

        准备工作,需要提前在RocketMQ Dashboard 新建一个主题即可。

package com.jay.demo01;

import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.apis.ClientConfiguration;
import org.apache.rocketmq.client.apis.ClientException;
import org.apache.rocketmq.client.apis.ClientServiceProvider;
import org.apache.rocketmq.client.apis.producer.Producer;
import org.apache.rocketmq.client.apis.producer.ProducerBuilder;
import org.apache.rocketmq.client.apis.producer.TransactionChecker;

import java.time.Duration;

@Slf4j
public class ProducerSingleton {
    private static Producer PRODUCER;
    private static Producer TRANSACTIONAL_PRODUCER;

    private static final String ENDPOINT = "xxx.xxx.xxx.xxx:8081";

    public ProducerSingleton() {
    }
    private static Producer buildProducer(TransactionChecker checker,String ... topic) throws ClientException {
        ClientServiceProvider provider = ClientServiceProvider.loadService();
        ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder().setEndpoints(ENDPOINT)
                .setRequestTimeout(Duration.ofSeconds(10)).build();
        ProducerBuilder producerBuilder = provider.newProducerBuilder()
                .setTopics(topic)
                .setMaxAttempts(3)
                .setClientConfiguration(clientConfiguration);
        if(checker != null){
            producerBuilder.setTransactionChecker(checker);
        }
        Producer producer = producerBuilder.build();
        log.info("producer 创建成功[{}]",producer.getClass());
        return producerBuilder.build();

    }

    public static Producer getInstance(String ... topic) throws ClientException {
        if(null == PRODUCER){
            synchronized (ProducerSingleton.class){
                if(null == PRODUCER){
                    PRODUCER = buildProducer(null,topic);
                }
            }
        }
        return PRODUCER;
    }

    public static Producer getTransactionalProducer(TransactionChecker checker,String ... topic) throws ClientException {
        if(null == TRANSACTIONAL_PRODUCER){
            synchronized (ProducerSingleton.class){
                if(null == TRANSACTIONAL_PRODUCER){
                    TRANSACTIONAL_PRODUCER = buildProducer(checker,topic);
                }
            }
        }
        return TRANSACTIONAL_PRODUCER;
    }

    public static void main(String[] args) throws ClientException {
        Producer producer = ProducerSingleton.getInstance("topic001");
    }
}

运行结果

    

4 使用PushConsumer和SimpleConsumer消费消息

        准备工作:创建主题、消费者组、标签

package com.jay.demo01;

import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.apis.ClientConfiguration;
import org.apache.rocketmq.client.apis.ClientException;
import org.apache.rocketmq.client.apis.ClientServiceProvider;
import org.apache.rocketmq.client.apis.consumer.*;
import org.apache.rocketmq.client.apis.message.MessageId;
import org.apache.rocketmq.client.apis.message.MessageView;

import java.io.IOException;
import java.time.Duration;
import java.util.Collections;
import java.util.List;

@Slf4j
public class PushConsumerAndSimpleConsumerTest {
    //接入点
    private static final String ENDPOINT = "XXX.XXX.XXX.XXX:8081";
    //消费者组名
    private static final String GROUPNAME = "groupName01";
    //Tag标签
    private static final String TAG = "TAG01";
    //主题
    private static final String TOPIC = "topic001";
    public static void main(String[] args) throws ClientException, IOException, InterruptedException {
        final ClientServiceProvider provider = ClientServiceProvider.loadService();
        //测试PushConsumer
        //testPushConsumer(provider);
        //测试SimpleConsumer
       testSimpleConsumer(provider);
    }

    public static void testPushConsumer(ClientServiceProvider provider)throws InterruptedException, IOException, ClientException{
        //定义ClientConfiguration,设置接入点
        ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder()
                .setEndpoints(ENDPOINT)
                .build();
        //定义过滤表达式
        FilterExpression filterExpression = new FilterExpression(TAG, FilterExpressionType.TAG);
        //定义PushConsumer
        log.info("pushConsumer 开始接收信息");
        PushConsumer pushConsumer = provider.newPushConsumerBuilder()
                //设置配置信息
                .setClientConfiguration(clientConfiguration)
                //设置消费者组
                .setConsumerGroup(GROUPNAME)
                //设置主题表达式
                .setSubscriptionExpressions(Collections.singletonMap(TOPIC,filterExpression))
                //设置消息监听器
                .setMessageListener(messageView -> {
                    log.info("PushConsumer message = {}", messageView);
                    return ConsumeResult.SUCCESS;
                })
                .build();
        Thread.sleep(Long.MAX_VALUE);
        pushConsumer.close();
    }

    public static void testSimpleConsumer(ClientServiceProvider provider) throws ClientException {
        //1 客户端配置接入点
        ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder()
                .setEndpoints(ENDPOINT)
                .build();
        // 2 配置 Tag标签过滤表达式
        FilterExpression filterExpression = new FilterExpression(TAG, FilterExpressionType.TAG);
        //3 设置请求时间
        Duration duration = Duration.ofSeconds(30);
        //4 创建SimpleConsumer

        SimpleConsumer simpleConsumer = provider.newSimpleConsumerBuilder()
                .setClientConfiguration(clientConfiguration)
                //配置消费者组
                .setConsumerGroup(GROUPNAME)
                //配置等待时间
                .setAwaitDuration(duration)
                //为消费者设置订阅属性,包括主题和标签
                .setSubscriptionExpressions(Collections.singletonMap(TOPIC, filterExpression))
                .build();
        //5 设置最多消息数量
        int maxMessageNum = 16;
        // 6 设置不可见时间
        Duration invisibleDuration   = Duration.ofSeconds(15);
        //7 接收信息
        do{
            log.info("simpleConsumer 开始接收信息");
            final List<MessageView> messageViewList = simpleConsumer.receive(maxMessageNum,invisibleDuration);
            log.info("simpleConsumer 接收{} 消息",messageViewList.size());
            for(MessageView messageView : messageViewList){
                final MessageId messageId = messageView.getMessageId();
                try {
                    simpleConsumer.ack(messageView);
                    log.info("消息被成功消费,messageId = {}",messageId);
                }catch (Throwable t){
                    log.error("消息消费失败,messageId = {}",messageId,t);
                }

            }
        }while (true);


    }
}

  testSimpleConsumer()运行结果:

  testPushConsumer()运行结果

5 发送/接收普通消息

5.1 生产者发送普通同步消息

package com.jay.demo01;

import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.apis.ClientException;
import org.apache.rocketmq.client.apis.ClientServiceProvider;
import org.apache.rocketmq.client.apis.message.Message;
import org.apache.rocketmq.client.apis.producer.Producer;
import org.apache.rocketmq.client.apis.producer.SendReceipt;
import org.checkerframework.checker.units.qual.C;

import java.nio.charset.StandardCharsets;

@Slf4j
public class MessageTest {
    //接入点
    private static final String ENDPOINT = "xxx.xxx.xxx.xxx:8081";
    //消费者组名
    private static final String GROUPNAME = "groupName01";
    //Tag标签
    private static final String TAG = "TAG01";
    //主题
    private static final String TOPIC = "topic001";
    public static void main(String[] args) throws ClientException {
        final ClientServiceProvider provider = ClientServiceProvider.loadService();
        normalMessageTest(provider);
    }

    public static void normalMessageTest(ClientServiceProvider provider) throws ClientException {
        final Producer producer = ProducerSingleton.getInstance(TOPIC);
        byte[] messageBody = "This is a normal message for Apache RocketMQ".getBytes(StandardCharsets.UTF_8);
        Message message = provider.newMessageBuilder()
                //设置主题
                .setTopic(TOPIC)
                //设置标签
                .setTag(TAG)
                //设置唯一索引键
                .setKeys("001")
                //设置消息体
                .setBody(messageBody)
                .build();
        try {
            final SendReceipt sendReceipt = producer.send(message);
            log.info("发送消息成功, messageId={}", sendReceipt.getMessageId());
        }catch (Throwable t){
            log.error("发送消息失败", t);
        }


    }

}

  运行结果

使用PushConsumer消费普通消息,运行结果

使用SimpleConsumer消费消息,运行结果

  

5.2 生产者发送普通异步消息

public static void normalMessageAsyncTest(ClientServiceProvider provider) throws ClientException {
        final Producer producer = ProducerSingleton.getInstance(TOPIC);
        for (int i = 0; i < 20; i++) {
            byte[] messageBody = "This is a normal message for Apache RocketMQ".getBytes(StandardCharsets.UTF_8);
            Message message = provider.newMessageBuilder()
                    //设置主题
                    .setTopic(TOPIC)
                    //设置标签
                    .setTag(TAG)
                    //设置唯一索引键
                    .setKeys("001")
                    //设置消息体
                    .setBody(messageBody)
                    .build();
            CompletableFuture<SendReceipt> future = producer.sendAsync(message);
            ExecutorService threadPool = Executors.newFixedThreadPool(5);
            future.whenCompleteAsync((sendReceipt,throwable) ->{
                if(null != throwable){
                    log.info("消息发送失败");
                }
                log.info("消息发送成功,messageId = {}", sendReceipt.getMessageId());
            },threadPool);
        }



    }

生产者发送异步消息运行结果

消费者消费消息运行结果

  • 19
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

geminigoth

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值