安装流程--略;RocketMQ安装启动
启动流程:
到对应路径bin下面打开cmd输入:mqnamesrv

启动BROKER:start mqbroker.cmd -n 127.0.0.1:9876 autoCreateTopicEnable=true


启动不起来得话:把c:/user/你的用户名/里面的store里面的所有文件全部删除,再启动,成功
broker应该算是RocketMQ中比较重要的一个环节,负责消息的接收、存储、发送,搭建方式支持主从。实现高性能、高吞吐量。简言之,生产者发送的消息全部到了这里;
注意:我前面一直启动不成功,使用了很多方法都不行,最后偶然发现原因是JDK版本是32位的(也就是默认jdk在C:\Program Files (x86)),和MQ不对应造成的,重新装了64的就好了;
启动可视化程序:


demo
添加依赖:
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.5.1</version>
</dependency>
代码如下:
/**
* @ClassName: MQConfig
* @Author: 中都
* @Date: 2022/1/1 16:53
* @Description: 连接RocketMQ服务器配置类,这里为了方便直接写成常量。
*/
public class MQConfig {
/**
* Name Server 地址,因为是集群部署 所以有多个用 分号 隔开
*/
public static final String NAME_SERVER = "192.168.0.196:9876";
/**
* 主题名称 主题一般是服务器设置好 而不能在代码里去新建topic
* ( 如果没有创建好,生产者往该主题发送消息 会报找不到topic错误)
* mqadmin updateTopic -c DefaultCluster -n 127.0.0.1:9876 -t topic_test
*/
public static final String TOPIC = "topic_test";
}
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
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.apache.rocketmq.remoting.common.RemotingHelper;
import org.springframework.stereotype.Component;
/**
* @ClassName: Producer
* @Author: 中都
* @Date: 2022/1/1 17:12
* @Description: 生产者
*/
@Slf4j
@Component
public class Producer {
private String producerGroup = "test_producer";
private DefaultMQProducer producer;
public Producer() {
start();
}
/**
* 对象在使用之前必须要调用一次,只能初始化一次
*/
public void start() {
// 示例生产者
producer = new DefaultMQProducer(producerGroup);
// 不开启vip通道 开通口端口会减2
producer.setVipChannelEnabled(false);
// 绑定name server
producer.setNamesrvAddr(MQConfig.NAME_SERVER);
// 设置超过多大进行compress压缩
producer.setCompressMsgBodyOverHowmuch(1024 * 10);
// 设置发送失败的尝试次数。
producer.setRetryTimesWhenSendFailed(3);
// 设置如果返回值不是send_ok,是否要重新发送
producer.setRetryAnotherBrokerWhenNotStoreOK(false);
// 设置限制最大的文件大小
producer.setMaxMessageSize(1024*50);
// 设置默认主题对应的队列数
producer.setDefaultTopicQueueNums(4);
// 设置发送超时时间 ms(这个时间给长一点,不然报错sendDefaultImpl call timeout)
producer.setSendMsgTimeout(60000);
try {
this.producer.start();
} catch (MQClientException e) {
log.info(ExceptionUtils.getStackTrace(e));
}
}
/**
* 生产者生产方法
* @param topic 主题
* @param tags 标签,用来给消费者进行过滤的
* @param keys 作为key
* @param body 发送的内容
*/
@SneakyThrows
public SendResult producerSendMes(String topic, String tags, String keys, String body) {
Message message = new Message(topic, tags, keys, body.getBytes(RemotingHelper.DEFAULT_CHARSET));
// 发送
SendResult sendResult = this.producer.send(message);
return sendResult;
}
/**
* 生产者生产方法
* @param topic 主题
* @param tags 标签,用来给消费者进行过滤的
* @param body 发送的内容
*/
@SneakyThrows
public SendResult producerSendMes(String topic, String tags, String body) {
Message message = new Message(topic, tags, body.getBytes(RemotingHelper.DEFAULT_CHARSET));
// 发送
SendResult sendResult = this.producer.send(message);
return sendResult;
}
public DefaultMQProducer getProducer(){
return this.producer;
}
/**
* 一般在应用上下文,使用上下文监听器,进行关闭
*/
public void shutdown() {
this.producer.shutdown();
}
}
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.Message;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
/**
* @ClassName: Producer
* @Author: 中都
* @Date: 2022/1/1 16:55
* @Description: 消费者--一般情況下需要程序启动就开始初始化
*/
@Slf4j
@Component
public class Consumer {
/**
* 消费者实体对象
*/
private DefaultMQPushConsumer consumer;
/**
* 消费者组
*/
public static final String CONSUMER_GROUP = "test_consumer";
/**
* 通过构造函数 实例化对象
* @throws MQClientException
*/
public Consumer() throws MQClientException {
consumer = new DefaultMQPushConsumer(CONSUMER_GROUP);
consumer.setNamesrvAddr(MQConfig.NAME_SERVER);
// 消费模式:一个新的订阅组第一次启动从队列的最后位置开始消费 后续再启动接着上次消费的进度开始消费
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
// 订阅主题和 标签( * 代表所有标签)下信息
consumer.subscribe(MQConfig.TOPIC,"*");
// 注册消费的监听 并在此监听中消费信息,并返回消费的状态信息
consumer.registerMessageListener((MessageListenerConcurrently) (msgs, context) -> {
/**
* msgs中只收集同一个topic,同一个tag,并且key相同的message
* 会把不同的消息分别放置到不同的队列中
*/
try {
for(Message msg : msgs) {
// 消费者获取消息 这里只输出 不做后面逻辑处理
String body = new String(msg.getBody(), "utf-8");
log.info("Consumer-获取消息-主题topic为={}, 消费消息为={}", msg.getTopic(), body);
}
}catch (UnsupportedEncodingException e) {
log.error("rocketMq error:{}", ExceptionUtils.getStackTrace(e));
// 异常重试
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
});
consumer.start();
log.info("消费者 启动成功=======");
}
}
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: RocketMqController
* @Author: 中都
* @Date: 2022/1/1 17:17
* @Description: RocketMQ测试
*/
@Slf4j
@RestController
@RequestMapping(value = "/mq")
public class RocketMqController {
@Autowired
private Producer producer;
private List<String> list;
/**
* 初始化消息
*/
public RocketMqController() {
list = new ArrayList<>();
list.add("小小");
list.add("爸爸");
list.add("妈妈");
list.add("爷爷");
list.add("奶奶");
list.add("外公");
list.add("外婆");
}
@RequestMapping("/test")
public Object callback() throws Exception {
// 总共发送五次消息
for (String s : list) {
// 创建生产信息
SendResult sendResult = producer.producerSendMes(MQConfig.TOPIC, "testtag", ("小小一家人的称谓:" + s));
log.info("输出生产者信息={}",sendResult);
}
return "成功";
}
}
启动程序,访问得到的日志:

对应的可视化程序:

在可视化应用在添加几个消息,后台显示:


浙公网安备 33010602011771号