参考官方文档 https://rocketmq.apache.org/docs/quick-start/
下载rocketmq源码 https://rocketmq.apache.org/dowloading/releases/ (我的版本为4.5.0 。最新的4.8.0安装namesrv时报错)
解压源码
unzip rocketmq-all-4.5.0-source-release.zip
进入解压文件夹,使用mvn编译(需要maven版本3.0以上)
mvn -Prelease-all -DskipTests clean install -U
启动namesrv
修改bin目录下的runserver.sh虚拟机内存参数
cd distribution/target/apache-rocketmq/
vim bin/runserver.sh
将
JAVA_OPT="${JAVA_OPT} -server -Xms2g -Xmx2g -Xmn1g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
修改为
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
启动命令
nohub sh bin/mqnamesrv >namesrv.log 2>&1 &
启动broker
修改bin目录下runbroker.sh的java虚拟机内存参数
JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g"
修改为
JAVA_OPT="${JAVA_OPT} -server -Xms1g -Xmx1g -Xmn512m"
启动broker
nohub sh bin/mqbroker -n localhost:9876 -c conf/2m-noslave/broker-a.properties >broker-a.log 2>&1 &
注意 localhost是namesrv的ip地址或域名
namesrv与broker都可以是集群部署,参考conf目录下的2m-2s-async(2主2从异步) 目录下的配置文件,只需要执行sh bin/mqbroker命令时替换不同的配置文件即可
关闭 namesrv和broker
sh bin/mqshutdown broker
sh bin/mqshutdown namesrv
java示例代码
pom依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.4</version>
</dependency>
application.properties
#=======================================================ROCKET MQ====================================================#
rocketmq.name-server=192.168.92.128:9876
#消息发送组
rocketmq.producer.group=rocket-group
ProducerService.java
package com.wl.mq.rocket;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Service;
/**
* Created by Administrator on 2021/3/6.
*/
@Service
public class ProducerService {
private RocketMQTemplate rocketMQTemplate;
@Autowired
public ProducerService(RocketMQTemplate rocketMQTemplate){
this.rocketMQTemplate = rocketMQTemplate;
}
/**
* 同步发送消息
* destination formats: `topicName:tags`
* 最终调用 RocketMQTemplate 中的 doSend 方法
*/
public void convertAndSend(String destination,String message){
rocketMQTemplate.convertAndSend(destination,message);
}
/**
* MessageBuilder.withPayload("Hello, World! I'm from spring message").build()
* 最终调用 RocketMQTemplate 中的 doSend 方法
*/
public void send(String destination, Message message){
rocketMQTemplate.send(destination, message);
}
public void syncSend(String destination,String message){
rocketMQTemplate.syncSend(destination,message);
}
public SendResult syncSendOrderly(String destination, String message, String hashKey){
return rocketMQTemplate.syncSendOrderly(destination,message,hashKey);
}
//========================================================================
//send messgae asynchronously
public void asyncSend(String destination,String message){
rocketMQTemplate.asyncSend(destination,message,null);
}
public void asyncSend(String destination, String message, SendCallback callback){
rocketMQTemplate.asyncSend(destination,message,callback);
}
public void asyncSendOrderly(String destination,String message,String hashKey){
rocketMQTemplate.asyncSendOrderly(destination,message,hashKey,null);
}
public void asyncSendOrderly(String destination,String message,String hashKey,SendCallback callback){
rocketMQTemplate.asyncSendOrderly(destination,message,hashKey,callback);
}
}
ConsumerServiceA.java
package com.wl.mq.rocket;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
/**
* Created by Administrator on 2021/3/6.
* RocketMQMessageListener 监听相同的topic 如果consumerGroup不一样则会所有的consumerGroup都会被消费(将ConsumerServiceB注释打开执行RocketMqTest 会发现消息被消费两次)
* 在集群环境下consumerGroup一样(例如将这个服务分别部署到两台服务器上)则 ConsumerServiceA只会消费一次OnMessage(相当于activeMq中的虚拟topic)
注意 一个应用里面consumerGroup必须全局唯一,否则应用将启动失败。
*
*/
@Service
@RocketMQMessageListener(topic = "rocket-order-topic", consumerGroup = "rocket-consumer-order-topic-a")
public class ConsumerServiceA implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.println("================================================ rocket-consumer-order-topic-a");
System.out.println("=============rocket-order-topic=================");
System.out.println(message);
System.out.println("=============rocket-order-topic=================");
}
}
测试代码
package com.wl.mq;
import com.wl.mq.rocket.ProducerService;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* Created by Administrator on 2021/3/6.
*/
@SpringBootTest(classes = Application.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class RocketMqTest {
@Autowired
private ProducerService producerService;
@Test
public void testConvertAndSend() throws Exception{
String destination = "rocket-order-topic";
String message = "hello this is rocketMq topic message testConvertAndSend";
producerService.convertAndSend(destination,message);
Thread.sleep(100000);
}
@Test
public void testSend() throws Exception{
String destination = "rocket-order-topic";
String message = "hello this is rocketMq topic message testSend";
producerService.convertAndSend(destination,message);
Thread.sleep(100000);
}
@Test
public void testSyncSend() throws Exception{
String destination = "rocket-order-topic";
String message = "hello this is rocketMq topic message testSyncSend";
producerService.syncSend(destination,message);
Thread.sleep(100000);
}
@Test
public void testSyncSendOrderly() throws Exception{
String destination = "rocket-order-topic";
String message = "hello this is rocketMq topic message testSyncSendOrderly";
String hashKey = "hashKey";
SendResult sendResult = producerService.syncSendOrderly(destination,message,hashKey);
System.out.println(sendResult.getSendStatus());
Thread.sleep(100000);
}
@Test
public void testAsyncSend() throws Exception{
String destination = "rocket-order-topic";
String message = "hello this is rocketMq topic message testAsyncSend";
producerService.asyncSend(destination,message);
Thread.sleep(100000);
}
@Test
public void testAsyncSendCallBack() throws Exception{
String destination = "rocket-order-topic";
String message = "hello this is rocketMq topic message testAsyncSendCallBack";
producerService.asyncSend(destination, message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println("===========success==============");
}
@Override
public void onException(Throwable throwable) {
System.out.println("============exception===========");
}
});
Thread.sleep(100000);
}
}
在rocketmq中,集群环境下如果监听的topic相同且consumerGroup相同,那么该消息只会被执行一次,完美解决了activemq中集群环境下topic会被重复消费的问题(activemq可以通过虚拟topic解决该问题)
rocketmq 控制台
进入github https://github.com/apache/rocketmq-externals
打开rocketmq-console项目,这是一个spring-boot项目修改其application.properties中的rocketmq.config.namesrvAddr=192.168.92.128:9876参数
启动application打开locahost:8080如下