RabbitMQ的部分参数用法及部分高级功能总结

        RabbitMQ作为一款轻量级高可用高性能的消息中间件,已经得到很多公司青睐,特别是一些有金融背景的公司。若对消息要求很高,但消息的量级不足千万时,RabbitMQ就是非常不错的选择。下面主要是记录一下RabbitMQ部分参数的用法及一些高级功能的总结。

  1. Mandatory参数和Immediate参数

       Mandatory和Immediate是channel发布消息时的两个参数,主要用在当发布消息时,在不可达目的地时的消息如何处理,mandatory默认是false,当exchange无法根据类型和routing找到符合要求的队列时,消息将直接被丢弃;mandatory为true时,当出现找不到符合要求的队列时,消息将直接返回给发送者,配合ReturnListener使用,如果是spring集成amqp,则是ReturnCallback,主要代码如下:

template.setMandatory(true);

template.setReturnCallback(new ReturnCallback() {

                     @Override

                     public void returnedMessage(Message message, int replyCode, String             replyText, String exchange, String routingKey) {

                            logger.error("Messageid:{} send fail,replyCode:{},replyText:{}",

                     message.getMessageProperties().getCorrelationId(),replyCode,replyText);

                            RepublishMessageRecoverer recover = new RepublishMessageRecoverer(rabbitTemplate(), "ErrorExchange", "errorRoutingKey");

                            recover.recover(message, new Throwable("Republish fail message"));

                     }

     });

在returnedMessage中,我把收到的错误消息再路由到错误的队列中,并记录一下日志,供后期排查问题用。

immediate参数设置为true时,表示消息发送到队列后,需要立即消费,若当前队列没有消费者,则消息将会被路由到生产者,在RabbitMQ3.0版本以后,这个参数因为影响镜像队列的性能,被去掉了,不再对immediate参数支持。

   2,镜像队列

    通俗的讲:镜像模式是RabbitMQ集群模式最常用的一种,当某个队列为镜像队列时,那集群中的其他机器会至少有一个此队列的备份队列,而且当master队列down掉时,备份队列中某一个(一般是此备份队列的第一个)会自动切换为master队列提供服务,保证服务的可用性。结构如下:

RabbitMQ的部分参数用法及部分高级功能总结_第1张图片

镜像队列一般以vhost为基础,当vhost为镜像模式时,该vhost下的队列都是镜像队列。当设置某个vhost的policies时,有几个关键性参数需要关注:

ha-mode:镜像模式,分为三种all,exactly,nodes。如下:

ha-mode

ha-params

result

all

none

镜像队列会在整个集群中创建mirror队列,当集群新增一个节点时,镜像队列会mirror到此节点上。
mirror到所有的节点会增加额外的压力到所有集群的节点上,包括网络i/o,磁盘i/o和磁盘空间的使用。

exactly

count

在集群中mirror count个队列,
count=1时,集群中只有一个master队列;
count=2时,集群中一个master,一个mirror队列;
若count大于集群节点数,等同于all,若count小于集群节点数,当其中一个mirror队列down掉时,一个新的mirror队列将会被创建在另一个节点上。
count=N/2 +1是最被推荐的

nodes

node names

mirror队列将会被创建在指定的node名字上,节点名字也就是二郎节点在集群状态上显示的那个;
如果节点名字没有在集群中,这将不会构成错误,但master队列将被声明在client连接的那个节点上。

ha-sync-mode:mirror队列的同步方式,有automatic和manual。默认为manual,当为manual时,master队列消息不会主动同步到slave,除非显式的调用同步命令。当为automatic时,master队列消息会主动同步到slave中,推荐设置为automatic。通过RabbitMQ管理界面设置镜像队列示例如下:

RabbitMQ的部分参数用法及部分高级功能总结_第2张图片

   3.惰性队列

    RabbitMQ从3.6.0版本开始引入惰性队列的概念,它会尽快的尽可能的持久消息到磁盘上,只有当消费者消费这些消息时才会加载到内存中。它被设计的一个最主要的目的是能够支持更长的队列(几百万量级),当消费者由于各种各样的原因比如延迟队列,消费者下线,消费者消费慢,down机等,致使长时间不能消费消费而造成消息堆积时,惰性队列就非常有用。

