目录
1、下载Rocketmq
2、环境变量配置
3、启动mq相关服务
3.1 启动namesrv服务
3.2启动brokerserver服务
3.3 解决办法
3.3.1 修改2个cmd文件配置CLASSPATH
3.3.2 去掉2个cmd配置文件
4、实际的代码示例
4.1 引入依赖
4.2 MqConstants
4.3 User实体类
4.4 Producer消息生产者
4.5 Consumer消费者
4.6 生产者生产消息报错
1、下载Rocketmq
rocket文件下载地址https://rocketmq.apache.org/release_notes/release-notes-4.4.0/
解压之后存放在自己的盘符
2、环境变量配置
新建系统变量:
变量名: ROCKETMQ_HOME
变量值: D:\tools\rocketmq-all-4.4.0-bin-release (解压后的 RocketMq 路径)
3、启动mq相关服务
3.1 启动namesrv服务
start mqnamesrv.cmd
3.2启动brokerserver服务
start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true
ps:如果jdk安装的路径为C:\Program Files\Java\jdk1.8.0_212会出现无法启动
3.3 解决办法
3.3.1 修改2个cmd文件配置CLASSPATH
需要修改runserver.cmd, runbroker.cmd这两个文件里面的这个地方的配置
原始的:set CLASSPATH=.;%BASE_DIR%conf;%CLASSPATH%
修改之后的:set CLASSPATH=.;%BASE_DIR%conf;"%CLASSPATH%"
就是这个地方的%CLASSPATH%外面要添加上半角双引号
3.3.2 去掉2个cmd配置文件
需要修改runserver.cmd, runbroker.cmd这两个文件里面的这个地方的配置
runbroker.cmd
原始的:set "JAVA_OPT=%JAVA_OPT% -cp %CLASSPATH%"
修改之后的:set JAVA_OPT=%JAVA_OPT% -cp %CLASSPATH%
runserver.cmd
原始的:set "JAVA_OPT=%JAVA_OPT% -cp "%CLASSPATH%""
修改之后的:set "JAVA_OPT=%JAVA_OPT% -cp %CLASSPATH%"
就是去掉这个地方的双引号。
然后再次执行3.2的命令,启动成功的命令如下图:
4、实际的代码示例
4.1 引入依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.4.0</version>
</dependency>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
4.2 MqConstants
package com.shucha.deveiface.biz.constants;
public class MqConstants {
public interface Topics {
String TOPIC_DEMO1 = "topic_deve-iface";
String TOPIC_DEMO2 = "topic_dev";
}
public interface Tags {
String TAG_DEMO1 = "tag_demo1";
String TAG_DEMO2 = "tag_demo2";
}
public interface ConsumerGroup {
String CONSUMER_GROUP1 = "rmq-group1";
String CONSUMER_GROUP2 = "rmq-group2";
}
public interface InstanceName {
String INSTANCE_Name1 = "producer1";
String INSTANCE_Name2 = "producer2";
}
}
4.3 User实体类
package com.shucha.deveiface.biz.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
/**
* @author tqf
* @Description
* @Version 1.0
* @since 2022-04-07 13:53
*/
@Data
public class User {
/**
* 主键ID
*/
private Long id;
/**
*用户名
*/
private String userName;
/**
* 用户密码
*/
private String passWord;
/**
* 年龄
*/
private Integer age;
/**
* 性别(0-男,1-女,2-未知)
*/
private Integer sex;
/**
* 创建时间
*/
private Date createTime;
}
4.4 Producer消息生产者
package com.shucha.deveiface.biz.mq.producer;
/**
* @author tqf
* @Description 生产者
* @Version 1.0
* @since 2022-04-21 09:58
*/
import com.shucha.deveiface.biz.constants.MqConstants;
import com.shucha.deveiface.biz.model.User;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageQueue;
import java.util.Date;
import java.util.List;
public class Producer {
public static void main(String[] args) throws MQClientException {
producerGroup1();
producerGroup2();
}
public static void producerGroup1() throws MQClientException {
//创建一个消息生产者,传入的是消息组名称
DefaultMQProducer producer = new DefaultMQProducer(MqConstants.ConsumerGroup.CONSUMER_GROUP1);
//输入nameserver服务的地址
producer.setNamesrvAddr("127.0.0.1:9876");
producer.setInstanceName(MqConstants.InstanceName.INSTANCE_Name1);
//启动生产者
producer.start();
try {
for (int i = 0; i < 10; i++) {
// 每秒发送一次MQ
Thread.sleep(1000);
// 创建消息
Message msg = new Message(MqConstants.Topics.TOPIC_DEMO1, MqConstants.Tags.TAG_DEMO1,
// (new Date() + " RocketMQ test msg1 发送消息" + user.toString()).getBytes()// body
(new Date() + " RocketMQ test msg1 发送消息" + i).getBytes()// body
);
//发送,返回结果对象
SendResult sendResult = producer.send(msg);
// 消息id
System.out.println(sendResult.getMsgId());
// 队列信息
System.out.println(sendResult.getMessageQueue());
// 发送结果
System.out.println(sendResult.getSendStatus());
// 下一个要消费的消息的偏移量
System.out.println(sendResult.getOffsetMsgId());
// 队列消息偏移量
System.out.println(sendResult.getQueueOffset());
System.out.println();
System.out.println("================================================");
// System.out.printf("Product:发送状态=%s, 存储queue=%s , message=%s\n", sendResult.getSendStatus(),sendResult.getMessageQueue().getQueueId(), msg);
}
} catch (Exception e) {
e.printStackTrace();
}
producer.shutdown();
}
public static void producerGroup2() throws MQClientException {
//创建一个消息生产者,传入的是消息组名称
DefaultMQProducer producer = new DefaultMQProducer(MqConstants.ConsumerGroup.CONSUMER_GROUP2);
//输入nameserver服务的地址
producer.setNamesrvAddr("127.0.0.1:9876");
producer.setInstanceName(MqConstants.InstanceName.INSTANCE_Name2);
//启动生产者
producer.start();
try {
for (int i = 0; i < 10; i++) {
// 每秒发送一次MQ
Thread.sleep(1000);
// 创建消息
User user = new User();
user.setId(Long.valueOf(i));
user.setUserName("名称"+i);
user.setAge(i);
user.setCreateTime(new Date());
user.setSex(i);
Message msg = new Message(MqConstants.Topics.TOPIC_DEMO2, MqConstants.Tags.TAG_DEMO2,
(new Date() + " RocketMQ test msg1 发送消息" + user.toString()).getBytes()// body
);
//发送,返回结果对象
// SendResult sendResult = producer.send(msg);
// 顺序发送,顺序消费
SendResult sendResult = producer.send(msg, new MessageQueueSelector() {
@Override
public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg) {
return mqs.get(0);
}
},i);
// 消息id
/*System.out.println(sendResult.getMsgId());
// 队列信息
System.out.println(sendResult.getMessageQueue());
// 发送结果
System.out.println(sendResult.getSendStatus());
// 下一个要消费的消息的偏移量
System.out.println(sendResult.getOffsetMsgId());
// 队列消息偏移量
System.out.println(sendResult.getQueueOffset());
System.out.println();
// System.out.println("================================================");*/
System.out.printf("Product:发送状态=%s, 存储queue=%s, message=%s\n", sendResult.getSendStatus(),sendResult.getMessageQueue().getQueueId(), msg);
}
} catch (Exception e) {
e.printStackTrace();
}
producer.shutdown();
}
}
4.5 Consumer消费者
package com.shucha.deveiface.biz.mq.consumer;
/**
* @author tqf
* @Description 第一个消费者
* @Version 1.0
* @since 2022-04-21 10:01
*/
import com.shucha.deveiface.biz.constants.MqConstants;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.*;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.common.RemotingHelper;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Random;
public class Consumer {
public static void main(String[] args) throws MQClientException {
consumer1();
consumer2();
}
public static void consumer1() throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(MqConstants.ConsumerGroup.CONSUMER_GROUP1);
consumer.setNamesrvAddr("127.0.0.1:9876");
consumer.setInstanceName("consumer");
//订阅某个主题,然后使用tag过滤消息,不过滤可以用*代表
consumer.subscribe(MqConstants.Topics.TOPIC_DEMO1, MqConstants.Tags.TAG_DEMO1);
//注册监听回调实现类来处理broker推送过来的消息,MessageListenerConcurrently是并发消费
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> messages, ConsumeConcurrentlyContext context) {
for (MessageExt msg : messages) {
System.out.println(msg.getMsgId() + " ===== " + new String(msg.getBody()));
// String msgBody = new String(msg.getBody(), Charset.forName(RemotingHelper.DEFAULT_CHARSET));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();//消费者启动完成
System.out.println("Consumer Started.");
}
public static void consumer2() throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(MqConstants.ConsumerGroup.CONSUMER_GROUP2);
consumer.setNamesrvAddr("127.0.0.1:9876");
consumer.setInstanceName("consumer");
//订阅某个主题,然后使用tag过滤消息,不过滤可以用*代表
consumer.subscribe(MqConstants.Topics.TOPIC_DEMO2, MqConstants.Tags.TAG_DEMO2);
// 第一种消费方式
//注册监听回调实现类来处理broker推送过来的消息,MessageListenerConcurrently是并发消费
/*consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> messages, ConsumeConcurrentlyContext context) {
for (MessageExt msg : messages) {
System.out.println(msg.getMsgId() + " ===== " + new String(msg.getBody()));
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});*/
// 第二种消费方式
// 消费者真正要达到消费顺序,须要分布式锁,因此这里须要将MessageListenerOrderly替换以前的MessageListenerConcurrently,由于它里面实现了分布式锁
consumer.registerMessageListener((MessageListenerOrderly) (msgs, context) -> {
/*Random random = new Random();
try {
Thread.sleep(random.nextInt(5) * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
for (MessageExt msg : msgs) {
System.out.println(new String(msg.getBody()));
}
return ConsumeOrderlyStatus.SUCCESS;
});
consumer.start();//消费者启动完成
System.out.println("Consumer Started.");
}
}
4.6 生产者生产消息报错
生产者生成消息报错:CODE: 14 DESC: service not available now, maybe disk full, CL: 0.91 CQ: 0.91 INDEX: 0.91, maybe
解决方法,再到conf文件下面的配置文件broker.conf,在文件后面添加一行
diskMaxUsedSpaceRatio=99
重启服务就可以啦。