一 、安装
1、去官网下载: https://rocketmq.apache.org/docs/quick-start/
2、也可以直接下载:https://www.apache.org/dyn/closer.cgi?path=rocketmq/5.1.0/rocketmq-all-5.1.0-bin-release.zip
3、解压
4、配置环境变量
ROCKETMQ_HOME=C:\app\rocketmq-all-5.1.0-bin-release
NAMESRV_ADDR=localhost:9876
5、启动--进入安装目录cd C:\app\rocketmq-all-5.1.0-bin-release,管理员身份cmd打开命令行
# 启动 nameserver
.\bin\mqnamesrv.cmd
# 启动broker
.\bin\mqbroker.cmd -n localhost:9876 autoCreateTopicEnable=true
二、简单应用---上代码
1、创建项目rocketmq-utils,结构如下
2.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.0.4.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springboot-rocketmq</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-acl</artifactId>
<version>5.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-dashboard</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.69</version>
</dependency>
</dependencies>
</project>
3.properties
server.port=8081
spring.application.name=rocketmq-utils
4.RocketmqApplication启动类
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RocketmqApplication {
public static void main(String[] args) {
SpringApplication.run(RocketmqApplication.class,args);
}
}
5.实体类
package org.example.simple;
import org.apache.rocketmq.client.producer.SendStatus;
public class Result {
private SendStatus sendStatus;
private String msgId;
public SendStatus getSendStatus() {
return sendStatus;
}
public void setSendStatus(SendStatus sendStatus) {
this.sendStatus = sendStatus;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
@Override
public String toString() {
return "Result{" +
"sendStatus=" + sendStatus +
", msgId='" + msgId + '\'' +
'}';
}
}
package org.example.simple;
import com.alibaba.fastjson.JSONObject;
public class ProducerOptions {
private String accesskey;
private String accessSecret;
private String nameServer;
private String group;
private String topic;
private String tags = "*";
public String getAccesskey() {
return accesskey;
}
public ProducerOptions setAccesskey(String accesskey) {
this.accesskey = accesskey;
return this;
}
public String getAccessSecret() {
return accessSecret;
}
public ProducerOptions setAccessSecret(String accessSecret) {
this.accessSecret = accessSecret;
return this;
}
public String getNameServer() {
return nameServer;
}
public ProducerOptions setNameServer(String nameServer) {
this.nameServer = nameServer;
return this;
}
public String getGroup() {
return group;
}
public ProducerOptions setGroup(String group) {
this.group = group;
return this;
}
public String getTopic() {
return topic;
}
public ProducerOptions setTopic(String topic) {
this.topic = topic;
return this;
}
public String getTags() {
return tags;
}
public ProducerOptions setTags(String tags) {
this.tags = tags;
return this;
}
public ProducerOptions() {
}
public ProducerOptions(ProducerOptions options) {
this.accesskey = options.getAccesskey();
this.accessSecret = options.getAccessSecret();
this.nameServer = options.getNameServer();
this.group = options.getGroup();
this.topic = options.getTopic();
this.tags = options.getTags();
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
package org.example.simple;
import com.alibaba.fastjson.JSONObject;
public class ConsumerOptions {
private String accesskey;
private String accessSecret;
private String nameServer;
private String group;
private String topic;
private String tags = "*";
public String getAccesskey() {
return accesskey;
}
public ConsumerOptions setAccesskey(String accesskey) {
this.accesskey = accesskey;
return this;
}
public String getAccessSecret() {
return accessSecret;
}
public ConsumerOptions setAccessSecret(String accessSecret) {
this.accessSecret = accessSecret;
return this;
}
public String getNameServer() {
return nameServer;
}
public ConsumerOptions setNameServer(String nameServer) {
this.nameServer = nameServer;
return this;
}
public String getGroup() {
return group;
}
public ConsumerOptions setGroup(String group) {
this.group = group;
return this;
}
public String getTopic() {
return topic;
}
public ConsumerOptions setTopic(String topic) {
this.topic = topic;
return this;
}
public String getTags() {
return tags;
}
public ConsumerOptions setTags(String tags) {
this.tags = tags;
return this;
}
public ConsumerOptions() {
}
public ConsumerOptions(ConsumerOptions options) {
this.accesskey = options.getAccesskey();
this.accessSecret = options.getAccessSecret();
this.nameServer = options.getNameServer();
this.group = options.getGroup();
this.topic = options.getTopic();
this.tags = options.getTags();
}
@Override
public String toString() {
return JSONObject.toJSONString(this);
}
}
6.生产者消费者接口
package org.example.simple.service;
import org.apache.rocketmq.client.exception.MQClientException;
public interface ProducerService {
void sendMsg(String body) throws MQClientException;
}
package org.example.simple.service;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
public interface ConsumerService {
void consumerMsg(MessageListenerConcurrently listener) throws MQClientException;
}
7.消费者监听器
package org.example.simple;
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.common.message.MessageExt;
import java.util.List;
public class ConsumerListener implements MessageListenerConcurrently {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
for (MessageExt messageExt : list) {
String messageBody = new String(messageExt.getBody());
System.out.println("messageExt: " + messageExt);//输出消息内容
System.out.println(messageExt.getStoreHost());//获取对应rocketmq服务器ip地址
System.out.println("消费响应:msgId : " + messageExt.getMsgId() + ", msgBody : " + messageBody);//输出消息内容
// TODO Auto-generated method stub
}
//返回消费状态:CONSUME_SUCCESS 消费成功;RECONSUME_LATER 消费失败,需要稍后重新消费
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
}
8.生产者消费者实现类
package org.example.simple.impl;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.example.simple.ProducerOptions;
import org.example.simple.Result;
import org.example.simple.service.ProducerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class ProducerServiceImpl implements ProducerService {
private final static Logger logger = LoggerFactory.getLogger(ProducerServiceImpl.class);
private ProducerOptions options;
public ProducerServiceImpl() {
}
public ProducerServiceImpl(ProducerOptions options) {
this.options = options;
}
private DefaultMQProducer builder() throws MQClientException {
DefaultMQProducer defaultMQProducer = null;
if (StringUtils.isNotBlank(options.getAccesskey()) && StringUtils.isNotBlank(options.getAccessSecret())) {
defaultMQProducer = new DefaultMQProducer(options.getGroup(),
new AclClientRPCHook(new SessionCredentials(options.getAccesskey(), options.getAccessSecret())));
} else {
defaultMQProducer = new DefaultMQProducer(options.getGroup());
}
defaultMQProducer.setNamesrvAddr(options.getNameServer());
// 发送失败重试次数
defaultMQProducer.setRetryTimesWhenSendFailed(3);
// 超时时间
defaultMQProducer.setSendMsgTimeout(3000);
defaultMQProducer.start();
return defaultMQProducer;
}
@Override
public void sendMsg(String body) throws MQClientException {
DefaultMQProducer producer = builder();
try {
body = "" + new Date();
//设置消息的类型
//设置消息的Topic
//设置消息tags ,tags可以设置多个用||分割例如"TagA||TagC||TagD"
//消息的实体内容
Message msg = new Message(options.getTopic(),options.getTags(),body.getBytes());
//同步方式发送(produer.start()发送消息),会得到一个返回值
// SendResult sendResult = producer.send(msg);
// Result result = new Result();
// //打印返回内容
// System.out.println(sendResult.toString());
// result.setMsgId(sendResult.getMsgId());
// result.setSendStatus(sendResult.getSendStatus());
//异步
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
//打印返回内容
System.out.printf("你好:" + sendResult.toString());
}
@Override
public void onException(Throwable e) {
System.out.printf("%-10d Exception %n", e);
e.printStackTrace();
}
});
} catch (Exception e) {
logger.error("[Producer生产者]--Producer发送消息异常!e={}", e.getMessage());
throw new RuntimeException("[Producer生产者]--Producer发送消息异常!", e);
} finally {
if (null != producer) {
//关闭producer
producer.shutdown();
System.out.println("Producer Shutdown");
}
}
}
}
package org.example.simple.impl;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.remoting.protocol.heartbeat.MessageModel;
import org.example.simple.ConsumerOptions;
import org.example.simple.service.ConsumerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class ConsumerServiceImpl implements ConsumerService {
private final static Logger logger = LoggerFactory.getLogger(ConsumerServiceImpl.class);
private ConsumerOptions options;
public ConsumerServiceImpl() {
}
public ConsumerServiceImpl(ConsumerOptions options) {
this.options = options;
}
@Override
public void consumerMsg(MessageListenerConcurrently listener) throws MQClientException {
DefaultMQPushConsumer consumer = null;
if (StringUtils.isNotBlank(options.getAccesskey()) && StringUtils.isNotBlank(options.getAccessSecret())) {
consumer = new DefaultMQPushConsumer(options.getGroup(),
new AclClientRPCHook(new SessionCredentials(options.getAccesskey(), options.getAccessSecret())),
// 平均分配队列算法,hash
new AllocateMessageQueueAveragely());
} else {
consumer = new DefaultMQPushConsumer(options.getGroup());
}
consumer.setNamesrvAddr(options.getNameServer());
//设置的是一个consumer的消费策略
//CONSUME_FROM_LAST_OFFSET 默认策略,从该队列最尾开始消费,即跳过历史消息
//CONSUME_FROM_FIRST_OFFSET 从队列最开始开始消费,即历史消息(还储存在broker的)全部消费一遍
//CONSUME_FROM_TIMESTAMP 从某个时间点开始消费,和setConsumeTimestamp()配合使用,默认是半个小时以前
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
// 消费模式:集群模式
// 集群:同一条消息 只会被一个消费者节点消费到
// 广播:同一条消息 每个消费者都会消费到
consumer.setMessageModel(MessageModel.CLUSTERING);
// 设置每次拉取的消息量,默认为1
consumer.setConsumeMessageBatchMaxSize(100);
// 订阅MyTopic的所有消息defaultMQPushConsumer.subscribe(topic, "*");
//设置订阅的Topic和tags
consumer.subscribe(options.getTopic(), options.getTags());
consumer.registerMessageListener(listener);
try {
// 启动消费者
consumer.start();
} catch (MQClientException e) {
logger.error("[Consumer消费者]--Consumer加载异常!e={}", e.getMessage());
throw new RuntimeException("[Consumer消费者]--Consumer加载异常!", e);
}
logger.info("[Consumer消费者]--Consumer加载完成!");
}
}
9.单元测试
package org.example;
import com.alibaba.fastjson.JSONObject;
import com.sun.deploy.association.utility.AppConstants;
import org.apache.rocketmq.client.exception.MQClientException;
import org.example.simple.*;
import org.example.simple.impl.ConsumerServiceImpl;
import org.example.simple.impl.ProducerServiceImpl;
import org.example.simple.service.ConsumerService;
import org.example.simple.service.ProducerService;
import org.junit.Before;
import org.junit.Test;
public class MQTest {
@Test
public void test_producer() throws MQClientException {
ProducerOptions options = new ProducerOptions()
.setGroup("producer").setNameServer("localhost:9876")
// .setAccesskey("qwjgqh").setAccessSecret("sdfafd")
.setTopic("123456").setTags("user_register");
ProducerService instance = new ProducerServiceImpl(options);
JSONObject jsonObject = new JSONObject();
jsonObject.put("account","sadjkfja");
jsonObject.put("intuid","asfdadfad");
jsonObject.put("type","afdasfas");
try{
instance.sendMsg(jsonObject.toJSONString());
} catch (MQClientException e) {
System.out.println("发送mq消息,e=" + e);
}
}
@Before
public void before() throws MQClientException {
ConsumerOptions options = new ConsumerOptions()
.setGroup("producer").setNameServer("localhost:9876")
// .setAccesskey("qwjgqh").setAccessSecret("sdfafd")
.setTopic("123456").setTags("*");
ConsumerService consumerService = new ConsumerServiceImpl(options);
ConsumerListener consumerListener = new ConsumerListener();
consumerService.consumerMsg(consumerListener);
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}