不是吧,生产环境下RocketMq还在用默认参数?

生产环境下的架构

大家对RocketMq一定不陌生吗?作为阿里开源的久经考验的消息中间件,最近几年也是越来越火热,相信很多公司在消息中间件的选型上都会选择它吧。

RocketMQ的消息时延小,吞吐量很高,单机可以达到10万QPS以上,而且可以保证高可用性,性能很高,而且支持通过配置保证数据绝对不丢失,可以部署大规模的集群,还支持各种高级的功能,比如说延迟消息、事务消息、消息回溯、死信队列、消息积压,等等。

而且RocketMQ是基于Java开发的,符合国内大多数公司的技术栈,很容易就可以阅读他的源码,甚至是修改他的源码。

那么现在我们要在生产环境下部署一个RocketMq集群了?
好,那么我先部署个三台NameServer作为注册中心吧,这样我们要拉取和发送消息时就可以在这上面找到对应Broker的路由信息了吧,同时三台NameServer保证了高可用吧,然后Broker肯定也得做主从吧,并且还要能主从切换,那么基于RocketMQ 4.5新版本引入的Dledger技术部署个六台Broker吧(实际生产环境应该更多),其中三台分为一组(一台Master,两台Slave)。整体架构看起来可能是下面这样:
在这里插入图片描述
当然Slave也是要向所有NameServer注册的,这里没有画出来,并且其中的注册和同步都是基于TCP长连接的。

好了,万事大吉,直接启动。
大家想一想,这么做合适吗?

默认参数带来的问题

大家首先要搞明白一点,RocketMQ是Java开发的,那么在机器上部署核启动一个RocketMQ相当于就是启动一个JVM进程,由这个JVM进程来运行中间件系统内的所有代码,然后实现中间件系统的各种功能。


生产环境下,我们总不可能用4核8G的机器来部署RocketMq吧,可能我们会用8核16G的机器来部署NameServer,因为NameServer是核心的路由服务,一般就是承载Broker注册和心跳、系统的路由表拉取等请求,负载其实很低,因此不需要特别高的机器配置,部署三台也可以实现高可用的效果了,然后Broker是负载最高的,未来要承载高并发写入和海量数据存储,所以我们给他配置个24核48G的机器吧。

那么现在机器配置也上去了,我们是不是理所当然地认为部署就完成了,机器配置那么高,肯定可以很好地发挥它的性能吧。

但是哥们,你的各种参数都是默认的啊。。。
比如你的RocketMq,本质上就是一个JVM进程,明明你部署了一个48GB内存的高配置物理机,结果你就给JVM分配了1GB的内存,你的RocketMq就用了里面的几十分之一的内存,根本没用上那么多的资源!你觉得这是不是在开玩笑?
又比如你的机器是24核CPU,结果你的RocketMq默认就开启了4个工作线程去处理请求,相当于24核CPU里很多都是空闲状态,是没有任何事情可以干的。这不是纯浪费资源嘛!
还有一些OS参数,如果不调整的话,根本没法合理地利用资源。

所有对于像RocketMq这种中间件系统而言,往往必须要对os内核参数、jvm参数以及自身核心参数都做出相对应的合理的调整,再进行压测和上线。

调整OS参数

  1. vm.overcommit_memory

可选值:0、1、2。
0:中间件系统申请内存的时候,os内核会检查可用内存是否足够,如果足够的话就分配内存给你,如果剩余内存不是太够了,就会拒绝你的申请,导致你申请内存失败,进而导致中间件系统异常出错。
1:意思是把所有可用的物理内存都允许分配给你,只要有内存就给你来用,这样可以避免申请内存失败的问题。
2:表示内核允许分配超过所有物理内存和交换空间总和的内存

因此一般需要将这个参数的值调整为1,可以用如下命令修改:
echo ‘vm.overcommit_memory=1’ >> /etc/sysctl.conf。

  1. vm.max_map_count

