本教程是简明教程,供快速入门,不废话
rocketmq-all-4.9.1-bin-release.zip
解压到自己的工作目录
unzip rocketmq-all-4.9.3-source-release.zip
启动nameserv : nohup sh bin/mqnamesrv &
启动broker : nohup sh bin/mqbroker -n localhost:9876 &
使用jps -l 查看是否启动
注意 这个地方很多人没有启动成功,是因为他设置的broker堆栈太大8个G,这里需要修改一下broker启动文件的配置
路径: /usr/local/rocket/rocketmq-all-4.9.1-bin-release/bin
JAVA_OPT=“${JAVA_OPT} -server -Xms256m -Xmx256m”
修改后再次启动broker, 执行jps -l
会发现启动起来了
注意启动顺序。
1: export NAMESRV_ADDR=localhost:9876 暴露 9876duankou
2: sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer 生产者发送消息
完后点ctrl+c 结束就行,他会发送1K条数据
3:sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer 消费者接受消息
能收到消息说明接受成功。
下载
wget -P /usr/local/rocket https://github.com/apache/rocketmq-dashboard/archive/refs/tags/rocketmq-dashboard-1.0.0.tar.gz
解压
tar -zxvf rocketmq-dashboard-1.0.0.tar.gz
maven编译
mvn clean package -Dmaven.test.skip=true -f rocketmq-dashboard-rocketmq-dashboard-1.0.0
将target下的jar文件拷贝到本目录
cp -r rocketmq-dashboard-rocketmq-dashboard-1.0.0/target/rocketmq-dashboard-1.0.0.jar /usr/local/rocket
后台启动
nohup java -jar /usr/local/rocket/rocketmq-dashboard/rocketmq-dashboard-1.0.0.jar &
jps-l 查看进程
在window系统数据
http:// 你自己linux的IP:8080
注意 : 要关闭防火墙 systemctl stop firewalld
引入maven
org.apache.rocketmq
rocketmq-client
4.9.3
命名服务器 nameserv: 管理broker.
消息生产者发送消息时,先去nameserv查询消息发给哪个broker。nameserv相当于注册中心,管理broker集群,通过心跳机制检查broker是否处于活跃状态。
客户端(消息生产者和消费者)在发送、接受消息时,都先通过nameserv确认接受哪一个broker的消息。
客户端通过以下方式找到nameserv地址
1: 配置环境变量 NAMESRV_ADDR=localhost:9876
2: producer.setNamesrvAddr("localhost:9876");
启动顺序
先启动生产者
再启动消费者,消费者不关闭
生产者
public class MyRocketProducer {
public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {
// 声明生产者所在的组
DefaultMQProducer producer = new DefaultMQProducer("mygroup");
// 注册nameserv地址
producer.setNamesrvAddr("192.168.1.7:9876");
// 启动生产
producer.start();
// 当发送失败时,需要从新发送的次数
producer.setRetryTimesWhenSendAsyncFailed(3);
// 发送消息 this is test 参数:1:test 主题 2 tag 相当于二级主题 3:以byte方式发送消息
Message msg = new Message("test","tagA" ,"this is test".getBytes(StandardCharsets.UTF_8));
// 共执行几个任务,我们发送1条数据 所以是1,此时 主线程会在任务结束后 再次执行,采用的是异步发送消息模式
final CountDownLatch countDownLatch = new CountDownLatch(1);
// 发送消息
producer.send(msg, new SendCallback() {
// 发送成功
@Override
public void onSuccess(SendResult sendResult) {
countDownLatch.countDown();
System.out.println("我发送了/n"+ sendResult);
}
// 发送失败处理方式
@Override
public void onException(Throwable e) {
countDownLatch.countDown();
System.out.println("发送失败了");
e.printStackTrace();
}
});
countDownLatch.await(5, TimeUnit.SECONDS);
// 生产者关闭
producer.shutdown();
}
}
consumer
public class MyRocketConsumer {
public static void main(String[] args) throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("mygroup");
consumer.setNamesrvAddr("192.168.1.7:9876");
consumer.subscribe("test","*");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) {
msgs.stream().forEach(messageExt -> {
byte[] body = messageExt.getBody();
System.out.println("consumer receiv:"+new String(body));
});
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
// 注意消费者没有关闭,因为 broker的消息以推送方式发送给消费者,启动了监听,如果断掉,消费者无法接受消息
}
}
案例1:RocketMQ 在集群模式下,对同一主题相同组时,所有消费者不会产生重复消费。
案例2:RocketMQ 在集群模式下,对同一主题不同组是广播模式,即所有消费者都会产生重复消费
案例1:
修改 生产者发送10条消息
public class MyRocketProducer {
public static void main(String[] args) throws MQClientException, MQBrokerException, RemotingException, InterruptedException {
DefaultMQProducer producer = new DefaultMQProducer("mygroup");
producer.setNamesrvAddr("192.168.1.7:9876");
producer.start();
producer.setRetryTimesWhenSendAsyncFailed(3);
for (int i = 0; i < 10; i++) {
Message msg = new Message("test","tagA" ,("this is test"+i).getBytes(StandardCharsets.UTF_8));
SendResult send = producer.send(msg);
System.out.println("发送了消息:"+i+"/n"+send);
}
producer.shutdown();
}
}
同时启动2个生产者
此时可以看到消费1 和 消费2 没有产生重复消费
如果要同组内的消费者 全部消费 则设置模式
案例2:
启动消费1
启动消费2 之前,修改组(随便换一个)
启动生产者 可以看到组不相同 则会产生重复消费 即 都消费了1-9 这些消息
实时性强,消息发送出去后,必须等到有返回后才进行下一步操作。如秒杀下单后,需要及时返回成功信息
producer
public class Producer {
public static void main(String[] args) throws MQBrokerException, RemotingException, InterruptedException, MQClientException {
DefaultMQProducer producer = new DefaultMQProducer("pros1");
producer.setNamesrvAddr("192.168.1.101:9876");
producer.start();
for (int i = 0; i < 10; i++) {
String msg = "hello world "+i;
Message message = new Message("topic1","tag1",msg.getBytes(StandardCharsets.UTF_8));
SendResult send = producer.send(message);
System.out.println(send);
}
producer.shutdown();
}
}
consumer
public class Consumer {
public static void main(String[] args) throws MQClientException {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("c1");
consumer.setNamesrvAddr("192.168.1.101:9876");
consumer.subscribe("topic1","*");
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) {
msgs.forEach(e->{
System.out.println(e.toString());
});
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
};
});
consumer.start();
}
}
即时性弱,消息发送后,不必等待处理消息结束,就立即返回结果。
producer
public class Producer {
public static void main(String[] args) throws MQBrokerException, RemotingException, InterruptedException, MQClientException {
DefaultMQProducer producer = new DefaultMQProducer("pros1");
producer.setNamesrvAddr("192.168.1.101:9876");
producer.start();
for (int i = 0; i < 10; i++) {
String msg = "hello world "+i;
Message message = new Message("topic1","tag1",msg.getBytes(StandardCharsets.UTF_8));
producer.send(message, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println(sendResult);
}
@Override
public void onException(Throwable e) {
System.out.println(e.getMessage());
}
});
}
Thread.sleep(1000);
producer.shutdown();
}
}
consumer
代码和上述代码一致
只管发,别的啥都不管
修改生产者为 sendOneWay(),如下图,可以看到 没有返回消息
message共分多个延迟等级,1S代表1等级
设置延迟等级方式:
在produce里面,
Message msg = new Message(“test”,“tagA” ,(“this is test”+i).getBytes(StandardCharsets.UTF_8));
msg.setDelayTimeLevel(1);
批量消息 修改produce。
public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
DefaultMQProducer producer = new DefaultMQProducer("mygroup");
producer.setNamesrvAddr("192.168.1.121:9876");
producer.start();
// 批量添加3条消息
List list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Message msg = new Message("test2","tagA" ,("this is test "+i).getBytes(StandardCharsets.UTF_8));
list.add(msg);
}
SendResult send = producer.send(list);
producer.shutdown();
System.out.println("发送了消息完成"+send);
}
注意:
1: 使用批量消息时,不能将消息设置为延迟消息
2:官网 要求批量消息大小为1MiB,但一般都是以4M为上限
打开消息过滤功能,切换到 rocker bin目录下,因为mqadmin命令在这个目录。
mqadmin updateBrokerConfig -blocalhost:10911 -kenablePropertyFilter -vtrue
获取
produce
public static void main(String[] args) throws MQClientException, RemotingException, InterruptedException, MQBrokerException {
DefaultMQProducer producer = new DefaultMQProducer("mygroup");
producer.setNamesrvAddr("192.168.1.121:9876");
producer.start();
List list = new ArrayList<>();
for (int i = 0; i < 3; i++) {
Message msg = new Message("test2","vip" ,("this is test "+i).getBytes(StandardCharsets.UTF_8));
// 给消息设置属性
msg.putUserProperty("seria",i+"");
list.add(msg);
}
SendResult send = producer.send(list);
producer.shutdown();
System.out.println("发送了消息完成"+send);
}
consumer
获取seria< 2的消息
consumer.subscribe("test2", MessageSelector.bySql("seria<2")); // bysql 类似于 sql语句 where 后面的语法