默认情况下,当生产消息时,队列消息会尽可能的保存在内存中,这样就可以尽快的把消息推送给消费者,即使是持久性的消息,在被写到磁盘时,也会保留一份在内存中。当broker需要释放内存时,会将内存中的消息paged out 到磁盘上。paged 一批消息到磁盘将会耗会时间和堵塞队列接收新消息。虽然最新的RabbitMQ版本提高了page算法,但是在大消息量级时,堵塞队列操作的情形依然存在。

惰性队列特性就是尽可能快速的把消息移动到磁盘保存,这就表示在普遍的操作中内存中会保留着非常少的消息,不过这会增加磁盘I/O的消费。

惰性队列有2中模式:default和lazy。默认模式是default,若想设置为惰性队列,

可以通过queue.daclare

也可以通过policy,如:

RabbitMQ的部分参数用法及部分高级功能总结_第3张图片

比如惰性队列与普通队列的对比,发送1千万条消息,每条消息的大小只为1KB,普通队列耗时801秒,而惰性队列在420秒,若此时没有消费者,惰性队列消耗内存1.5MB,而普通队列为1.2GB。

     4.内存和磁盘设置

     当内存使用超过配置的阈值或者磁盘剩余空间低于配置的阈值时,RabbitMQ都会暂时堵塞客户端的connection并停止接收从客户端发送过来的消息,以此来避免服务崩溃。

所以需要设置内存阈值,通过rabbitmqctl environment可以查看vm_memory_high_watermark参数,如下:

RabbitMQ的部分参数用法及部分高级功能总结_第4张图片

默认情况下RabbitMQ所使用的内存阈值设置为0.4,这并不意味着此时的RabbitMQ不能使用超过40%的内存,这仅仅只是限制了RabbitMQ的消息生产者。在最坏的情况下,二郎的垃圾回收机制会导致2倍的内存消耗,也就是80%的使用占比。

vm_memory_high_watermark正常取值范围在0.4到0.66,不建议取值超过0.7.也可以设置绝对值内存,如:

{vm_memory_high_watermark,{absolute,”1024MiB”}},命令如下:

rabbitmqctl set vm_memory_high_watermark {absolute,”1024MiB”}

     5.state状态

    管理界面上会有connection,channel,queue的state,这些状态有以下几种,idle,running,flow,blocked,blocking,所表达意思如下:

idle 空闲,一般在队列上没有生产者和消费者时会显式显示

running 表示进行生产或者消费

flow 表示消息的发送速率受限,connection,channel或者queue出现了性能瓶颈,因为消息的发送是从connection->channnel->queue->store流式处理的,queue环节容易造成性能瓶颈

blocked与blocking主要针对connection,blocking对应于不是试图发送消息的connection,比如消费者的connection,此时connection可以继续运行;blocked对应于一直有消息发送的connection,这种状态下的connection会停止发送消息。

    6.HTTP API接口

    RabbitMQ management 插件不仅提供了一个优秀的web管理界面,还提供了HTTP API接口以供调用。通过/api/nodes接口来获取集群节点的信息,返回结果是一个json字符串,通过解析json字符串,拿到我们需要的参数,包括磁盘,内存占用等的实时信息;如下:

获取exchange信息  ip:15672/api/exchanges/

获取queue信息 ip:15672/api/queues/vhost/name

获取各个节点信息 /api/nodes/name

获取所有的连接信息 /api/connections

      获取指定的信道信息 /api/channels/channel

获取所有的绑定信息 /api/bindings

等等,具体详情请查看官网。

    7.消息追踪

     RabbitMQ management 提供了一个rabbitmq_tracing插件,执行开启命令后,会在控制台有tracing功能,它会记录所配置的vhost下所有的队列消息发送接收情况,有两种模式一个text,一个是json。缺点是:没有做到与业务队列逻辑隔离,当消息量很大时,消息轨迹记录也会消耗该台机器的性能,进而影响消息发送接收情况,所以是否开启此插件功能,需要根据业务逻辑及消息量级来考虑。

     RabbitMQ高阶功能还有很多比如流控,跨集群的federation plugin 和shovel plugin,网络分区等等,后续会补充。

你可能感兴趣的:(java,RabbitMQ,MQ,消息中间件)