4.消息发送之同步消息、异步消息、单向消息


highlight: arduino-light

4.1 消息发送基本样例

  • 导入rocketmq-demo
  • 导入MQ客户端依赖

maven <dependency>    <groupId>org.apache.rocketmq</groupId>    <artifactId>rocketmq-client</artifactId>    <version>4.4.0</version> </dependency>

  • 消息发送者步骤分析

md 1.创建消息生产者producer,并指定生产者组名 2.指定Nameserver地址 3.启动producer 4.创建消息对象,指定主题Topic、Tag和消息体 5.发送消息 6.关闭生产者producer

  • 消息消费者步骤分析

md 1.创建消费者Consumer,制定消费者组名 2.指定Nameserver地址 3.订阅主题Topic和Tag 4.设置回调函数,处理消息 5.启动消费者consumer

4.1.1 消息发送

1)同步消息:可靠性

retryTimesWhenSendFailed:同步方式发送消息重试次数,默认为2,总共执行3次。

retryTimesWhenSendAsyncFailed:异步方法发送消息重试次数,默认为2,总共执行3次

发送同步消息如果开启retryAnotherBrokerWhenNotStoreOK会自动重试3次,默认是false,但是可能会造成消息的重复发送

这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知。

java package com.itheima.mq.rocketmq.base.producer; ​ import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.client.producer.SendStatus; import org.apache.rocketmq.common.message.Message; import org.apache.rocketmq.common.message.MessageQueue; ​ import java.util.concurrent.TimeUnit; ​ /** * 发送同步消息 */ public class SyncProducer { ​    public static void main(String[] args) throws Exception {        //1.创建消息生产者producer,并指定生产者组名        DefaultMQProducer producer = new DefaultMQProducer("group1");        //2.指定NameServer地址        producer.setNamesrvAddr("127.0.0.1:9876");        //3.启动producer        producer.start(); ​        for (int i = 0; i < 8; i++) {            //4.创建消息对象,指定主题Topic、Tag和消息体            /**             * 参数一:消息主题Topic             * 参数二:消息Tag             * 参数三:消息内容             */            Message msg = new Message               ("tyrant", "tag", ("Hello World -" + i).getBytes());            //5.发送消息            SendResult result = producer.send(msg);            //发送状态            SendStatus status = result.getSendStatus();            String msgId = result.getMsgId();            MessageQueue messageQueue = result.getMessageQueue();             System.out.println("结果:" + result + "状态:" + status + "messageQueue:" + messageQueue); ​            //线程睡1秒            TimeUnit.SECONDS.sleep(1);       } ​        //6.关闭生产者producer        producer.shutdown();   } }

消息发送结果

md 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A7F7E90000, offsetMsgId=AC125FD700002A9F000000000000FDE9, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=5], queueOffset=2] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=5] ​ 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A7FC760001, offsetMsgId=AC125FD700002A9F000000000000FE95, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=6], queueOffset=4] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=6] ​ 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A800BF0002, offsetMsgId=AC125FD700002A9F000000000000FF41, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=7], queueOffset=1] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=7] ​ 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A805350003, offsetMsgId=AC125FD700002A9F000000000000FFED, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=0], queueOffset=1] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=0] ​ 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A8097B0004, offsetMsgId=AC125FD700002A9F0000000000010099, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=1], queueOffset=1] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=1] ​ 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A80DCD0005, offsetMsgId=AC125FD700002A9F0000000000010145, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=2], queueOffset=3] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=2] ​ 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A812100006, offsetMsgId=AC125FD700002A9F00000000000101F1, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=3], queueOffset=1] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=3] ​ 结果:SendResult [sendStatus=SLAVE_NOT_AVAILABLE, msgId=AC125FD7012014DAD5DC17A816560007, offsetMsgId=AC125FD700002A9F000000000001029D, messageQueue=MessageQueue [topic=tyrant, brokerName=broker-a, queueId=4], queueOffset=1] 状态:SLAVE_NOT_AVAILABLE messageQueue:MessageQueue [topic=tyrant, brokerName=broker-a, queueId=4] ​ ​ 说明第一次发送到了Topic为tyrant,brokerName为broker-a的服务器上,且消息所在的队列的Id=5 说明第二次发送到了Topic为tyrant,brokerName为broker-a的服务器上,且消息所在的队列的Id=6 ....

2)异步消息:延时性

retryTimesWhenSendFailed:同步方式发送消息重试次数,默认为2,总共执行3次。

retryTimesWhenSendAsyncFailed:异步方法发送消息重试次数,默认为2,总共执行3次。

虽然定义了retryTimesWhenSendAsyncFailed但是搜索getRetryTimesWhenSendAsyncFailed却没有用到!

异步消息通常用在对响应时间敏感的业务场景,即发送端不能容忍长时间地等待Broker的响应。

一般也不会使用发送异步消息。异步消息发送成功,但是回调没执行。怎么办呢?

java package rocketmq.base.producer; ​ import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.client.producer.SendCallback; import org.apache.rocketmq.client.producer.SendResult; import org.apache.rocketmq.common.message.Message; import java.util.concurrent.TimeUnit; ​ /** * 发送异步消息 */ public class AsyncProducer { ​    public static void main(String[] args) throws Exception {        //1.创建消息生产者producer,并制定生产者组名        DefaultMQProducer producer = new DefaultMQProducer("group1");        //2.指定Nameserver地址        producer.setNamesrvAddr("127.0.0.1:9876");        //3.启动producer        producer.start(); ​        for (int i = 0; i < 10; i++) {            //4.创建消息对象,指定主题Topic、Tag和消息体            /**             * 参数一:消息主题Topic             * 参数二:消息Tag             * 参数三:消息内容             */            Message msg = new Message("tyrant", "tag", ("Hello World" + i).getBytes());            //5.发送异步消息            producer.send(msg, new SendCallback() {                /**                 发送成功回调函数                 @param sendResult                */                @Override                public void onSuccess(SendResult sendResult) {                    System.out.println("发送结果:" + sendResult);               } ​                /**                 发送失败回调函数                 @param e                */                @Override                public void onException(Throwable e) {                    System.out.println("发送异常:" + e);               }           }); ​            //线程睡1秒            TimeUnit.SECONDS.sleep(1);       } ​        //6.关闭生产者producer        producer.shutdown();   } } ​

3)单向消息:不关心结果

这种方式主要用在不特别关心发送结果的场景,例如日志发送。

java package rocketmq.base.producer; ​ import org.apache.rocketmq.client.exception.MQBrokerException; import org.apache.rocketmq.client.producer.DefaultMQProducer; import org.apache.rocketmq.common.message.Message; ​ import java.util.concurrent.TimeUnit; ​ /** * 发送单向消息 */ public class OneWayProducer { ​    public static void main(String[] args) throws Exception, MQBrokerException {        //1.创建消息生产者producer,并制定生产者组名        DefaultMQProducer producer = new DefaultMQProducer("group1");        //2.指定Nameserver地址        producer.setNamesrvAddr("127.0.0.1:9876");        //3.启动producer        producer.start(); ​        for (int i = 0; i < 3; i++) {            //4.创建消息对象,指定主题Topic、Tag和消息体            /**             * 参数一:消息主题Topic             * 参数二:消息Tag             * 参数三:消息内容             */            Message msg = new Message("test", "test1", ("Hello World,单向消息啊" + i).getBytes());            //5.发送单向消息            producer.sendOneway(msg); ​            //线程睡1秒            TimeUnit.SECONDS.sleep(5);       } ​        //6.关闭生产者producer        producer.shutdown();   } } ​

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值