RabbitMQ-高级特性(六)

存储机制

待...

消息结构

惰性队列

惰性队列会尽可能将消息存入到磁盘中,消费者消费相应的消息才会加载到内存,它可以支持更长的队列

默认情况下生产者消息会尽可能存储到内存中就算设置持久化消息 也会再内存中备份一份 当rabbitMQ需要释放内存时会将内存中的队列持久化到磁盘中(消息堆积很耗时)

惰性队列无论持久化和非持久化都会存储到磁盘 所以带来了io开销,就算非持久化设置惰性队列重启后消息也会丢失(所以持久化消息和惰性队列是很好的搭档)

经过测试发送1000万条消息(无消费者) 普通队列需要耗时801秒 惰性队列需要421秒  惰性队列有消费者时平均消费速度约14000条每秒 差距就是普通队列内存不足换也持久化到磁盘的时间

惰性队列适合于消费者不能正常消息 还能保证消息接收的吞吐量

3.6.0版本之前默认是惰性队列

可以通过

Map<String,Object>args=new HasMap<String,Object>
args.put("x-queue-mode","lazy")
chinnel.queueDeclare("queuname",false,fase,false,args)

内存和磁盘告警

当使用内存超过配置阀值或者磁盘剩余空间低于配置阀值时RabbitMq都会占时阻塞客户端连接并停止接收客户端发来的消息以免服务崩溃 可以通过rabbitmqctl list_connections

命令或者web页面查看状态

被阻塞的状态要么是Blocking要么是blocked(注意集群下一个节点内存告警 整个集群也会受限制)

内存设置

可以通过rabbitmqctl set_vm_memory_high_watermark 0.4(默认值 通过命令设置重启后会失效 通过配置不会)

或者通过rabbitmq.config的vm_memory_high_watermark 参数设置

当rabbitmq使用内存超过40%(物理内存*40%)时会触发内存告警

如果设置为0将立即触发内存告警(当不允许消费者发送消息可以设置)

在内存告警前 会尝试换页持久化和非持久化消息都会持久化到磁盘 释放内存空间

磁盘设置

当broker启动时会启动一个进程监控磁盘空间 10秒一次 当剩余空间磁盘空间低于阀值时会触发磁盘告警(默认为50MB)

可以通过config disk_free_limit(阀值)  或者disk_free_limit (绝对值)设置支持单位(KB KiB MB MiB GB GiB)

或者通过命令 set_disk_free_list **GB  或者set_disk_free_limit mem_relative 0.4 (阀值)

流控

磁盘和内存告警相当于一个全局的流控 而流控是针对单个connection的

erlang进程之间不共享内存 一个进程多个connection

进程a接收消息转发给b转发给c

a没转发一条 credis值-1当为0后就会触发流动 a将不再发送消息给c 同时不再接收消息  当a没接收一条消息通知a credis+1

当a发送消息b大于b接收速度时会触发流控

一个连接触发流控会多次再blocked和unblocked之间切换 这样可以控制消息发送频率再服务器可接收范围内

连接的几个状态

 flow:和处于runing状态的connection没什么不同只是告诉系统管理员相应的发送速率受限了 

当一个connection处于flow 没有一个channel处于flow name表示connectin中有一个或多个channel出现性能瓶颈

当一个connection处于flow 并且这个connectin中一个或者多个channel处于flow状态但是没有任何一个对应的队列处于flow状态 意味着一个或者多个多列出现性能瓶颈

当一个connection处于flow 并且一个或者多个channel 队列同时出现flow状态 意味着在消息持久化出现了性能瓶颈

流控优化

书260页  意思就是讲一个进程换成多个进程队列 通过以前的一个消息队列换成 一个exchange 根据路由随机投递给多个队列 有点像spring cloud stream的分区 可以提高性能

原文地址:https://www.cnblogs.com/LQBlog/p/11019289.html