目录
Linux下安装RocketMQ
准备工作
RocketMQ下载地址:http://rocketmq.apache.org/release_notes/ 选择对应的版本号进行下载,我下载的是4.7.1
带bin的是二进制文件,带source的是源码
中文官方文档:https://github.com/apache/rocketmq/tree/master/docs/cn
官方推荐配置:
- 64bit OS, Linux/Unix/Mac is recommended;(Windows user see guide below)
- 64bit JDK 1.8+;
- Maven 3.2.x;
- Git;
- 4g+ free disk for Broker server
我的linux版本:CentOS 7
安装rocketmq前需要先安装jdk1.8,因为rocketmq是Java语言写的
JDK1.8安装教程:https://blog.csdn.net/Me_xuan/article/details/111306026
安装
第一步、上传文件,解压
将我们下载的zip的包上传至服务器,新建文件夹,将zip包复制到我们新建的文件夹下面,然后进行解压,我的目录是/app/rocketmq
解压完后重命名,也可以不重命名,因为之前的名字太长,建议还是重命名一下比较好
第二步、配置环境变量,启动rocketmq
配置环境变量
vi /etc/profile
# rocketmq
export ROCKETMQ_HOME=/app/rocketmq/rocketmq
export PATH=$PATH:${ROCKETMQ_HOME}/bin
ROCKETMQ_HOME就是我们刚安装的racketmq的地址
配置完环境变量,我们启动一下NameServer
nohup sh mqnamesrv &
如果没有配置环境变量。则得在mq的bin目录下执行 sh mqnamesrv
如果此时启动不起来,看一下rockermq设置的jvm参数,可以把-Xms -Xmx -Xmn 这三个参数根据自己的服务器配置进行相应的调整
启动成功后查看rocketmq的进程
也可以看打印的日志 tail -f ~/logs/rocketmqlogs/namesrv.log
启动borker
先根据自己的服务器配置修改JVM参数
vi runbroker.sh
启动
nohup sh mqbroker -n localhost:9876 &
-n参数后面接要连接到的NameServer的ip和端口 , ip:port;ip:port 多个用分号隔开。
日志打印
至此,我们的rocketmq服务端就已经启动成功了。
第三步、关闭服务
NameServer和broker关闭
# 关闭NameServer
sh mqshutdown namesrv
# 关闭broker
sh mqshutdown broker
测试
第一步、打开相应端口
开放9876、10911端口
查看防火墙状态:[root@localhost ~]# systemctl status firewalld
查看开放端口:[root@localhost ~]# firewall-cmd --list-all
开放端口:
firewall-cmd --zone=public --add-port=9876/tcp --permanent
firewall-cmd --zone=public --add-port=10911/tcp --permanent
刷新防火墙:firewall-cmd --reload
注意,这里有个坑
之前我天真的以为打开这个端口9876就可以了,结果还是不行,然后得再打开10911这个端口
如果不打开10911这个端口,生产者服务会报超时异常,然后一直打印[NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[] result: true
如:
RocketMQLog:WARN No appenders could be found for logger (io.netty.util.internal.InternalThreadLocalMap).
RocketMQLog:WARN Please initialize the logger system properly.
Exception in thread "main" org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:667)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1343)
at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1289)
at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:325)
at com.example.demo.rocketmq.producer.SyncProducer.main(SyncProducer.java:30)
23:18:22.026 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[] result: true
23:18:52.508 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[] result: true
23:19:22.510 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[] result: true
通过日志可以看到,broker使用了10911这个端口
因为代理服务器(Broker Server)在RocketMQ系统中负责接收从生产者发送来的消息并存储、同时为消费者的拉取请求作准备,所以broker的端口也得打开
然后再启动生产者代码,会正常打印相关日志,address中会有我们的两个服务地址,如下
00:01:14.782 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[192.168.75.100:10911] result: true
00:01:14.785 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[192.168.75.100:9876] result: true
第二步、修改broker.conf配置文件
需要配置broker.conf 这个配置文件,不然的话自己的java项目是无法连接至服务端的
[root@localhost bin]# vi ../conf/broker.conf
增加两个配置项:
# 当前服务器ip:port
namesrvAddr=192.168.75.100:9876
# 当前服务器ip
brokerIP1=192.168.75.100
然后重新启动NameServer和broker
nohup sh mqnamesrv -n 192.168.75.100:9876 &
nohup sh mqbroker -n 192.168.75.100:9876 -c ../conf/broker.conf autoCreateTopicEnable=true &
autoCreateTopicEnable=true 的作用是自动创建topic
第三步、编写代码进行测试
代码示例:
官方文档中有简单案例:
https://github.com/apache/rocketmq/blob/master/docs/cn/RocketMQ_Example.md
我这就是直接拷的官方demo
我这个是springboot的项目
1.引入maven相关依赖
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>4.7.1</version>
</dependency>
2.编写生产者代码
package com.example.demo.rocketmq.producer;
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;
/**
* @ClassName SyncProducer
* @Author chenxuan
* @Date 2020/12/15 23:11
* @Version 1.0
*/
public class SyncProducer {
public static void main(String[] args) throws Exception {
// 实例化消息生产者Producer
DefaultMQProducer producer = new DefaultMQProducer("please_rename_unique_group_name");
// 设置NameServer的地址
producer.setNamesrvAddr("192.168.75.100:9876");
// 启动Producer实例
producer.start();
for (int i = 0; i < 10; i++) {
// 创建消息,并指定Topic,Tag和消息体
Message msg = new Message("TopicTest" /* Topic */,
"TagA" /* Tag */,
("Hello RocketMQ " + i).getBytes(RemotingHelper.DEFAULT_CHARSET) /* Message body */
);
// 发送消息到一个Broker
SendResult sendResult = producer.send(msg);
// 通过sendResult返回消息是否成功送达
System.out.printf("%s%n", sendResult);
}
// 如果不再发送消息,关闭Producer实例。
producer.shutdown();
}
}
3.编写消费者代码
package com.example.demo.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.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import java.util.List;
/**
* @ClassName Consumer
* @Author chenxuan
* @Date 2020/12/15 23:11
* @Version 1.0
*/
public class Consumer {
public static void main(String[] args) throws InterruptedException, MQClientException {
// 实例化消费者
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer("please_rename_unique_group_name");
// 设置NameServer的地址
consumer.setNamesrvAddr("192.168.75.100:9876");
// 订阅一个或者多个Topic,以及Tag来过滤需要消费的消息
consumer.subscribe("TopicTest", "*");
// 注册回调实现类来处理从broker拉取回来的消息
consumer.registerMessageListener(new MessageListenerConcurrently() {
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
System.out.printf("%s Receive New Messages: %s %n", Thread.currentThread().getName(), msgs);
msgs.stream().forEach(msg ->
System.out.println("msg:"+new String(msg.getBody()))
);
// 标记该消息已经被成功消费
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
});
// 启动消费者实例
consumer.start();
System.out.printf("Consumer Started.%n");
}
}
4.启动代码,成功运行
生产者日志:
RocketMQLog:WARN Please initialize the logger system properly.
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E3E80000, offsetMsgId=C0A84B6400002A9F000000000000178E, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=1], queueOffset=9]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E3FB0001, offsetMsgId=C0A84B6400002A9F0000000000001857, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=2], queueOffset=7]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E3FF0002, offsetMsgId=C0A84B6400002A9F0000000000001920, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=3], queueOffset=6]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E4010003, offsetMsgId=C0A84B6400002A9F00000000000019E9, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=0], queueOffset=8]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E4050004, offsetMsgId=C0A84B6400002A9F0000000000001AB2, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=1], queueOffset=10]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E4090005, offsetMsgId=C0A84B6400002A9F0000000000001B7B, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=2], queueOffset=8]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E40C0006, offsetMsgId=C0A84B6400002A9F0000000000001C44, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=3], queueOffset=7]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E4100007, offsetMsgId=C0A84B6400002A9F0000000000001D0D, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=0], queueOffset=9]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E4120008, offsetMsgId=C0A84B6400002A9F0000000000001DD6, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=1], queueOffset=11]
SendResult [sendStatus=SEND_OK, msgId=C0A8016931CC00B4AAC25266E4140009, offsetMsgId=C0A84B6400002A9F0000000000001E9F, messageQueue=MessageQueue [topic=TopicTest, brokerName=broker-a, queueId=2], queueOffset=9]
00:01:14.782 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[192.168.75.100:10911] result: true
00:01:14.785 [NettyClientSelector_1] INFO RocketmqRemoting - closeChannel: close the connection to remote address[192.168.75.100:9876] result: true
Process finished with exit code 0
消费者日志(只打印了消息内容,不然日志太多):
Consumer Started.
msg:Hello RocketMQ 0
msg:Hello RocketMQ 1
msg:Hello RocketMQ 2
msg:Hello RocketMQ 3
msg:Hello RocketMQ 4
msg:Hello RocketMQ 5
msg:Hello RocketMQ 6
msg:Hello RocketMQ 7
msg:Hello RocketMQ 8
msg:Hello RocketMQ 9
至此我们的rocketmq安装成功,第一个rocketmq的demo也成功运行,后面就可以开始rocketmq之旅了。