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(); } }