小内存快速搭建rocketmq测试环境

一、下载

wget http://mirror.bit.edu.cn/apache/rocketmq/4.4.0/rocketmq-all-4.4.0-bin-release.zip

unzip rocketmq-all-4.4.0-bin-release.zip

cd rocketmq-all-4.4.0-bin-release

因为买的测试服务器内存只有2G,所以启动前要先修改服务器内存大小

先设置java环境变量,如果不知道如何设置,翻到本文最后;

二、启动nameserver服务器

修改内存大小,内存大小在文件:runserver.sh

JAVA_OPT="${JAVA_OPT} -server -Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m"

备份文件

cp ./bin/runserver.sh  ./bin/runserver.sh_bak

修改内存

perl -p -i -e "s/-Xms4g -Xmx4g -Xmn2g -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=320m/-Xms512m -Xmx512m -Xmn200m/g"  ./bin/runserver.sh

启动

nohup sh bin/mqnamesrv &

三、启动broker

备份文件

cp ./bin/runbroker.sh  ./bin/runbroker.sh_bak

修改内存

修改broker内存大小:runbroker.sh

JAVA_OPT="${JAVA_OPT} -server -Xms8g -Xmx8g -Xmn4g"

修改为

JAVA_OPT="${JAVA_OPT} -server -Xms512m -Xmx512m -Xmn256m"

启动broker

nohup sh bin/mqbroker -n localhost:9876 &

验证

sh bin/mqadmin clusterList -n localhost:9876

[root@VM_0_6_centos rocketmq-all-4.4.0-bin-release]# sh bin/mqadmin clusterList -n localhost:9876
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=128m; support was removed in 8.0
#Cluster Name     #Broker Name            #BID  #Addr                  #Version                #InTPS(LOAD)       #OutTPS(LOAD) #PCWait(ms) #Hour #SPACE
DefaultCluster    localhost               0     172.27.0.6:10911       V4_4_0                   0.00(0,0ms)         0.00(0,0ms)          0 430982.83 -1.0000

这里注意“#Addr"一栏显示的值“ 172.27.0.6:10911”  后面会说明这里存在的问题。

四、关闭服务器

关闭namesrv服务:sh bin/mqshutdown namesrv

关闭broker服务 :sh bin/mqshutdown broker

另外如果想要快速启动broker与nameserver,bin目录下面有一个play.sh文件,执行后可以直接启动nameserver和broker;

五、rocketmqConsole

GitHub - apache/rocketmq-externals: Mirror of Apache RocketMQ (Incubating)

application.properties文件中配置好nameServer就可以了

六、异常处理

1. 外网访问mq,client端收到内网地址

Exception in thread "main" INFO 2019-03-02 22:20:13.156 [NettyClientSelector_1] [RocketmqRemoting] [] [] [] [closeChannel: close the connection to remote address[] result: true]
org.apache.rocketmq.client.exception.MQClientException: Send [3] times, still failed, cost [7303]ms, Topic: TopicTest, BrokersSent: [localhost, localhost, localhost]
See http://rocketmq.apache.org/docs/faq/ for further details.
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:586)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1223)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1173)
	at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:214)
	at com.fintell.flowplatform.common.mq.Producter.main(Producter.java:33)
Caused by: org.apache.rocketmq.remoting.exception.RemotingConnectException: connect to <172.27.0.6:10909> failed
	at org.apache.rocketmq.remoting.netty.NettyRemotingClient.invokeSync(NettyRemotingClient.java:393)
	at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessageSync(MQClientAPIImpl.java:356)
	at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:340)
	at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:294)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:761)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:505)

异常原因:

当我们使用rocketmq客户端的时候,会发现,只需要配置好nameService的地址就可以了,不需要指定broker地址,这是因为broker启动后会注册到nameServer上 ,client端会从nameService上获取broker的地址列表和topic路由信息,异常中打印的broker地址172.27.0.6:10909就是nameServer返回的broker的内网地址,内网地址,在外网肯定访问不了的,如查看控制台,会发现控制台Address一栏显示的就是内网ip:

要将这地址修改为外网地址,需要修改broker的配置文件conf/broker.conf

#InetAddress用于网络接口,外网ip,一定是能夠访问到rocketmq的ip
brokerIP1 = 外网ip地址
#监听端口 ,也是外网映射端口(这里需要注意的是,外网端口和内网的8911端口需要一致,否则会出现 timeout问题)
listenPort=8911

启动命令行中使用-c指定配置文件:

sh bin/mqbroker -n localhost:9876 -c /root/rocketmq-all-4.4.0-bin-release/conf/broker.conf > broker.log &

验证一下地址:

[root@VM_0_6_centos rocketmq-all-4.4.0-bin-release]# sh bin/mqadmin clusterList -n localhost:9876
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=128m; support was removed in 8.0
#Cluster Name     #Broker Name            #BID  #Addr                  #Version                #InTPS(LOAD)       #OutTPS(LOAD) #PCWait(ms) #Hour #SPACE
DefaultCluster    broker-a                0     118.24.47.211:8911     V4_4_0                   0.00(0,0ms)         0.00(0,0ms)          0 430983.06 -1.0000

发现已经更改成了外网ip。

异常:


connect to <ip:10909> failed


org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout

产生的原因:

rocketmq需要打开10909,10912两个端口

rocketmq默认开启了vip通道,需要使用10909vip通道端口;而我们运维只开放了10912,没有开放10909;

解决方案:在客户端代码层面加入

producer.setVipChannelEnabled(false);
consumer.setVipChannelEnabled(false);
 

添加swap

因为2G内存服务器实际内存1.8G,还跑了一个mysql占用了800多M,启动过程中发现改小了内存仍然启动不起来,用free 命令看了下内存使用情况

发现swap没有打开

添加swap:

增加swap交换文件
1.使用dd命令创建一个swap交换文件
dd if=/dev/zero of=/home/swap bs=1024 count=1024000 
这样就建立一个/home/swap的分区文件,大小为1G。

2.制作为swap格式文件:
mkswap /home/swap

3.再用swapon命令把这个文件分区挂载swap分区
swapon /home/swap 
我们用free -m命令看一下,发现已经有交换分区了。 
但是重启系统后,swap分区又变成0了。

4.为防止重启后swap分区变成0,要修改/etc/fstab文件
vi /etc/fstab 
在文件末尾(最后一行)加上 
/home/swap swap swap default 0 0 
 

清理缓存:

清理pagecache(页面缓存)

 echo 2 > /proc/sys/vm/drop_caches

清理dentries(目录缓存)和inodes

 echo 2 > /proc/sys/vm/drop_caches

pagecache、dentries和inodes

 echo 3 > /proc/sys/vm/drop_caches

rocketmq的端口

nameserver端口是9876,写死在代码里面不可以通过配置文件更改
Broker占用3个端口:
listenPort=10911 -- Broker 对外服务的监听端口
haListenPort = 10912 -- Master 和Slave同步的数据的端口,默认为listenPort+1
fastListenPort=10909 --  fastRemotingServer服务使用,默认为:listenPort - 2

rocketmq  分三部分,nameserve、broker、client :

1. nameserver可以认为就是rocketmq的服务注册发现中心,nameserver通过9876端口对外提供服务;各个nameserver之间没有任何交互,其中挂掉任意一个,不影响其他nameserver对外服务。

2. broker作用就是收发消息,有两种角色,master与slaver,关系为1对n,slaver通过10912端口同步master上面的数据,master挂掉后,可以继续从其对应的slaver上读取消息,但是不能发送消息到这些slaver上;要向保证高可用,需要将一个topic的不同queue分布到多个master上去,一个master挂掉后,其它master仍然可以提供读写服务,挂掉master的slaver仍然能够提供读服务。

java环境变量

/etc/profile

·在profile文件末尾加入: 
export JAVA_HOME=/export/packages/jdk1.8 
export PATH=$JAVA_HOME/bin:$PATH 
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 

异常一:

