我撸了一套RabbitMQ的客户端
,其实还是因为 RabbitMQ 客户端的使用有很多的注意事项,稍微不注意,就容易翻车。 我是 2013 年就开始用起了 RabbitMQ,一路使用,一路和它一起成长。当时,由于用的早,市面上也没有特别成熟的 RabbitMQ 客户端框架。所以,不得已之下,只好自己做了一套客户端。 在这其中,正好也有了许多独特的经验也和大家分享一下,以免后来者陷入“后人哀之而不鉴之,亦使后人而复哀后人也”的套娃中。 一、那么,就先从网络连接开始吧 1. 应该长久生存的连接 在 RabbitMQ 中,由于需要客户端和服务器端进行握手,所以导致客户端和服务器端的连接如果要成功创建,需要很高的成本。 每一个连接的创建至少需要 7 个 TCP 包,这还只是普通连接。如果需要 TLS 的参与,则 TCP 包会更多。 而且,RabbitMQ 中主要是以 Channel 方式通信,所以,每次创建完 Connection 网络连接,还得创建 Channel,这又需要 2 个 TCP 包。 如果,每次用完,再把连接关闭,首先还要关闭已经创建的 Channel,这也需要 2 个 TCP 包。 然后,再关闭已经建立好的 Connection 连接,又需要 2 个 TCP 包。 咱们算算,如果一个连接从创建到关闭,一共需要多少个 TCP 包? 7 + 2 + 2 + 2 = 13 一共需要 13 个包。这个成本是很昂贵的。 所以,在 RabbitMQ 中,连接最好缓存起来,重复使用更好。 2. Channel 还是独占好 在 RabbitMQ 自己的客户端中,Channel 出于性能原因,并不是线程安全的。 而如果咱们为了线程共用,给 Channel 人为的在外部加上锁,本身就和 RabbitMQ 的 Channel 设计意图是冲突的。 所以,最好的办法就是一个线程一个 Channel。 3. Channel 最好也别关 就像连接应该缓存起来那样,Channel 的打开和关闭也需要时间成本,而且没有必要去重新创建 Channel,所以,Channel 也应该缓存起来重用。 4. 别把消费和发送的连接搞在一起 把消费和发送的连接搞在一起,这是个很容易犯的错误! 我们用 RabbitMQ 的时候,我们自己的系统本身大部分都是既要发消息也要收消息的。对于这种情况,有很多程序员走了极端: 他们觉得 RabbitMQ 连接成本高,所以省着用。于是就把发消息和收消息的连接混在一起,使用同一个 TCP 连接。 这很可能会埋一个大雷。 因为,当我们发消息很频繁的时候,我们收消息也是走的同一个 TCP 通道,收完了消息,客户端还要给 RabbitMQ 服务器端一个 ACK。 RabbitMQ 服务器端,对于每个 TCP 连接都会分配专门的进程,如果遇到这个进程繁忙,这个 ACK 很可能被丢弃,又或者等待处理的时间过长。而这种情况又会导致 RabbitMQ 中的未确认消息会被堆积的越来越多,影响到整套系统。 所以,消费和发送的连接必须分开,各干各的事情。 5. 别搞太多连接和 Channel,RabbitMQ 的 Web 受不了 RabbitMQ 的 Web 插件会收集很多连接,和其对应 Channel 的相关数据。
如果连接和 Channel 堆积太多了,整个 Web 打开会非常慢,几乎无法对 RabbitMQ 进行管理。所以,要注意限制连接和 Channel 的数量。 (编辑:济南站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |