网站运营和维护都是干什么的,企业网站优化三层含义,手机模板网站模板,网站设计的字体之前写的解决方案,都是基于测试环境测试的.到生产环境之后,正常使用没有问题,生产环境压测时,又出现了system busy异常(简直崩溃).最后在rocketmq群里大佬指导下,终于解决(希望是彻底解决).
下面直接给出结果:
目前通过生产环境各种参数修改测试得出:
broker busy异常: 可通…之前写的解决方案,都是基于测试环境测试的.到生产环境之后,正常使用没有问题,生产环境压测时,又出现了system busy异常(简直崩溃).最后在rocketmq群里大佬指导下,终于解决(希望是彻底解决).
下面直接给出结果:
目前通过生产环境各种参数修改测试得出:
broker busy异常: 可通过增大 waitTimeMillsInSendQueue 解决
system busy异常:可通过增大 osPageCacheBusyTimeOutMills 解决
#发送队列等待时间
waitTimeMillsInSendQueue3000
#系统页面缓存繁忙超时时间(翻译),默认值 1000
osPageCacheBusyTimeOutMills5000
个人猜测,出现异常的原因是因为我们同一台服务器部署的多个应用造成的.我们一台服务器上部署了 三个ES、八个redis、一个rocketmq 压力测试时这些都在使用虽然cpu、内存都还有很大剩余但是磁盘io和内存频率毕竟只有那么多可能已经占满或者还有其他都会有影响。 之前测试环境测试其他东西时发现mq和redis同时大量使用时redis速度会降低三到四倍由此可见应用分服务器部署的重要性。以前知道会有影响没想到影响这么大。 最终结解决方案:应该给rocketmq单独部署性能较高的服务器.
下面给下我们完整的配置:
#broker名字注意此处不同的配置文件填写的不一样
brokerClusterNamerocketmqcluster
brokerNamebroker-a
#0 表示 Master 0 表示 Slave
brokerId0
#nameServer地址分号分割
namesrvAddrrocketmq-nameserver1:9876;rocketmq-nameserver2:9876
#这个配置可解决双网卡,发送消息走外网的问题,这里配上内网ip就可以了
brokerIP110.30.51.149#在发送消息时自动创建服务器不存在的topic默认创建的队列数
defaultTopicQueueNums8
#是否允许 Broker 自动创建Topic建议线下开启线上关闭
autoCreateTopicEnablefalse
#是否允许 Broker 自动创建订阅组建议线下开启线上关闭
autoCreateSubscriptionGrouptrue
#Broker 对外服务的监听端口
listenPort10911
#删除文件时间点默认凌晨 0点
deleteWhen03
#文件保留时间默认 48 小时
fileReservedTime48
#commitLog每个文件的大小默认1G
mapedFileSizeCommitLog1073741824
#ConsumeQueue每个文件默认存30W条根据业务情况调整
mapedFileSizeConsumeQueue1000000
destroyMapedFileIntervalForcibly120000
redeleteHangedFileInterval120000
#检测物理文件磁盘空间
diskMaxUsedSpaceRatio88
#存储路径
storePathRootDir/app/data/rocketmq/data
#commitLog 存储路径
storePathCommitLog/app/data/rocketmq/data/commitlog
#消费队列存储路径存储路径
storePathConsumeQueue/app/data/rocketmq/data/consumerqueue
#消息索引存储路径
storePathIndex/app/data/rocketmq/data/index
#checkpoint 文件存储路径
storeCheckpoint/app/data/rocketmq/data/checkpoint
#abort 文件存储路径
abortFile/app/data/rocketmq/data/abort
#限制的消息大小 修改为16M
maxMessageSize16777216
#发送队列等待时间
waitTimeMillsInSendQueue3000
osPageCacheBusyTimeOutMills5000
flushCommitLogLeastPages12
flushConsumeQueueLeastPages6
flushCommitLogThoroughInterval30000
flushConsumeQueueThoroughInterval180000
#Broker 的角色
#- ASYNC_MASTER 异步复制Master
#- SYNC_MASTER 同步双写Master
#- SLAVE
brokerRoleASYNC_MASTER
#刷盘方式
#- ASYNC_FLUSH 异步刷盘
#- SYNC_FLUSH 同步刷盘
flushDiskTypeASYNC_FLUSH
#checkTransactionMessageEnablefalse
#发消息线程池数量
sendMessageThreadPoolNums80
#拉消息线程池数量
pullMessageThreadPoolNums128
useReentrantLockWhenPutMessagetrue
记一次 rocketmq 使用时的异常。 这里就不说什么rocketmq 源码啥的了因为没看过。网上一搜这两个异常 大部分都是什么源码解读也没说出现后的解决办法。
大量测试发现
1、system busy , start flow control for a while 该异常会造成 消息丢失。
2、broker busy , start flow control for a while 该异常不会造成消息丢失。这是最坑的都异常了消息竟然是正常发送了的。
解决过程
1、最开始时候 测试发现在性能好的服务器上 只会出现system busy也就是说出现异常就会消息丢失。 所以业务代码进行处理出现异常就会重发到当前topic的 bak队列当时想的是既然这个topic busy了就换到另外的topic去发总不能都 busy吧。
也算是临时解决了。
2、运行一年后可能是服务器上运行的东西多了或者其他原因。发现有消息重复的现象。不用想肯定是报broker busy异常重发到topic的 bak队列了。又因为broker busy可能不会造成消息丢失所以消息重复就出现了。
3、无奈找新的解决方法。本来想的是判断异常如果是broker busy就不重发了。
报着试一试的态度又去百度了一下还是搜出来一堆源码解读。搭上梯子google一下还真找到了。
https://stackoverflow.com/questions/47749906/rocketmq-throw-exception-timeout-clean-queuebroker-busy-start-flow-control-f
https://www.cnblogs.com/cs99lzzs/p/9181555.html
想到不知道在哪看的的一句话在stackoverflow上能找到和你一样的问题那问题已经解决了百分之90了。这他喵的真实至理名言啊。
吐槽完
又经过大量测试验证
解决方案
修改rocketmq配置文件
方案一sendMessageThreadPoolNums 改成 1 没有的话新增一行。 sendMessageThreadPoolNums1
方案二推荐useReentrantLockWhenPutMessage改成true没有的话新增一行。 sendMessageThreadPoolNums32 useReentrantLockWhenPutMessagetrue
说明 sendMessageThreadPoolNums这个属性是发送线程池大小 rocketmq4.1版本之后默认为 1之前版本默认什么不知道但是肯定大于1。这个属性改成1的话就不用管useReentrantLockWhenPutMessage这个属性了 如果改成大于1就需要将useReentrantLockWhenPutMessage这个属性设置为 true 目前测试 未发现这两个方案有什么区别sendMessageThreadPoolNums1 时也支持多线程发送发送速度感觉和 sendMessageThreadPoolNums大于1没有区别都能跑满100M的网卡。 感觉如果useReentrantLockWhenPutMessagetrue的时候就是打开锁属性名翻译一下也大概是这个意思然后关键代码其实还是单线程处理 有闲功夫的话去翻翻源码看看去。 最后 我是选择的方案二毕竟看着好看点。