org.apache.rocketmq.client.exception.MQBrokerException: CODE: 14 DESC: service not available now, maybe disk full, CL: 0.90 CQ: 0.90 INDEX: 0.90, maybe your broker machine memory too small.


此时无法写入消息,rocketmq有一个三个参数

1:物理使用率大于diskSpaceWarningLevelRatio(默认90%可通过参数设置),则会阻止新消息的插入
2:物理使用率大于diskSpaceCleanForciblyRatio(默认85%,可设置),则过进行过期物理文件的删除
3:物理磁盘使用率小于diskMaxUsedSpaceRatio 表示磁盘使用正常

异常二:

org.apache.rocketmq.client.exception.MQBrokerException: CODE: 2  DESC: [TIMEOUT_CLEAN_QUEUE]broker busy, start flow control for a while, period in queue: 200ms, size of queue: 16
For more information, please visit the url, http://rocketmq.apache.org/docs/faq/
        at org.apache.rocketmq.client.impl.MQClientAPIImpl.processSendResponse(MQClientAPIImpl.java:556)
        at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessageSync(MQClientAPIImpl.java:358)
        at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:340)
        at org.apache.rocketmq.client.impl.MQClientAPIImpl.sendMessage(MQClientAPIImpl.java:294)
        at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendKernelImpl(DefaultMQProducerImpl.java:807)
        at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:551)
        at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1279)
        at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:301)
        at com.fintell.dp3.common.mq.MQProducerService.sendMessage(MQProducerService.java:71)
        at com.fintell.dp3.api.context.Context$Task.run(Context.java:74)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:748)

一个等待队列的头元素(也就是第一个要处理或者正在处理的元素)等待时间超过该队列设置的最大等待时间,则丢弃该元素对象的任务,并对这个请求返回[TIMEOUT_CLEAN_QUEUE]broker busy异常信息; period in queue: 200ms, 代表在队列中等待了200毫秒了

修改参数:

#默认值为200

waitTimeMillsInSendQueue=600

异常三:

org.apache.rocketmq.client.exception.MQClientException: The producer service state not OK, CREATE_JUST

上面异常出现原因,是因为rocketmq生产者在发送消息的时候才开始初始化生产者实例,导致生产者还没有初始化完成就开始发公司你消息,就报这个异常,高并发下,系统启动后,马上处理任务就会导致大量失败,解决方案,在系统启动时就初始化rocketmq生产者实例;

异常四:

除了上面的异常三,高并下,异常三后面还报了大量的以下异常:

org.apache.rocketmq.client.exception.MQClientException: The producer service state not OK, START_FAILED

原因如下:

public void start(final boolean startFactory) throws MQClientException {
    switch (this.serviceState) {
        // serviceState 状态为 CREATE_JUST ,启动 Producer
        case CREATE_JUST:
            // 防止启动多个 Producer,serviceState 状态修改为 START_FAILED。
            this.serviceState = ServiceState.START_FAILED;
        .....

异常四

org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: DEFAULT ASYNC send call timeout

这个是客户端生产者以异步方式发送rocketmq消息超时的异常,分析见异常五;

异常五:

org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendDefaultImpl call timeout
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.sendDefaultImpl(DefaultMQProducerImpl.java:635)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1280)
	at org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl.send(DefaultMQProducerImpl.java:1226)
	at org.apache.rocketmq.client.producer.DefaultMQProducer.send(DefaultMQProducer.java:283)
	at com.rocketmq.test.producer.ProducerDemoTest.producerTest1(ProducerDemoTest.java:60)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

这个是rocketmq客户端生产者向broker同步发送消息时,等待时间超过超时时间导致,高并发下会导致此问题,可以调用生产者带timeout参数的send方法,指定超时时间,默认为3000毫秒,我们设置为8000后,不再出现。

           // rocketmq拉取到本地消息的最大条数
            // consumer.setPullThresholdForTopic(200);
            // rocketmq拉取到本地消息的最大容量
            // consumer.setPullThresholdSizeForTopic(200);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值