Rocket MQ「5」简单消息

前言

    简单消息是Rocket MQ最基本的消息类型,特点就是… …没有特点。正因如此也就没有什么好讲述的内容,故该博文的讲述重点其实在于【发送方式】。

【注】本博文代码基于底层API实现以便于更好的展示流程,关于Spring Boot整合Rocket MQ请点击下方博文。

【附】博文:《Spring Boot(4):整合Rocket MQ》

一 发送方式

    Rocket MQ共有三种发送方式:

  • 同步发送
  • 异步发送
  • 单向发送

    发送方式与消息类型没有直接关联。也就是说对于任何消息类型都会有三种发送方式,以后续会讲述的有序消息为例,分为:有序同步消息/有序异步消息/有序单向消息。开发者需要根据需求及应用场景选择的消息类型及发送方式。

    /**
     * 主方法
     *
     * @param args 数组
     */
    public static void main(String[] args) {
        try {
            // 同步发送消息。
            syncSendMessage();
            // 异步发送消息。
            asyncSendMessage();
            // 单向发送消息。
            oneWaySendMessage();
        } catch (MQClientException | InterruptedException | RemotingException |
                MQBrokerException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

二 同步发送(可靠)

    同步消息具备回应机制【ACK】以确保消息被正确的从生产者发送至经纪人服务器。其最大的特点是会与线程中的其它任务同步执行。

    /**
     * 同步发送消息
     *
     * @throws MQClientException            MQ客户端异常
     * @throws RemotingException            远程异常
     * @throws InterruptedException         终端异常
     * @throws MQBrokerException            经纪人服务器异常
     * @throws UnsupportedEncodingException 不支持编码异常
     */
    public static void syncSendMessage() throws MQClientException, RemotingException,
            InterruptedException, MQBrokerException, UnsupportedEncodingException {
        // 实例化生产者/设置命名服务器地址/开启生产者。
        DefaultMQProducer producer = new DefaultMQProducer("simple_producer");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();
        // 同步发送消息并接收回应。
        byte[] body = "这是一条简单同步消息。".getBytes(RemotingHelper.DEFAULT_CHARSET);
        Message message = new Message("simple", "sync", body);
        System.out.println("开始发送简单同步消息......");
        SendResult sendResult = producer.send(message);
        System.out.println("简单同步消息发送结果:" + sendResult.getSendStatus());
        System.out.println();
        // 关闭生产者。
        producer.shutdown();
    }

三 异步发送(可靠)

    异步发送同样具备回应机制,但与同步发送的不同在于其会与线程中的其它任务异步执行。也就是说其会开启一个新的专属线程用于发送并接收回应,如果业务场景要求较高的实时性,可以采用该种发送方式。

    /**
     * 发送异步消息
     *
     * @throws MQClientException            MQ客户端异常
     * @throws RemotingException            远程异常
     * @throws InterruptedException         终端异常
     * @throws UnsupportedEncodingException 不支持编码异常
     */
    public static void asyncSendMessage() throws MQClientException, RemotingException,
            InterruptedException, UnsupportedEncodingException {
        // 实例化生产者/设置命名服务器地址/开启生产者。
        DefaultMQProducer producer = new DefaultMQProducer("simple_producer");
        producer.setNamesrvAddr("127.0.0.1:9876");
        // 设置发送失败的重试次数,0表示不重试。
        producer.setRetryTimesWhenSendAsyncFailed(5);
        producer.start();
        // 实例化计数器,用于防止异步线程在发送消息的过程中主线程关闭生产者。
        CountDownLatch countDownLatch = new CountDownLatch(1);
        // 异步发送消息并执行成功/失败逻辑。
        byte[] body = "这是一条简单异步消息。".getBytes(RemotingHelper.DEFAULT_CHARSET);
        Message message = new Message("simple", "async", body);
        System.out.println("开始发送简单异步消息......");
        producer.send(message, new SendCallback() {

            /**
             * 执行成功
             * @param sendResult 发送结果
             */
            @Override
            public void onSuccess(SendResult sendResult) {
                System.out.println("简单异步消息发送结果:" + sendResult.getSendStatus());
                System.out.println();
                countDownLatch.countDown();
            }

            /**
             * 执行异常
             * @param throwable 异常
             */
            @Override
            public void onException(Throwable throwable) {
                System.out.println("简单异步消息发送异常。");
                throwable.printStackTrace();
                System.out.println();
                countDownLatch.countDown();
            }

        });
        countDownLatch.await();
        // 关闭生产者。
        producer.shutdown();
    }

四 单向消息(不可靠)

    单向消息不具备回应机制,也就是说其是不可靠的,对于不在意执行结果的任务可以采用该种发送方式。其与异步发送相同,与线程中的其它任务是异步执行的。

    /**
     * 单向发送消息
     *
     * @throws MQClientException            MQ客户端异常
     * @throws RemotingException            远程异常
     * @throws InterruptedException         终端异常
     * @throws UnsupportedEncodingException 不支持编码异常
     */
    public static void oneWaySendMessage() throws MQClientException, RemotingException,
            InterruptedException, UnsupportedEncodingException {
        // 实例化生产者/设置命名服务器地址/开启生产者。
        DefaultMQProducer producer = new DefaultMQProducer("simple_producer");
        producer.setNamesrvAddr("127.0.0.1:9876");
        producer.start();
        // 单向发送消息。
        byte[] body = "这是一条简单单向消息。".getBytes(RemotingHelper.DEFAULT_CHARSET);
        Message message = new Message("simple", "one_way", body);
        System.out.println("开始发送简单单向消息......");
        producer.sendOneway(message);
        System.out.println("别看了,简单单向消息没回应。");
        System.out.println();
        // 等待线程5秒钟,确保单向消息发送完全。
        Thread.sleep(5000);
        // 关闭生产者。
        producer.shutdown();
    }

消费

package simple;

import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;

import java.util.List;

/**
 * @Author: 说淑人
 * @Date: 2021/6/24 下午8:42
 * @Description: 简单消费者
 */
public class SimpleConsumer {

    /**
     * 主方法
     *
     * @param args 数组
     */
    public static void main(String[] args) {
        try {
            // 消费消息。
            consumeMessage();
        } catch (MQClientException e) {
            e.printStackTrace();
        }
    }

    /**
     * 消费消息
     *
     * @throws MQClientException MQ客户端异常
     */
    public static void consumeMessage() throws MQClientException {
        // 实例化消费者(推模式)并设置命名服务器地址。
        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("simple_consumer");
        consumer.setNamesrvAddr("127.0.0.1:9876");
        // 订阅主题,并设置接收一切标签。
        consumer.subscribe("simple", "*");
        // 向经纪人服务器注册并行消息监听器。
        consumer.registerMessageListener(new MessageListenerConcurrently() {

            /**
             * 消费消息
             * @param messageExts 消息列表
             * @param consumeConcurrentlyContext 空间
             * @return 消费并行状态
             */
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(
                    List<MessageExt> messageExts, 
                    ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                // 输出消息。
                for (MessageExt messageExt : messageExts) {
                    System.out.println("主题:" + messageExt.getTopic());
                    System.out.println("标签:" + messageExt.getTags());
                    System.out.println("消息ID:" + messageExt.getMsgId());
                    String message = new String(messageExt.getBody());
                    System.out.println("消息内容:" + message);
                    System.out.println();
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }

        });
        // 开启消费者。
        consumer.start();
    }

}

【上篇】《Rocket MQ【4】下载/安装/启动/关闭(附高版本JDK配置)》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

说淑人

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

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

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

打赏作者

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

抵扣说明:

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

余额充值