RocketMQ学习(一)——简介加部署及快速入门
文章目录
前言
通过网课学习笔记
一、RocketMQ简介
(一)简介
Apache RocketMQ是一个采用Java语言开发的分布式的消息系统,由阿里巴巴团队开发,与2016年底贡献给Apache,成为了Apache的一个顶级项目。
官网地址
(二)底层原理
producer:消息生产者,负责提供发送消息。
consumer:消息消费者,异步从消息队列中拉取消息。一般分为push consumer(服务端推送消息)和pull consumer(主动拉取消息)两类。
nameServer:负责记录broker元数据,负责消息队列协调工作。
broker:是RocketMQ的核心负责消息的发送、接收、高可用等(真正干活的),需要定时发送自身情况到NameServer,默认10秒发送一次,超时2分钟会认为该broker失效。
Topic:不同类型的消息以不同的Topic名称进行区分,如User、Order等是逻辑概念。
Message Queue:消息队列,用于存储消息
二、linux部署
(一)非docker环境部署
下载链接:安装包
cd /rocketmq
unzip rocketmq-all-4.3.2-bin-release.zip
cd rocketmq-all-4.3.2-bin-release
#启动nameserver
bin/mqnamesrv
# The Name Server boot success. serializeType=JSON 看到这个表示已经提供成功
#启动broker
bin/mqbroker -n 192.168.17.101:9876 #-n 指定nameserver地址和端口
#启动出错
Java HotSpot(TM) 64-Bit Server VM warning: INFO:
os::commit_memory(0x00000005c0000000, 8589934592, 0) failed; error='Cannot allocate
memory' (errno=12)
…………………………………………………………………
启动错误,是因为内存不够,导致启动失败,需要调整启动内存
#调整默认的内存大小参数
cd bin/
vim runserver.sh
JAVA_OPT="${JAVA_OPT} -server -Xms128m -Xmx128m -Xmn128m -XX:MetaspaceSize=128m -
XX:MaxMetaspaceSize=128m"
cd bin/
vim runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms128m -Xmx128m -Xmn128m"
#从新启动测试
bin/mqbroker -n 172.16.55.185:9876
The broker[172.17.0.1:10911] boot success. serializeType=JSON and name
server is 172.16.185.55:9876
这里注意:会发现broker的启动ip和namespace的ip不同,并通过外网不能对该ip进行访问,这里需要自己设置配置文件。
#创建broker配置文件
vim /rocketmq/rmq/rmqbroker/conf/broker.conf
#指定brokerip
brokerIP1=172.16.55.185
namesrvAddr=172.16.55.185:9876
#确定镜像名
brokerName=broker_test
#启动broker,通过 -c 指定配置文件
bin/mqbroker -c /rocketmq/rmq/rmqbroker/conf/broker.conf
The broker[172.16.55.185:10911] boot success. serializeType=JSON and name
server is 172.16.55.185:9876 #这样就可以进行访问了
(二)docker部署
#拉取镜像 这里注意没用官方镜像
docker pull foxiswho/rocketmq:server-4.3.2
docker pull foxiswho/rocketmq:broker-4.3.2
#创建nameserver容器
docker create -p 9876:9876 --name rmqserver \
-e "JAVA_OPT_EXT=-server -Xms128m -Xmx128m -Xmn128m" \
-e "JAVA_OPTS=-Duser.home=/opt" \
-v /rocketmq/rmq/rmqserver/logs:/opt/logs \
-v /rocketmq/rmq/rmqserver/store:/opt/store \
foxiswho/rocketmq:server-4.3.2
#创建broker容器
docker create -p 10911:10911 -p 10909:10909 --name rmqbroker \
-e "JAVA_OPTS=-Duser.home=/opt" \
-e "JAVA_OPT_EXT=-server -Xms128m -Xmx128m -Xmn128m" \
-v /rocketmq/rmq/rmqbroker/conf/broker.conf:/etc/rocketmq/broker.conf \
-v /rocketmq/rmq/rmqbroker/logs:/opt/logs \
-v /rocketmq/rmq/rmqbroker/store:/opt/store \
foxiswho/rocketmq:broker-4.3.2
#启动容器
docker start rmqserver rmqbroker
#停止删除容器
docker stop rmqbroker rmqserver
docker rm rmqbroker rmqserver
(三)管理软件
rocketMQ提供了UI管理工具,名为rocketmq-console,项目地址:地址链接
该工具支持docker以及非docker安装,这里我们选择使用docker安装
#拉取镜像
docker pull styletang/rocketmq-console-ng:1.0.0
#创建并启动容器
docker run -e "JAVA_OPTS=-Drocketmq.namesrv.addr=172.16.55.185:9876 -
Dcom.rocketmq.sendMessageWithVIPChannel=false" -p 8082:8080 -t styletang/rocketmq-console-ng:1.0.0
通过服务器地址和8082端口号即可访问
三、快速入门
(一)导入maven依赖
<dependencies>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.3.2</version>
</dependency>
</dependencies>
(二)创造topic
package com.dbh123.rocketmq.topic;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
/**
* @description:
* @author: DBH123
* @date: 2021/8/18 0:07
*/
public class ProduceTopic {
public static void main(String[] args) throws Exception{
DefaultMQProducer producer = new DefaultMQProducer("producers");
producer.setNamesrvAddr("192.168.17.101:9876");
producer.start();
/*
* * key:broker名称 broker配置文件设置
* newTopic:topic名称
* queueNum:队列数(分区)
* */
producer.createTopic("broker_test" , "topic_test" , 10);
System.out.println("topic 创建成功");
producer.shutdown();
}
}
(三)创建同步生产者
package com.dbh123.rocketmq.producer;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
/**
* @description:
* @author: DBH123
* @date: 2021/8/18 0:03
*/
public class SyncProducer {
public static void main(String[] args) throws Exception{
//1.创建消费者 参数为消费者组名
DefaultMQProducer producer = new DefaultMQProducer("producers");
producer.setNamesrvAddr("192.168.17.101:9876");
producer.start();
//2.编写消息
String msg = "这是我的第一条同步消息!!!";
Message message = new Message("topic_test","MY_TAG" ,msg.getBytes("UTF-8"));
//3.发送消息
SendResult send = producer.send(message);
//4.打印回执
System.out.println(send);
//5.关闭
producer.shutdown();
}
}
Message参数详解
Topic null 必填,线下环境不需要申请,线上环境需要申请后才能使用
Body null 必填,二进制形式,序列化由应用决定,Producer 与 Consumer 要协商好
序列化形式。
Tags null选填,类似于 Gmail 为每封邮件设置的标签,方便服务器过滤使用。目前只
支持每个消息设置一个 tag,所以也可以类比为 Notify 的 MessageType 概念
Keys null选填,代表这条消息的业务关键词,服务器会根据 keys 创建哈希索引,设置
后,可以在 Console 系统根据 Topic、Keys 来查询消息,由于是哈希索引,
请尽可能保证 key 唯一,例如订单号,商品 Id 等。
Flag 0 选填,完全由应用来设置,RocketMQ 不做干预
DelayTimeLevel 0 选填,消息延时级别,0 表示不延时,大于 0 会延时特定的时间才会被消费
WaitStoreMsgOK TRUE 选填,表示消息是否在服务器落盘后才返回应答。
(四)创建异步生产者
package com.dbh123.rocketmq.producer;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.common.RemotingHelper;
/**
* @description:
* @author: DBH123
* @date: 2021/8/18 0:22
*/
public class AsyncProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer();
producer.setNamesrvAddr("192.168.17.101:9876");
// 发送失败的重试次数
producer.setRetryTimesWhenSendAsyncFailed(0);
producer.start();
String msgStr = "这是我的第一条异步消息";
Message msg = new Message("topic_test","SYNC",
msgStr.getBytes(RemotingHelper.DEFAULT_CHARSET));
//发送消息
producer.send(msg, new SendCallback() {
@Override
public void onSuccess(SendResult sendResult) {
System.out.println(sendResult);
}
@Override
public void onException(Throwable throwable) {
System.out.println(throwable);
}
});
//这里不能顺序关闭,因为为异步执行,可能没哟执行完就关闭producer
//producer.shutdown();
}
}
(五)创建push消费者
package com.dbh123.rocketmq.consumer;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
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.io.UnsupportedEncodingException;
import java.util.List;
/**
* @description:
* @author: DBH123
* @date: 2021/8/18 19:48
*/
public class ConsumerDemo {
public static void main(String[] args) throws Exception{
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumers");
consumer.setNamesrvAddr("192.168.17.101:9876");
//订阅topic
/*
* topic:订阅的主题名
* subExpression:消息的tab
* */
consumer.subscribe("topic_test","*");
//注册监听器
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
for (MessageExt msg : list){
try {
System.out.println(new String(msg.getBody() , "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
//开始
consumer.start();
}
}
订阅配置的方式
完整匹配
consumer.subscribe(“topic_test”, “SEND_MSG”);
//或匹配
consumer.subscribe(“topic_test”, “SEND_MSG || SEND_MSG1”);
(六)消息过滤
RocketMQ支持根据用户自定义属性进行过滤,对消息添加属性,并在消费端通过过滤表达式类似于SQL的where,如:a> 5 AND b ='abc’来进行筛选。
1.配置rocketmq打开消息过滤功能
#加入到broker的配置文件中
enablePropertyFilter=true
2.编写生产者类
package com.dbh123.rocketmq.filter;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
/**
* @description:
* @author: DBH123
* @date: 2021/8/18 20:10
*/
public class FileterProducer {
public static void main(String[] args) throws Exception {
DefaultMQProducer producer = new DefaultMQProducer("producers");
producer.setNamesrvAddr("192.168.17.101:9876");
producer.start();
String msg = "这是我的第一条过滤消息!!";
Message message = new Message("topic_test" , "FILETER" , msg.getBytes());
//设置属性
message.putUserProperty("key" , "123");
SendResult send = producer.send(message);
System.out.println(send);
producer.shutdown();
}
}
3.编写消费者类
package com.dbh123.rocketmq.filter;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.MessageSelector;
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.io.UnsupportedEncodingException;
import java.util.List;
/**
* @description:
* @author: DBH123
* @date: 2021/8/18 20:15
*/
public class FileterConsumer {
public static void main(String[] args) throws Exception {
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("consumers");
consumer.setNamesrvAddr("192.168.17.101:9876");
consumer.subscribe("topic_test" , MessageSelector.bySql("key = 123"));
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list, ConsumeConcurrentlyContext consumeConcurrentlyContext) {
for(MessageExt msg : list){
try {
System.out.println(new String(msg.getBody(),"UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
consumer.start();
}
}