rocketMq消息队列就是临时接收消息的地方,生产者生产消息存储在这里,消费者消费消息。
1.下载rocketmq包
mq下载地址: https://rocketmq.apache.org/release_notes/release-notes-4.9.3/
mq官方文档: https://github.com/apache/rocketmq/tree/master/docs/cn
2.springboot中添加对应的依赖和配置文件中配置地址
<!--rocketMq消息队列-->
<dependency>
<groupId>com.alibaba.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>3.2.6</version>
</dependency>
#下面的配置其实是非必须的,需要配置也就是那个nameServer的信息,其他可以默认
rocketmq.nameServer=localhost:9876
rocketmq.producer.group=p_group
rocketmq.consumer.group=c_group
rocketmq.consumer.topic=c_topic
3.生产者发送消息
@RequestMapping("/mqt")
public void mqtemplate() {
for (int i = 0; i < 10; i++) {
mqtemplate.convertAndSend("testmq", "测试模板啊" + i);
}
}
上面是直接发送消息到 testmq主题中去,发送的内容是后面的数据,如果不使用模板发送消息,可以使用
essage message = new Message(topic, tags, body.getBytes(StandardCharsets.UTF_8));
上面的发送消息的topic是消息的主题,tags是消息的标签,每条消息都有这两部分,如果一条消息表示一个学生,则topic表示学校,tags表示年级,进行区分这些消息.
4.消费者消费消息
@Component
@RocketMQMessageListener(topic = "testmq",selectorExpression="*",consumerGroup = "mygroup")
public class MqConsumerServicer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("消费的消息是;"+message);
}
}
消费消息的类需要实现消息监听器的接口RocketMQListener,且需要再上面添加@RocketMQMessageListener(topic = “testmq”,consumerGroup = “mygroup”)来监听哪些类型的消息。这里表示监听topic=testmq的所有消息
5.启动rocketMq的服务器
进入/rocketMq/bin文件夹的命令窗口下运行下面的命令
start mqnamesrv.cmd
start mqbroker.cmd -h localhost:9876 autoCreateTopicEnable=true
其中mqnamesrv是用来保存broker的信息的,所有的生产者定时向通过mqnamesrv获取broker的信息,所有的broker定时向mqnamesrv添加自己的信息。
mqbroker后面的参数是为了自动创建topic,如果没有的话程序运行会报错 org.apache.rocketmq.client.exception.MQClientException: No route info of this topic: xxxx
6.mq测试例子
public static void main(String[] args) throws Exception {
// 生产者
new Thread() {
public void run() {
try {
startProducer1();
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
//消费者
new Thread() {
public void run() {
try {
Thread.sleep(1000);
startConsumer();
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
}
static void startConsumer() throws MQClientException {
DefaultMQPushConsumer mqc=new DefaultMQPushConsumer();
mqc.setConsumerGroup("c_consumer");
// mqc.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET); // 顺序消息处理的开始处理的位置。
mqc.setNamesrvAddr("test:9876");
mqc.subscribe("p_top","*");
mqc.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
Iterator<MessageExt> iterator= msgs.iterator();
while(iterator.hasNext()) {
System.out.println(new String(iterator.next().getBody(),StandardCharsets.UTF_8));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
mqc.start();
}
/**
* 单向发送消息
* @throws Exception
*/
static void startProducer1() throws Exception {
DefaultMQProducer cmq=new DefaultMQProducer();
cmq.setProducerGroup("proceduce_group");
cmq.setNamesrvAddr("test:9876");
cmq.start();
for(int i=0;i<1000;i++) {
Message msg=new Message("p_top", "tag_a", "", ("测试啊").getBytes(StandardCharsets.UTF_8));
cmq.sendOneway(msg);
}
cmq.shutdown();
}
/**
* 异步消息
* @throws Exception
*/
static void startProducer2() throws Exception {
DefaultMQProducer cmq=new DefaultMQProducer();
cmq.setProducerGroup("proceduce_group");
cmq.setNamesrvAddr("test:9876");
cmq.start();
cmq.setRetryTimesWhenSendFailed(0);
for(int i=0;i<1000;i++) {
Message msg=new Message("p_top", "tag_a", "", ("测试啊").getBytes(StandardCharsets.UTF_8));
cmq.send(msg,new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("发送成功了"+sendResult.getSendStatus());
}
@Override
public void onException(Throwable e) {
e.printStackTrace();
System.out.println("发送失败了");
}
});
}
cmq.shutdown();
}