汇率冲突仅靠政府对话远远不够
138
2024-11-13
大家好,关于rabbitmq启动慢很多朋友都还不太明白,今天小编就来为大家分享关于rabbitmq 启动的知识,希望对各位有所帮助!
本文目录
RabbitMQ消费者性能优化相关配置说明rabbitmq压力测试结果RabbitMQ最佳实践为什么rabbitMQ启动特别慢RabbitMQ消费者性能优化相关配置说明RabbitMQ是用Erlang语言编写的分布式消息中间件,常常用在大型网站中作为消息队列来使用,主要目的是各个子系统之间的解耦和异步处理。消息中间件的基本模型是典型的生产者-消费者模型,生产者发送消息到消息队列,消费者监听消息队列,收到消息后消费处理。
在使用RabbitMQ做消息分发时,主要有三个概念要注意:Exchange,RoutingKey,Queue。
Exchange可以理解为交换器,RoutingKey可以理解为路由,Queue作为真实存储消息的队列和某个Exchange绑定,具体如何路由到感兴趣的Queue则由Exchange的三种模式决定:
(1)Exchange为fanout时,生产者往此Exchange发送的消息会发给每个和其绑定的Queue,此时RoutingKey并不起作用;
(2)Exchange为topic时,生产者可以指定一个支持通配符的RoutingKey(如demo.*)发向此Exchange,凡是Exchange上RoutingKey满足此通配符的Queue就会收到消息;
(3)direct类型的Exchange是最直接最简单的,生产者指定Exchange和RoutingKey,然后往其发送消息,消息只能被绑定的满足RoutingKey的Queue接受消息。(通常如果不指定RoutingKey的具体名字,那么默认的名字其实是Queue的名字)
消费端yml配置:
在消费端,配置prefectch和concurrency参数便可以实现消费端mq并发处理消息,那么这两个参数具有有什么含义呢?
prefetch是每次从一次性从broker里面取的待消费的消息的个数。
每个customer会在MQ预取一些消息放入内存的LinkedBlockingQueue中进行消费,这个值越高,消息传递的越快,但非顺序处理消息的风险更高。如果ack模式为none,则忽略。
prefetch默认值以前是1,这可能会导致高效使用者的利用率不足。从spring-amqp2.0版开始,默认的prefetch值是250,这将使消费者在大多数常见场景中保持忙碌,从而提高吞吐量。
不过在有些情况下,尤其是处理速度比较慢的大消息,消息可能在内存中大量堆积,消耗大量内存;以及对于一些严格要求顺序的消息,prefetch的值应当设置为1。
对于低容量消息和多个消费者的情况(也包括单listener容器的concurrency配置)希望在多个使用者之间实现更均匀的消息分布,建议在手动ack下并设置prefetch=1。
如果要保证消息的可靠不丢失,当prefetch大于1时,可能会出现因为服务宕机引起的数据丢失,故建议将prefetch=1。
concurrency设置的是对每个listener在初始化的时候设置的并发消费者的个数。在上面的yml配置中,concurrency=1,即每个Listener容器将开启一个线程去处理消息。在2.0以后的版本中,可以在注解中配置该参数:
在服务启动后,可以发现在Listener容器中产生了两个线程去消费queue。如果在Listener配置了exclusive参数,即确定此容器中的单个customer是否具有对队列的独占访问权限。如果为true,则容器的并发性必须为1。
若一个消费者配置prefetch=10,concurrency=2,会有两个消费者(或是线程)同时监听Queue,但是注意这里的消息只要有被一个消费者消费掉就会自动ack,另外一个消费者就不会再获取到此消息,PrefetchCount为配置设置的值10,意味着每个消费者每次会预取10个消息准备消费(注意不是两个消费者去共享内存中抓取的消息)。
每个消费者对应的listener有个Exclusive参数,默认为false,如果设置为true,concurrency就必须设置为1,即只能单个消费者消费队列里的消息,适用于必须严格执行消息队列的消费顺序(先进先出)。
前面说过,设置并发的时候,要考虑具体的业务场景,对那种对消息的顺序有苛刻要求的场景不适合并发消费,而对于其他场景,比如用户注册后给用户发个提示短信,是不太在意哪个消息先被消费,哪个消息后被消费,因为每个消息是相对独立的,后注册的用户先收到短信也并没有太大影响。
设置并发消费除了能提高消费的速度,还有另外一个好处:当某个消费者长期阻塞,此时在当前消费者内部的BlockingQueue的消息也会被一直阻塞,但是新来的消息仍然可以投递给其他消费者消费,这种情况顶多会导致prefetch个数目的消息消费有问题,而不至于单消费者情况下整个RabbitMQ的队列会因为一个消息有问题而全部堵死。所有在合适的业务场景下,需要合理设置concurrency和prefetch值。
rabbitmq压力测试结果 性能相关情况
集群稳定性
集群的高用性
3个节点,节点服务器均为4核8G
每个节点均为磁盘节点
使用镜像队列
rabbitmq-perf-test
PerfTest是一个基于Java客户端的吞吐量测试工具,可以将其配置为模拟基本工作负载和更高级的工作负载。PerfTest还有一些额外的工具,可以生成输出的HTML图形。
RabbitMQ集群可能受到多种因素的限制,从基础架构级别的约束(例如,网络带宽)到RabbitMQ配置和拓扑,再到发布和使用的应用程序。PerfTest可以演示节点或节点集群的基准性能。
https://rabbitmq.github.io/rabbitmq-perf-test/stable/htmlsingle/#basic-usage
https://github.com/rabbitmq/rabbitmq-perf-test/blob/master/html/README.md
跑统计:bin/runjavacom.rabbitmq.perf.PerfTestMultihtml/test1/spec.jshtml/test1/result.js
起服务看结果:bin/runjavacom.rabbitmq.perf.WebServer 服务器IP地址:8080/test1/result.html
一开始进行单场景脚本测试时,发送速率也基本维持在35k/s左右,无法往上涨;开启多场景多脚本同步进行施加压力之后,发送速率也无法上升,反而一直在降,同时压测机器的负载也很高,性能跟不上。调整升级压测机器后,当我们多场景多脚本进行施压时,发送速率依旧变化不大,这是因为rabbitmq有相应的流控机制:
服务端默认配置是当内存使用达到40%,磁盘空闲空间小于50M,即启动内存报警,磁盘报警;报警后服务端触发流控(flowcontrol)机制。
一般地,当发布端发送消息速度快于订阅端消费消息的速度时,队列中堆积了大量的消息,导致报警,就会触发流控机制。
触发流控机制后,RabbitMQ服务端接收发布来的消息会变慢,使得进入队列的消息减少;
与此同时RabbitMQ服务端的消息推送也会受到极大的影响,测试发现,服务端推送消息的频率会大幅下降,等待下一次推送的时间,有时等1分钟,有时5分钟,甚至30分钟。
一旦触发流控,将导致RabbitMQ服务端性能恶化,推送消息也会变得非常缓慢;
调整测试脚本,增大生产者的并发数量到1000,5个队列,50个消费者,此时rabbitmq节点1的负载被打满;然后依次不停降低生产者和消费者的并发数量,直至生产者与消费者均只为30的场景,发现rabbitmq节点1服务器的cpu负载均很高,此时发现rabbitmq节点1服务器的cpu资源几乎都被四个线程也即rabbitmq的调取器线程占用,通过调整rabbitmq的调度器线程数量,我们发现发现速率以及服务器cpu负载有一定的变化,rabbitmq单节点的瓶颈在于其调度器的线程数:
4个线程全打开时,发送速率限制在了35k/s,此时空闲的cpu最大不到10%
打开3个调度器线程时,发送速率限制在25k/s,此时空闲的cpu最大为25%
打开2个调度器线程时,发送速率限制在20k/s,此时空闲的cpu最大为30%
因此,我们可以通过以下措施来提升rabbitmq的服务性能:
我们应当尽量避免触发rabbitmq的流控机制,要做好数据设计,使得发送速率和接收速率保持平衡,而不至于引起服务器堆积大量消息,进而引发流控。通过增加服务器集群节点,增加消费者,来避免流控发生,治标不治本,而且成本高。
如果当前的性能达不到业务要求时,可以升级服务器,将服务器由4核升级到8核,增加rabbitmq的调度器线程数量,来提升性能。
1个节点,节点内存为3G,只发布不消费,1个队列,10个消费者,生产速率上限约为60k/s,发送速率为0时是触发了rabbitmq的流控机制
1个节点,节点内存为3G,只发布不消费,1个队列,15个生产者,上限约为70k/s,发送速率为0时是触发了rabbitmq的流控机制
3、1个节点,节点内存为3G,只发布不消费,1个队列,30个生产者,上限约为60k/s,发送速率为0时是触发了rabbitmq的流控机制
1个节点,节点内存为3G,只发布不消费,1个队列,60个生产者,上限约为60k/s,发送速率为0时是触发了rabbitmq的流控机制
1个节点,节点内存为4G,只发布不消费,1个队列,30个生产者,上限约为70k/s,发送速率为0时是触发了rabbitmq的流控机制
1个节点,节点内存为4G,生产者大于消费者,1个队列,30个生产者,10个消费者,发送速率上限约为50k/s,消费速率上限约为25k/s
1个节点,节点内存为4G,生产者大于消费者,1个队列,30个生产者,15个消费者,发送速率上限约为60k/s,消费速率上限约为35k/s
1个节点,节点内存为4G,生产者大于消费者,1个队列,30个生产者,30个消费者,发送速率上限约为60k/s,消费速率上限约为35k/s
1个节点,节点内存为4G,生产者大于消费者,2个队列,30个生产者,30个消费者,发送速率上限约为60k/s,消费速率上限约为45k/s
1个节点,节点内存为4G,生产者大于消费者,1个队列,5个消费者,生产者从[1,5,10,15]逐步增加,消息体的大小由[0,1000,5000,10000,50000]逐步增加,下图的rate为发送速率
1个节点,节点内存为4G,生产者大于消费者,3个队列,5个消费者,生产者从[1,5,10,15]逐步增加,消息量由[0,1000,5000,10000,50000]逐步增加,消费速率约等于三个队列加总的发送速率
过程中队列有积压
1个节点,节点内存为4G,生产者大于消费者,1个队列,生产者和消费者数量均从[1,5,10,15,20]逐步增加,前台查看发送和接收速率基本持平,大部分在25k/s-30k/s
11、1个节点,节点内存为4G,生产者大于消费者,4个队列,生产者和消费者数量均从[1,5,10,15]逐步增加
RabbitMQ最佳实践有些应用程序需要非常高的吞吐量,而其他一些应用程序却正在发布批处理作业,这些作业可能会延迟一段时间。在设计系统时,目标应该是最大限度地将性能和可用性结合起来,这对您的特定应用程序是有意义的。错误的体系结构设计决策或客户端错误,可能会损坏中间件或影响吞吐量。
您的发布服务器可能会停止运行,或者由于内存使用过多而导致服务器崩溃。本系列文章重点关注rabbitmq的最佳实践。应做和不应做两种不同使用类别的最佳实践相混合;高可用性和高性能(高吞吐量)。我们将讨论队列大小、常见错误、延迟队列、预取值、连接和通道、HIPE和集群中的节点数。这些通常都是最佳实践规则,基于我们在使用rabbitmq时获得的经验。
队列中的许多消息会对RAM的使用造成很大的负担。为了释放RAM,rabbitmq将(页面输出)消息刷新到磁盘。此过程会降低排队速度。当有许多消息需要分页取出时,分页过程通常会花费时间并阻止队列处理消息。许多消息可能会对中间件的性能产生负面影响。
当有许多消息重启集群时,也是费时的,因为必须重建索引。重新启动后,在群集中的节点之间同步消息也需要时间。
在rabbitmq3.6中添加了一个名为lazyqueues的功能。懒惰队列是消息自动存储到磁盘上的队列。只有在需要时才将消息加载到内存中。对于懒惰的队列,消息直接进入磁盘,因此RAM的使用被最小化,但是吞吐时间将花费更长的时间。
我们已经看到,懒惰的队列以更好的可预测性的方式,创建了一个更稳定的集群。要让您的消息不出现警告,请刷新到磁盘。你不会突然被一个性能冲击问题所困扰。如果您一次发送大量消息(例如处理批处理作业),或者如果您认为您的消费者一直无法跟上发布者的速度,我们建议您启用延迟队列。
对于经常受到消息峰值冲击的应用程序,以及要求吞吐量比其他任何东西都重要的应用程序,可以推荐的另一做法是设置队列的最大长度。这样可以通过丢弃来自队列头部的消息来保持队列的简短性,从而使队列永远不会超过max-length设置。
队列在rabbitmq中是单线程的,一个队列可以处理大约50k条消息/秒。如果您有多个队列和消费者,您可以在多核系统上获得更好的吞吐量。如果在底层节点上拥有与核心一样多的队列,那么您将获得最佳吞吐量。
rabbitmq管理接口为集群中的每个队列收集和计算度量。如果您有数千个活动队列和使用者,这可能会减慢服务器的运行速度。如果队列太多,CPU和RAM的使用也可能受到负面影响。
队列性能受限于一个CPU核心。因此,如果将队列拆分到不同的核心,您将获得更好的性能;如果您拥有rabbitmq集群,您也可以将他们拆分到不同的节点。
rabbitmq队列绑定到最初声明它们的节点。即使您创建了一个rabbitmq中间件集群,所有路由到特定队列的消息都将转到该队列所在的节点。您可以在节点之间平均地手动拆分队列,但缺点是您需要记住队列的位置。
如果您有多个节点或具有多个核心的单节点集群,我们建议使用两个插件来帮助您:
当您想要在生产者和消费者之间共享队列时,为队列命名是很重要的,但是如果您使用临时队列,则不重要。相反,您应该让服务器使用一个随机的队列名称,而不是你自己命名一个——或者修改rabbitmq策略。
客户机连接可能会失败,并可能留下未使用的资源(队列),留下许多队列可能会影响性能。自动删除队列有三种方法:
在ErlangVM的内部队列每个队列均使用用了一个优先级别,他们耗费了一些资源。在大多数情况下,不超过5个优先级就足够了。
一个常见的问题是如何处理发送到rabbitmq的消息的palyload(消息大小)。当然,您不应该在消息中发送非常大的文件信息,但是每秒的消息数是一个比它本身的消息大小更大的瓶颈。发送多个小消息可能是一个坏的选择。一个更好的办法是将它们捆绑成一个更大的消息,让消费者将其拆分。但是,如果捆绑多条消息,则需要记住这可能会影响处理时间。如果其中一条捆绑消息失败,是否需要重新处理所有这些消息?如何设置这个取决于带宽和体系结构。
每个连接使用大约100kb的RAM(如果使用TLS,甚至更多)。数千个连接可能是rabbitmq服务器的沉重负担。在最坏的情况下,服务器可能由于内存不足而崩溃。AMQP协议有一种称为“多路复用”的机制,它“复用”单个TCP连接。它建议每个进程只创建一个TCP连接,并在这个唯一一个连接的基础上为不同的线程使用多个通道。连接也应该是长连接的。AMQP连接的握手过程非常复杂,至少需要7个TCP数据包(如果使用了TLS,则需要更多)。
相反,如果需要,可以更频繁地打开和关闭通道。如果可能的话,甚至通道也应该是长寿命的,例如,在每个发布信息线程中复用相同的通道。每次发布信息时不用打开频道。最佳实践是复用连接,使用各通道在一个连接的基础上实现多路复用。理想情况下,每个进程只能有一个连接,然后在应用程序中为每个线程使用一个通道,而每个channel复用同一个连接即可。
您还应该确保不在线程之间共享通道,因为大多数客户机不保证通道是线程安全的(因为这样会对性能产生严重的负面影响)。
确保不要在线程之间共享通道,因为大多数客户机不会使通道线程安全(因为这样会对性能产生严重的负面影响)。
为发布者和消费者区分连接以获得高吞吐量。当发布服务器向服务器发送太多要处理的消息时,rabbitmq可以对TCP连接施加反向压力。如果消费者使用相同的TCP连接,服务器可能不会从客户机接收消息确认。因此,消费性能也会受到影响。而随着消费速度的降低,服务器将不堪重负。
具有大量连接和通道的另一个影响为rabbitmq管理接口的性能。对于每个连接和通道性能,指标必须收集、分析和显示度量。
在连接失败的情况下,传输中的消息可能会丢失,并且可能需要重新传输此类消息。Acknowledgements让服务器和客户机知道何时重新传输消息。客户机可以在收到消息时对其进行确认,也可以在客户机完全处理完消息后对其进行确认。Acknowledgement具有性能影响,因此为了实现最快的吞吐量,应该禁用手动确认。
接收重要消息的消费应用程序在完成需要对其进行的任何操作之前不应确认消息,这样未处理的消息(工作进程崩溃、异常等)就不会丢失。
发布确认,是相同的事情,但用于发布。服务器收到来自发布服务器的消息时会进行确认。发布确认也会影响性能。但是,应该记住,如果发布者至少需要处理一次消息,就需要这样做。
所有未确认的消息必须驻留在服务器上的RAM中。如果您有太多未确认的消息,您将耗尽内存。限制未确认消息的一个有效方法是客户端预取的消息数做出相关设置。在预取部分了解有关预取的更多信息。
如果您不能承受丢失任何消息的代价,请确保您的队列声明为“持久”,并且您的消息以传递模式“持久”发送。
为了避免在中间件中丢失消息,需要为中间件重新启动、中间件硬件故障或中间件崩溃时做好准备。为了确保消息和中间件定义在重新启动后仍然存在,我们需要确保它们在磁盘上。在中间件重新启动期间,不持久的消息、交换和队列将会被丢失。
持久性消息更重,因为它们必须写入磁盘。请记住,即使您发送的是临时消息,懒惰的队列也会对性能产生相同的影响。对于高性能-请使用瞬态消息。
您可以通过amqps连接到rabbitmq,这是用tls包装的amqp协议。由于所有流量都必须加密和解密,因此TLS会影响性能。为了获得最大的性能,我们建议使用vpc对等,那么流量是私有的,并且是独立的,不涉及AMQP客户机/服务器。
在cloudamqp中,我们将rabbitmq服务器配置为只接受快速但安全的加密密码并确定其优先级。
预取值用于指定多少条消息将同时被发送给消费者。它被用来从你的消费者那里得到尽可能多的东西(饱和工作)。
FromRabbitMQ.com:“Thegoalistokeeptheconsumerssaturatedwithwork,buttominimisetheclient'sbuffersizesothatmoremessagesstayinRabbit'squeueandarethusavailablefornewconsumersortojustbesentouttoconsumersastheybecomefree.”
来自rabbitmq.com:“我们的目标是让消费者饱和工作,但要最大限度地减小客户机的缓冲区大小,因此更多的消息被留在Rabbit的队列中,从而对新的消费者可用,或者发送给那些变得空闲的消者。”
rabbitmq的默认预取设置为客户端提供了一个不受限制的缓冲区,这意味着rabbitmq在默认情况下会将尽可能多的消息发送给任何看起来准备接受它们的客户机。发送的消息由rabbitmq客户端库(在使用者中)缓存,直到对其进行处理。预取限制了在确认消息之前客户端可以接收的消息数。所有预取的消息都将从队列中删除,并且对其他使用者不可见。
AtoosmallprefetchcountmayhurtperformancesinceRabbitMQismostofthetimewaitingtogetpermissiontosendmoremessages.Theimagebelowisillustratinglongidlingtime.Intheexample,wehaveaQoSprefetchsettingof1.ThismeansthatRabbitMQwon'tsendoutthenextmessageuntilaftertheroundtripcompletes(deliver,process,acknowledge).Roundtimeinthispictureisintotal125mswithaprocessingtimeofonly5ms.
预取数太小可能会影响性能,因为rabbitmq大多数时间都在等待获得发送更多消息的许可。下图显示的是长时间的空转时间。在本例中,QoS预取设置为1。这意味着rabbitmq在往返完成(传递、处理、确认)之前不会发送下一条消息。图片中的整个周期时间总共为125ms,处理时间仅为5ms。
另一方面,大量的预取数可以接收队列中的大量消息并将其传递给同一个消费者,但是其他使用者却处于空闲状态。
如果您有一个或几个消费者快速处理消息,我们建议您一次预取多个消息。尽量让你的客户端繁忙。如果您一直有大约相同的处理时间,并且网络行为保持不变-您只需在客户机上为每个消息计算总的往返时间/处理时间,即可获得估计的预取值。
如果您有许多消费者,并且处理时间很短,我们建议预取值设置的应该比单个或少数使用者要低一些。太低的值会让消费者空转很多,因为他们需要等待消息到达。过高的值可能会使一个消费者忙碌,而其他消费者则处于空闲状态。
如果您有许多使用者和/或处理时间较长,我们建议您将预取计数设置为1,以便消息在所有消费者中均匀分布。
请注意,如果客户端自动确认消息,则预取值将不起作用。
一个典型的错误是有一个无限的预取,其中一个客户机接收所有的消息,耗尽内存并崩溃,然后所有的消息都被重新传递。
有关rabbitmq预取的信息,请参阅推荐的rabbitmq文档。
HIPE将以增加启动时间为代价增加服务器吞吐量。启用HIPE时,将在启动时编译rabbitmq。根据我们的基准测试,吞吐量增加了20-80%。HIPE的缺点是启动时间也增加了很多,大约1-3分钟。在rabbitmq的文档中,hipe仍然被标记为实验性的。
如果您需要高可用性,请不要启用HIPE。
当您用一个节点创建一个cloudamqp实例时,您将得到一个具有高性能的单个节点。一个节点将为您提供最高的性能,因为消息不需要在多个节点之间进行镜像。
当您使用两个节点创建一个CloudAMQP实例时,与单个节点的相比,您将获得一半的性能。节点位于不同的可用性区域,队列在可用性区域之间自动镜像。两个节点将为您提供高可用性,因为一个节点可能崩溃或被标记为受损,但另一个节点仍将启动并运行,准备接收消息。
当您使用三个节点创建一个CloudAMQP实例时,与单个节点的相同计划大小相比,您将获得1/4的性能。节点位于不同的可用性区域,队列在可用性区域之间自动镜像。您也可以暂停少数组件-与允许每个节点响应相比,通过关闭少数组件,您减少了重复传递。暂停少数组件是三节点集群中的一种分区处理策略,它可以防止由于网络拆分而导致数据不一致。
我们在cloudamqp集群中注意到的一个常见错误是,用户创建了一个新的vhost,但忘记为新的vhost启用一个ha策略。如果没有HA策略,则不会在节点之间同步消息。
直接交换是最快速。如果有许多bindings,rabbitmq必须计算将消息发送到何处。
有些插件可能非常好用,但它们可能会消耗大量的CPU或RAM。因此,不建议将它们用于生产服务器。确保禁用不使用的插件。您可以通过CloudAmqp中的控制面板启用许多不同的插件。
将rabbitmq管理统计速率模式设置为detailed会严重影响性能,不应在生产中使用。
确保您使用的是最新推荐的客户端库版本
保持最新稳定版本的rabbitmq和erlang。在为客户发布新的主要版本之前,我们通常会在很大程度上对其进行测试。请注意,在为新集群选择版本的下拉列表中,我们始终使用最推荐的版本作为所选选项(默认)。
Deadlettering和TTL是rabbitmq中的两个流行功能,应该谨慎使用。TTL和Deadlettering可以产生您没有预料到的性能影响。
使用x-dead-letter-exchange属性声明的队列将向指定的dead-letter-exchange发送被拒绝、非确认或过期(带有ttl)的消息。如果您指定了x-dead-letter-routing-key,则消息的路由键将在deadlettered时更改。
通过使用x-message-ttl属性声明队列,如果消息在指定的时间内未被使用,则将从队列中丢弃消息。
为什么rabbitMQ启动特别慢如果确保不是网络卡的原因导致电脑卡,那么很可能是电脑配置过低。
出现电脑硬件故障一般是硬盘的故障,电脑硬盘中存在不少坏道。
内存质量不佳,应用程序写入内存的数据无法读取会导致卡顿。
多个应用程序在内存地址分配时发生冲突也会导致卡。
用腾讯电脑管家多清理电脑缓存垃圾和用了系统盘瘦身功能,提升电脑运行速度
关于本次rabbitmq启动慢和rabbitmq 启动的问题分享到这里就结束了,如果解决了您的问题,我们非常高兴。