这个参数的值会影响中间件系统可以开启的线程的数量
如果这个参数过小,有的时候可能会导致有些中间件无法开启足够的线程,进而导致报错,甚至中间件系统挂掉。
他的默认值是65536,但是这个值有时候是不够的,因此建议可以把这个参数调大10倍,比如655360这样的值,保证中间件可以开启足够多的线程。

可以用如下命令修改:
echo ‘vm.max_map_count=655360’ >> /etc/sysctl.conf。

  1. vm.swappiness

这个参数是用来控制进程的swap行为的,这个简单来说就是os会把一部分磁盘空间作为swap区域,然后如果有的进程现在可能不是太活跃,就会被操作系统把进程调整为睡眠状态,把进程中的数据放入磁盘上的swap区域,然后让这个进程把原来占用的内存空间腾出来,交给其他活跃运行的进程来使用。
如果这个参数的值设置为0,意思就是尽量别把任何一个进程放到磁盘swap区域去,尽量大家都用物理内存。
如果这个参数的值是100,那么意思就是尽量把一些进程给放到磁盘swap区域去,内存腾出来给活跃的进程使用。
默认这个参数的值是60,有点偏高了,可能会导致我们的中间件运行不活跃的时候被迫腾出内存空间然后放磁盘swap区域去。
因此通常在生产环境建议把这个参数调整小一些,比如设置为10,尽量用物理内存,别放磁盘swap区域去。

可以用如下命令修改:
echo ‘vm.swappiness=10’ >> /etc/sysctl.conf。

  1. ulimit

这个是用来控制linux上的最大文件链接数的,默认值可能是1024,一般肯定是不够的,因为你在大量频繁的读写磁盘文件的时候,或
者是进行网络通信的时候,都会跟这个参数有关系。
对于一个中间件系统而言肯定是不能使用默认值的,如果你采用默认值,很可能在线上会出现如下错误:error: too many open
files。

因此通常建议用如下命令修改这个值:
echo ‘ulimit -n 1000000’ >> /etc/profile。

JVM参数调整

首先得先找到RocketMQ启动脚本中是如何设置JVM参数的,然后再有针对性的做出适当的调整和修改。

在rocketmq/distribution/target/apache-rocketmq/bin目录下,就有对应的启动脚本,比如mqbroker是用来启动Broker的,mqnamesvr是用来启动NameServer的。
这里仅仅列出一些常用参数

  1. -Xms8g -Xmx8g -Xmn4g:这个参数是重点需要调整的,它默认是堆内存分配8g,新生代4g,但是由于我们的高配物理机是48g内存的所以完全可以给堆内存个20g,其中新生代给10g,甚至可以更多一些,当然要留一些内存给操作系统来用。
  2. -XX:+UseG1GC -XX:G1HeapRegionSize=16m:这个参数是与垃圾回收有关的,比如这里是选用了G1垃圾回收器来做分代回收,对新生代和老年代都是用G1来回收这里把G1的region大小设置为了16m,这个因为机器内存比较多,所以region大小可以调大一些给到16m,不然用2m的region,会导致region数量过多的。
  3. -XX:G1ReservePercent=25:这个参数是说,在G1管理的老年代里预留25%的空闲内存,保证新生代对象晋升到老年代的时候有足够空间,避免老年代内存都满了,新生代有对象要进入老年代没有充足内存了。
  4. XX:InitiatingHeapOccupancyPercent=30:这个参数是说,当堆内存的使用率达到30%之后就会自动启动G1的并发垃圾回收,开始尝试回收一些垃圾对,它的默认值是45%,这里调低了一些,也就是提高了GC的频率,但是避免了垃圾对象过多,一次垃圾回收耗时过长的问题

关于对RocketMQ核心参数进行调整
dledger的配置文件中有一个较为核心的参数:sendMessageThreadPoolNums=16
这个参数的意思就是RocketMQ内部用来发送消息的线程池的线程数量,默认是16,其实这个参数可以根据你的机器的CPU核数进行适当增加,比如机器CPU是24核的,可以增加这个线程数量到24或者30,都是可以的。


当然,这里的具体调整值仅作参考,具体多少合适还是要根据实际情况来调整的,当然,默认值大多数情况下是不太合适的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值