目录
1.是什么
rocketmq是一个分布式的消息中间件,可以用在异步通信,数据管道等场景中.
官网地址:https://rocketmq.apache.org/docs/quick-start/
2.背景
随着使用中的队列和主题的增加,ActiveMQ IO模块达到了瓶颈,通过节流,断路器等方法解决这个问题,但效果不好,关注了当时流行的消息传递解决方案kafka,不幸的是,kafka不能满足我们的需求,特别是在低延迟和高可靠性方面,所以觉得发明一个新的消息引擎来处理更广泛的用例集,从传统的发布、订阅场景到高容量的实时零损失容忍事务系统。
3.常用消息队列对比
Messaging Product | Client SDK | Protocol and Specification | Ordered Message | Scheduled Message | Batched Message | BroadCast Message | Message Filter | Server Triggered Redelivery | Message Storage | Message Retroactive | Message Priority | High Availability and Failover | Message Track | Configuration | Management and Operation Tools |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
ActiveMQ | Java, .NET, C++ etc. | Push model, support OpenWire, STOMP, AMQP, MQTT, JMS | Exclusive Consumer or Exclusive Queues can ensure ordering | Supported | Not Supported | Supported | Supported | Not Supported | Supports very fast persistence using JDBC along with a high performance journal,such as levelDB, kahaDB | Supported | Supported | Supported, depending on storage,if using levelDB it requires a ZooKeeper server | Not Supported | The default configuration is low level, user need to optimize the configuration parameters | Supported |
Kafka | Java, Scala etc. | Pull model, support TCP | Ensure ordering of messages within a partition | Not Supported | Supported, with async producer | Not Supported | Supported, you can use Kafka Streams to filter messages | Not Supported | High performance file storage | Supported offset indicate | Not Supported | Supported, requires a ZooKeeper server | Not Supported | Kafka uses key-value pairs format for configuration. These values can be supplied either from a file or programmatically. | Supported, use terminal command to expose core metrics |
RocketMQ | Java, C++, Go | Pull model, support TCP, JMS, OpenMessaging | Ensure strict ordering of messages,and can scale out gracefully | Supported | Supported, with sync mode to avoid message loss | Supported | Supported, property filter expressions based on SQL92 | Supported | High performance and low latency file storage | Supported timestamp and offset two indicates | Not Supported | Supported, Master-Slave model, without another kit | Supported | Work out of box,user only need to pay attention to a few configurations | Supported, rich web and terminal command to expose core metrics |
4.单节点快速安装
环境要求:>=jdk1.8即可
这里下载4.7.1的版本
1.上传
rz
2.解压
unzip rocketmq-all-4.7.1-bin-release.zip
3.创建启动脚本
cd /data1/rocketmq-all-4.7.1-bin-release
vim start.sh
nohup sh bin/mqnamesrv &
nohup sh bin/mqbroker -n 本机ip地址:9876 -c conf/broker.conf &
#创建完成之后修改文件权限
chmod 744 start.sh
4.启动
sh start.sh
5.查看是否启动成功
jps |grep Start
6.验证
#先添加环境变量
vim /etc/profile
export NAMESRV_ADDR=本机ip地址:9876
#环境变量生效
source /etc/profile
#生产消息
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
#消费消息
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Consumer
7.创建停止脚本
vim stop.sh
nohup sh bin/mqshutdown broker &
nohup sh bin/mqshutdown namesrv &
#修改文件权限
chmod 744 stop.sh
8.查看日志
tail -f ~/logs/rocketmqlogs/namesrv.log
tail -f ~/logs/rocketmqlogs/broker.log
9.如果需要修改内存
#修改bin/runserver.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
#修改bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"
5.多master模式
1.优缺点
一个集群无Slave,全是Master,例如2个Master或者3个Master
1.优点
配置简单,单个Master宕机或重启维护对应用无影响,在磁盘配置为RAID10时,即使机器宕机不可恢复情况下,由于RAID10磁盘非常可靠,消息也不会丢(异步刷盘丢失少量消息,同步刷盘一条不丢),性能最高;
2.缺点
单台机器宕机期间,这台机器上未被消费的消息在机器恢复之前不可订阅,消息实时性会受到影响。
2.安装
下面以A,B2台机器为例,namesrv和broker在同一台机器上
1.上传安装包
AB2台机器分别上传安装包
rz
2.解压
unzip rocketmq-all-4.7.1-bin-release.zip
3.创建namesrv启动脚本
cd /data1/rocketmq-all-4.7.1-bin-release
vim startnamesrv.sh
nohup sh bin/mqnamesrv &
#创建完成之后修改文件权限
chmod 744 startnamesrv.sh
4.启动namesrv
sh startnamesrv.sh
5.修改broker配置
A修改conf/2m-noslave/broker-a.properties
B修改conf/2m-noslave/broker-b.properties
添加的下面内容
#添加nameserver
namesrvAddr=A机器ip地址:9876;B机器ip地址:9876
#添加自动创建topic=false
autoCreateTopicEnable=false
6.创建brokersrv启动脚本
如果是B机器,改为conf/2m-noslave/broker-b.properties
cd /data1/rocketmq-all-4.7.1-bin-release
vim startbrokersrv.sh
nohup sh bin/mqbroker -c conf/2m-noslave/broker-a.properties &
#创建完成之后修改文件权限
chmod 744 startbrokersrv.sh
7.启动brokersrv
sh startbrokersrv.sh
8.查看是否启动成功
jps |grep Start
9.查看日志
tail -f ~/logs/rocketmqlogs/namesrv.log
tail -f ~/logs/rocketmqlogs/broker.log
10.如果需要修改内存
#修改bin/runserver.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
#修改bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"
6.多Master多Slave模式-异步复制
1.优缺点
每个Master配置一个Slave,有多对Master-Slave,HA采用异步复制方式,主备有短暂消息延迟(毫秒级)
1.优点
即使磁盘损坏,消息丢失的非常少,且消息实时性不会受影响,同时Master宕机后,消费者仍然可以从Slave消费,而且此过程对应用透明,不需要人工干预,性能同多Master模式几乎一样;
2.缺点
Master宕机,磁盘损坏情况下会丢失少量消息。
2.安装
下面以6台机器为例,2n2m2s
A,B namesrv
C,D broker master
E,F broker slave 其中E是C的slave F是D的slave
1.上传安装包
6台机器分别上传安装包
rz
2.解压
unzip rocketmq-all-4.7.1-bin-release.zip
3.创建namesrv启动脚本
cd /data1/rocketmq-all-4.7.1-bin-release
vim startnamesrv.sh
nohup sh bin/mqnamesrv &
#创建完成之后修改文件权限
chmod 744 startnamesrv.sh
4.启动namesrv
sh startnamesrv.sh
5.修改broker配置
C修改conf/2m-2s-async/broker-a.properties
D修改conf/2m-2s-async/broker-b.properties
E修改conf/2m-2s-async/broker-a-s.properties
F修改conf/2m-2s-async/broker-b-s.properties
添加的下面内容
#添加nameserver
namesrvAddr=A机器ip地址:9876;B机器ip地址:9876
#添加自动创建topic=false
autoCreateTopicEnable=false
6.创建brokersrv启动脚本
D机器,改为conf/2m-2s-async/broker-b.properties
E机器,改为conf/2m-2s-async/broker-a-s.properties
F机器,改为conf/2m-2s-async/broker-b-s.properties
cd /data1/rocketmq-all-4.7.1-bin-release
vim startbrokersrv.sh
nohup sh bin/mqbroker -c conf/2m-2s-async/broker-a.properties &
#创建完成之后修改文件权限
chmod 744 startbrokersrv.sh
7.启动brokersrv
sh startbrokersrv.sh
8.查看是否启动成功
jps |grep Start
9.查看日志
tail -f ~/logs/rocketmqlogs/namesrv.log
tail -f ~/logs/rocketmqlogs/broker.log
10.如果需要修改内存
#修改bin/runserver.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"
#修改bin/runbroker.sh
JAVA_OPT="${JAVA_OPT} -server -Xms256m -Xmx256m -Xmn128m"
7.多Master多Slave模式-同步双写
1.优缺点
每个Master配置一个Slave,有多对Master-Slave,HA采用同步双写方式,即只有主备都写成功,才向应用返回成功,这种模式的优缺点如下:
1.优点
数据与服务都无单点故障,Master宕机情况下,消息无延迟,服务可用性与数据可用性都非常高;
2.缺点
性能比异步复制模式略低(大约低10%左右),发送单个消息的RT会略高,且目前版本在主节点宕机后,备机不能自动切换为主机。
2.安装
参照多Master多Slave模式-异步复制
只需要启动broker的时候使用conf/2m-2s-sync下面的配置文件即可
8.mqadmin管理工具
1.使用文档
地址:rocketmq/operation.md at master · apache/rocketmq · GitHub
2.常用命令
注意:
执行命令方法:./mqadmin {command} {args} 几乎所有命令都需要配置-n表示NameServer地址,格式为ip:port 几乎所有命令都可以通过-h获取帮助 如果既有Broker地址(-b)配置项又有clusterName(-c)配置项,则优先以Broker地址执行命令,如果不配置Broker地址,则对集群中所有主机执行命令,只支持一个Broker地址。-b格式为ip:port,port默认是10911
1.创建更新topic配置
./mqadmin updateTopic -n ip:9876 -c DefaultCluster -t TopicTest
2.查看topic列表信息
./mqadmin topicList -n ip:9876 -c
3.删除topic
./mqadmin deleteTopic -n ip:9876 -c DefaultCluster -t TopicTest
4.查看topic路由信息
./mqadmin topicRoute -n ip:9876 -t TopicTest
5.查看topic消息队列offset
./mqadmin topicStatus -n ip:9876 -t TopicTest
6.计算负载
以平均负载算法计算消费者列表负载消息队列的负载结果
./mqadmin allocateMQ -n ip:9876 -i ip1,ip2 -t TopicTest
7.查看topic的tps
打印Topic订阅关系、TPS、积累量、24h读写总量等信息
./mqadmin statsAll -n ip:9876 -t TopicTest
8.查看集群信息
./mqadmin clusterList -n ip:9876 -m
9.查看broker信息
./mqadmin brokerStatus -n ip:9876 -b ip:10911
10.根据id查询msg
./mqadmin queryMsgById -n ip:9876 -i msgId
11.发送消息
./mqadmin sendMessage -n ip:9876 -t TopicTest -p 'this is a body content' -c mqtest
12.消费消息
./mqadmin consumeMessage -n ip:9876 -t TopicTest
9.安装dashboard
提供了出色的监控功能。客户端和应用程序的各种事件、性能和系统信息的图表和统计明显地提供给用户
1.git地址
原来叫做rocketmq-console地址在https://github.com/apache/rocketmq-externals下的rocketmq-console
2.安装
1.下载源码
2.上传到服务器
rz -be
3.解压
unzip fileName
4.修改配置文件
进入rocketmq-dashboard-master/src/main/resources
vim application.properties
server.port=你要的端口号
namesrvAddr:你的namesrv地址
5.编译打包
mvn clean package -Dmaven.test.skip=true
#编译完成之后会在target目录生成jar包
6.创建启动脚本
vim start.sh
nohup java -jar rocketmq-dashboard-1.0.1-SNAPSHOT.jar >> rocketmq-dashboard.log &
#保存之后修改文件权限
chmod 744 start.sh
7.验证访问页面
10.java客户端使用
使用例子可以在官网找
Simple Message Example - Apache RocketMQ
1.添加依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.9.3</version>
</dependency>
2.生产消息
生产消息有3种模式
- Send Messages Synchronously
Reliable synchronous transmission is used in extensive scenes, such as important notification messages, SMS notification, SMS marketing system, etc..
- Send Messages Asynchronously
Asynchronous transmission is generally used in response time sensitive business scenarios.
- Send Messages in One-way Mode
One-way transmission is used for cases requiring moderate reliability, such as log collection.
这里以Send Messages Synchronously为例
private static DefaultMQProducer producer = null;
public SendResult producer(String topic, String tag, String messgae) {
// TODO Auto-generated method stub
SendResult sendResult = new SendResult();
try {
if (null == producer) {
producer = new DefaultMQProducer("producer");
// 设置NameServer的地址
producer.setNamesrvAddr(namesrvAddr);
// 启动Producer实例
producer.start();
}
// 创建消息,并指定Topic,Tag和消息体
Message msg = new Message(topic, tag, messgae.getBytes(RemotingHelper.DEFAULT_CHARSET));
// 发送消息到一个Broker
sendResult = producer.send(msg);
LOGGER.info(sendResult);
} catch (Exception e) {
// TODO: handle exception
LOGGER.error("producer", e);
}
return sendResult;
}
3.消费消息
private void pushConsumer(String topic, String tag) {
// 实例化消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(tag);
/**
* 设置Consumer第一次启动是从队列头部开始消费还是队列尾部开始消费<br>
* 如果非第一次启动,那么按照上次消费的位置继续消费
*/
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
// 设置NameServer的地址
consumer.setNamesrvAddr(namesrvAddr);
// 订阅一个或者多个Topic,以及Tag来过滤需要消费的消息
try {
consumer.subscribe(topic, tag);
// 注册回调实现类来处理从broker拉取回来的消息
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
try {
for (MessageExt msg : msgs) {
String body = new String(msg.getBody());
LOGGER.info("这里可以加上你要拿消费到的body干什么用");
}
// 标记该消息已经被成功消费
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
} catch (Exception e) {
// TODO: handle exception
LOGGER.error("", e);
// 标记该消息已经被成功消费
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
}
});
// 启动消费者实例
consumer.start();
} catch (MQClientException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}