RabbitMQ - 许多队列还是带有路由键的队列?
RabbitMQ - Many queues or one with routing keys?
我是 运行 一个分布式应用程序(运行 在多个服务器上),它从我们的主后端服务器 运行 一个 RabbitMQ 集群获取消息。
然而,消息几乎都是同一类,但我为每个客户使用一个队列。
我注意到我们的负载和内存使用率非常高 - 仅使用一个队列和路由键作为客户 ID 可以解决问题吗?
目前,我正在为每个消费者使用一个通道,每个连接最多使用 20 个通道 - 因此访问 rabbitmq 服务器的一台服务器可以有多个连接。大约 500-800 个连接并不罕见。
更新
以下是一些指标:
Connections: 748
Channels: 6577
Exchanges: 8
Queues: 1590
Consumers: 1098
Messages Total: 153.394
Messages unacked: 152.848
Acknowledge: 2674/s
Publish: 704/s
Deliver: 586/s
和rabbitmqctl status
输出:
Status of node rabbit@masternode ...
[{pid,10814},
{running_applications,
[{rabbitmq_management,"RabbitMQ Management Console","3.5.6"},
{rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.5.6"},
{webmachine,"webmachine","1.10.3-rmq3.5.6-gite9359c7"},
{mochiweb,"MochiMedia Web Server","2.7.0-rmq3.5.6-git680dba8"},
{rabbitmq_management_agent,"RabbitMQ Management Agent","3.5.6"},
{rabbit,"RabbitMQ","3.5.6"},
{os_mon,"CPO CXC 138 46","2.2.14"},
{inets,"INETS CXC 138 49","5.9.7"},
{mnesia,"MNESIA CXC 138 12","4.11"},
{amqp_client,"RabbitMQ AMQP Client","3.5.6"},
{xmerl,"XML parser","1.3.5"},
{sasl,"SASL CXC 138 11","2.3.4"},
{stdlib,"ERTS CXC 138 10","1.19.4"},
{kernel,"ERTS CXC 138 10","2.16.4"}]},
{os,{unix,linux}},
{erlang_version,
"Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:32:32] [async-threads:64] [kernel-poll:true]\n"},
{memory,
[{total,1093604792},
{connection_readers,8069400},
{connection_writers,6168304},
{connection_channels,115667448},
{connection_other,20448952},
{queue_procs,526134000},
{queue_slave_procs,3045928},
{plugins,1638160},
{other_proc,20891248},
{mnesia,5975616},
{mgmt_db,63193376},
{msg_index,2245016},
{other_ets,3895632},
{binary,214973160},
{code,20000582},
{atom,703377},
{other_system,80554593}]},
{alarms,[]},
{listeners,[]},
{vm_memory_high_watermark,0.4},
{vm_memory_limit,54036645478},
{disk_free_limit,50000000},
{disk_free,100918980608},
{file_descriptors,
[{total_limit,49900},
{total_used,1231},
{sockets_limit,44908},
{sockets_used,243}]},
{processes,[{limit,1048576},{used,15377}]},
{run_queue,1},
{uptime,2241834}]
发布和交付有时会停滞(非常低)
更新 2
日志中没有显示任何内容,并且 java 驱动程序在某些内容被阻止时不调用回调。
我有几个用例,例如我加载到搜索服务器 (solr) 的批处理文档。许多生产者(>50)每分钟生成大约 50.000 条消息,消费者使用该队列而不使用 autoack。
消息发送成功后(或最多重试5次),消息将被确认。也许这可以阻止一切?我将它设置为 autoack,现在一切都运行得更顺畅了。
我最初的问题是:我们的每个客户都有一个当前处于 autoack 状态的队列。可能会发生其中一个客户突然没有客户的情况,但这根本不是问题。那么,使用带有路由键的单个队列会提高性能吗?
目前我只是发送到一个没有路由密钥(或空路由密钥)的空交换(默认交换)直接到客户队列。邮件压缩 json,非常小,平均几 kb。
就目前而言,连接和通道都是轻量级对象,尽管与创建连接相比,创建连接涉及额外的过程和开销,通道只是一个单数据包命令。我不希望 800 个连接甚至开始拉伸 RabbitMQ。内存使用和磁盘使用主要由队列中的消息数量驱动,并且在某种程度上由队列数量驱动。如果没有关于您的应用程序吞吐量的详细信息,就很难进一步推测,但我会首先确保您的生产者和消费者从数量的角度来看大致匹配。
要了解有关内存使用情况的更多信息,请调用 rabbitmqctl status
(请参阅文档 here)。
我是 运行 一个分布式应用程序(运行 在多个服务器上),它从我们的主后端服务器 运行 一个 RabbitMQ 集群获取消息。
然而,消息几乎都是同一类,但我为每个客户使用一个队列。 我注意到我们的负载和内存使用率非常高 - 仅使用一个队列和路由键作为客户 ID 可以解决问题吗?
目前,我正在为每个消费者使用一个通道,每个连接最多使用 20 个通道 - 因此访问 rabbitmq 服务器的一台服务器可以有多个连接。大约 500-800 个连接并不罕见。
更新
以下是一些指标:
Connections: 748
Channels: 6577
Exchanges: 8
Queues: 1590
Consumers: 1098
Messages Total: 153.394
Messages unacked: 152.848
Acknowledge: 2674/s
Publish: 704/s
Deliver: 586/s
和rabbitmqctl status
输出:
Status of node rabbit@masternode ...
[{pid,10814},
{running_applications,
[{rabbitmq_management,"RabbitMQ Management Console","3.5.6"},
{rabbitmq_web_dispatch,"RabbitMQ Web Dispatcher","3.5.6"},
{webmachine,"webmachine","1.10.3-rmq3.5.6-gite9359c7"},
{mochiweb,"MochiMedia Web Server","2.7.0-rmq3.5.6-git680dba8"},
{rabbitmq_management_agent,"RabbitMQ Management Agent","3.5.6"},
{rabbit,"RabbitMQ","3.5.6"},
{os_mon,"CPO CXC 138 46","2.2.14"},
{inets,"INETS CXC 138 49","5.9.7"},
{mnesia,"MNESIA CXC 138 12","4.11"},
{amqp_client,"RabbitMQ AMQP Client","3.5.6"},
{xmerl,"XML parser","1.3.5"},
{sasl,"SASL CXC 138 11","2.3.4"},
{stdlib,"ERTS CXC 138 10","1.19.4"},
{kernel,"ERTS CXC 138 10","2.16.4"}]},
{os,{unix,linux}},
{erlang_version,
"Erlang R16B03 (erts-5.10.4) [source] [64-bit] [smp:32:32] [async-threads:64] [kernel-poll:true]\n"},
{memory,
[{total,1093604792},
{connection_readers,8069400},
{connection_writers,6168304},
{connection_channels,115667448},
{connection_other,20448952},
{queue_procs,526134000},
{queue_slave_procs,3045928},
{plugins,1638160},
{other_proc,20891248},
{mnesia,5975616},
{mgmt_db,63193376},
{msg_index,2245016},
{other_ets,3895632},
{binary,214973160},
{code,20000582},
{atom,703377},
{other_system,80554593}]},
{alarms,[]},
{listeners,[]},
{vm_memory_high_watermark,0.4},
{vm_memory_limit,54036645478},
{disk_free_limit,50000000},
{disk_free,100918980608},
{file_descriptors,
[{total_limit,49900},
{total_used,1231},
{sockets_limit,44908},
{sockets_used,243}]},
{processes,[{limit,1048576},{used,15377}]},
{run_queue,1},
{uptime,2241834}]
发布和交付有时会停滞(非常低)
更新 2
日志中没有显示任何内容,并且 java 驱动程序在某些内容被阻止时不调用回调。
我有几个用例,例如我加载到搜索服务器 (solr) 的批处理文档。许多生产者(>50)每分钟生成大约 50.000 条消息,消费者使用该队列而不使用 autoack。
消息发送成功后(或最多重试5次),消息将被确认。也许这可以阻止一切?我将它设置为 autoack,现在一切都运行得更顺畅了。
我最初的问题是:我们的每个客户都有一个当前处于 autoack 状态的队列。可能会发生其中一个客户突然没有客户的情况,但这根本不是问题。那么,使用带有路由键的单个队列会提高性能吗?
目前我只是发送到一个没有路由密钥(或空路由密钥)的空交换(默认交换)直接到客户队列。邮件压缩 json,非常小,平均几 kb。
就目前而言,连接和通道都是轻量级对象,尽管与创建连接相比,创建连接涉及额外的过程和开销,通道只是一个单数据包命令。我不希望 800 个连接甚至开始拉伸 RabbitMQ。内存使用和磁盘使用主要由队列中的消息数量驱动,并且在某种程度上由队列数量驱动。如果没有关于您的应用程序吞吐量的详细信息,就很难进一步推测,但我会首先确保您的生产者和消费者从数量的角度来看大致匹配。
要了解有关内存使用情况的更多信息,请调用 rabbitmqctl status
(请参阅文档 here)。