客户端配置
相对于RocketMQ的Broker集群,生产者和消费者都是客户端
DefaultMQProducer、TransactionMQProducer、DefaultMQPushConsumer、
DefaultMQPullConsumer都继承于ClientConfig类,ClientConfig为客户端的公共配置类。
客户端的配置都是get、set形式,每个参数都可以用spring来配置,也可以在代码中配置。
例如namesrvAddr这个参数可以这样配置,producer.setNamesrvAddr(“192.168.0.1:9876”),其他参数同理
客户端寻址方式
RocketMQ可以令客户端找到Name Server, 然后通过Name Server再找到Broker。如下所示有多种配置方式,优先级由高到低,高优先级会覆盖低优先级
代码中指定Name Server地址,多个namesrv地址之间用分号分割
producer.setNamesrvAddr("192.168.0.1:9876;192.168.0.2:9876");
consumer.setNamesrvAddr("192.168.0.1:9876;192.168.0.2:9876");
- Java启动参数中指定Name Server地址
-Drocketmq.namesrv.addr=192.168.0.1:9876;192.168.0.2:9876
HTTP静态服务器寻址(默认)
该静态地址,客户端第一次会10s后调用,然后每个2分钟调用一次。
客户端启动后,会定时访问一个静态HTTP服务器,地址如下:http://jmenv.tbsite.net:8080/rocketmq/nsaddr,这个URL的返回内容如下:
192.168.0.1:9876;192.168.0.2:9876
客户端的公共配置
Producer配置
PushConsumer配置
PullConsumer配置
Message数据结构
系统配置
JVM选项
设置Xms和Xmx一样大,防止JVM重新调整堆空间大小影响性能
-server -Xms8g -Xmx8g -Xmn4g
设置DirectByteBuffer内存大小。当DirectByteBuffer占用达到这个值,就会触发Full GC
-XX:MaxDirectMemorySize=15g
如果不太关心RocketMQ的启动时间,可以设置pre-touch,这样在JVM启动的时候就会分配完整的页空间
-XX:+AlwaysPreTouch
禁用偏向锁可能减少JVM的停顿,因为偏向锁在线程需要获取锁之前会判断当前线程是否拥有锁,如果拥有,就不用再去获取锁了。
在并发小的时候使用偏向锁有利于提升JVM效率,在高并发场合禁用掉
-XX:-UseBiasedLocking
推荐使用JDK1.8的G1垃圾回收器:
当在G1的GC日志中看到 to-space overflow 或者 to-space exhausted 的时候,表示G1没有足够的内存使用的(可能是 survivor 区不够了,可能是老年代不够了,也可能是两者都不够了),这时候表示Java堆占用大小已经达到了最大值。比如: 924.897: [GC pause (G1 Evacuation Pause)(mixed) (to-space exhausted), 0.1957310 secs] 924.897: [GC pause (G1 EvacuationPause) (mixed) (to-space overflow), 0.1957310 secs] 为了解决这个问题,请尝试做以下调整
- 增加预留内存:增大参数 -XX:G1ReservePercent 的值(相应的增加堆内存)来增加预留内存;
- 更早的开始标记周期:减小 -XX:InitiatingHeapOccupancyPercent 参数的值,以更早的开始标记周期;
- 增加并发收集线程数:增大 -XX:ConcGCThreads 参数值,以增加并行标记线程数。
对G1而言,大小超过region大小50%的对象将被认为是大对象,这种大对象将直接被分配到老年代的humongous regions中,humongous regions是连续的region集合,StartsHumongous表记集合从那里开始,ContinuesHumongous标记连续集合。
在分配大对象之前,将会检查标记阈值,如果有必要的话,还会启动并发周期。死亡的大对象会在标记周期的清理阶段和发生Full GC的时候被清理。
为了减少复制开销,任何转移阶段都不包含大对象的复制。在Full GC时,G1在原地压缩大对象。
因为每个独立的humongous regions只包含一个大对象,因此从大对象的结尾到它占用的最后一个region的结尾的那部分空间时没有被使用的,对于那些大小略大于region整数倍的对象,这些没有被使用的内存将导致内存碎片化。
如果你看到因为大对象的分配导致不断的启动并发收集,并且这种分配使得老年代碎片化不断加剧,那么请增加-XX:G1HeapRegionSize参数的值,这样的话,大对象将不再被G1认为是大对象,它会走普通对象的分配流程。
# G1回收器将堆空间划分为1024个region,此选项指定堆空间region的大小
-XX:+UseG1GC -XX:G1HeapRegionSize=16m
-XX:G1ReservePercent=25
-XX:InitiatingHeapOccupancyPercent=30
上述设置可能有点儿激进,但是对于生产环境,性能很好
XX:MaxGCPauseMillis不要设置的太小,否则JVM会使用小的年轻代空间以达到此设置的值,同时
引起很频繁的minor GC。
推荐使用GC log文件
-XX:+UseGCLogFileRotation
-XX:NumberOfGCLogFiles=5
-XX:GCLogFileSize=30m
如果写GC文件增加了Broker的延迟,可以考虑将GC log文件写到内存文件系统
-Xloggc:/dev/shm/mq_gc_%p.log123
Linux内核参数
os.sh脚本在bin文件夹中列出了许多内核参数,可以进行微小的更改然后用于生产用途。下面的参
数需要注意,更多细节请参考/proc/sys/vm/*的文档
https://www.kernel.org/doc/Documentation/sysctl/vm.txt
# 获取内核参数值
sysctl vm.extra_free_kbytes
# 设置内核参数值
sudo sysctl -w vm.overcommit_memory=1
vm.extra_free_kbytes,告诉VM在后台回收(kswapd)启动的阈值与直接回收(通过分配进程)的阈值之间保留额外的可用内存。RocketMQ使用此参数来避免内存分配中的长延迟。(与具体内核版本相关)
vm.min_free_kbytes,如果将其设置为低于1024KB,将会巧妙的将系统破坏,并且系统在高负载下容易出现死锁。
vm.max_map_count,限制一个进程可能具有的最大内存映射区域数。RocketMQ将使用mmap加载CommitLog和ConsumeQueue,因此建议将为此参数设置较大的值。
vm.swappiness,定义内核交换内存页面的积极程度。较高的值会增加攻击性,较低的值会减少交换量。建议将值设置为10来避免交换延迟。
File descriptor limits,RocketMQ需要为文件(CommitLog和ConsumeQueue)和网络连接打开文件描述符。我们建议设置文件描述符的值为655350
echo '* hard nofile 655350' >> /etc/security/limits.conf
Disk scheduler,RocketMQ建议使用I/O截止时间调度器,它试图为请求提供有保证的延迟