4.1 消息发送基本样例
- 导入rocketmq-demo
- 导入MQ客户端依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.4.0</version>
</dependency>
- 消息发送者步骤分析
1.创建消息生产者producer,并指定生产者组名
2.指定Nameserver地址
3.启动producer
4.创建消息对象,指定主题Topic、Tag和消息体
5.发送消息
6.关闭生产者producer
- 消息消费者步骤分析
1.创建消费者Consumer,制定消费者组名
2.指定Nameserver地址
3.订阅主题Topic和Tag
4.设置回调函数,处理消息
5.启动消费者consumer
4.1.1 消息发送
1)同步消息:可靠性
retryTimesWhenSendFailed:同步方式发送消息重试次数,默认为2,总共执行3次。
retryTimesWhenSendAsyncFailed:异步方法发送消息重试次数,默认为2,总共执行3次
发送同步消息如果开启retryAnotherBrokerWhenNotStoreOK会自动重试3次,默认是false,但是可能会造成消息的重复发送。
这种可靠性同步地发送方式使用的比较广泛,比如:重要的消息通知,短信通知。
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();
}
}
消息发送结果
结果: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的响应。
一般也不会使用发送异步消息。异步消息发送成功,但是回调没执行。怎么办呢?
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)单向消息:不关心结果
这种方式主要用在不特别关心发送结果的场景,例如日志发送。
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();
}
}