本系列是「RabbitMQ实战:高效部署分布式消息队列」书籍的总结笔记。
前两篇介绍了RabbitMQ在可用性、监控方面的考虑,这是基础保障,因为在某些场景下是不容许丢失消息的,但它和性能往往是对立的,需要根据业务场景做取舍。
当处理一些敏感数据时,比如银行卡信息,需要考虑安全性问题,上一篇总结了数据传输安全方面的知识点,这里就比较好理解了。
通过介绍,你会了解到:
- 对速度的考虑
- 对内存和进程的考虑
- 对安全的考
对速度的考虑
有很多因素影响RabbitMQ投递消息的速度,包括消息持久化、路由算法、绑定数目、以及消息确认策略等,下面分别来介绍。
消息持久化
当发布消息时,需要决定丢失其中的任何消息是否可以接受,如果可以接受,可以将delivery-model设置为1,消息就不会持久化到硬盘了。
消息确认
当消费消息时,可以在队列订阅时,通过设定no-ack标记加快消息投递,如果设置为true,服务器就会在消息发送给客户端后自动将其出队。
这样,处理完消息之后就无须再发送确认消息回服务器了,能极大地加快消费者消费消息,但由于某些原因连接中断了,或客户端应用程序发生故障了,消息就永远消息了。
路由算法和绑定规则
前面介绍了3种类型的交换器:direct、fanout、topic,每种交换器代表了服务器实现的特定路由算法,会根据消息的路由键以及队列与交换器之间的绑定来选择队列。
在服务器端,交换器和绑定作为记录条目存储在Mnesia数据库中,当匹配消息路由键时,会尝试查找对应路由键的绑定。
fanout交换器在路由消息的时候,会忽略路由键,不需要进行查找。direct只有一个绑定,也会比较快,topic存储的路由信息比较复杂,由于路由键可以包含以点分隔的多个词,所以匹配消息路由键不仅仅是简单字符串的匹配,也会占用更多内存。
RabbitMQ实现了trie树数据结构用来存储绑定路由键模式,以支持快速查询,关于这种数据结构,我之前没接触过,据说比桶状哈希表还快,后面专门写一篇介绍这个数据结构吧。
投递消息
在交换器找到消息需要路由的目的地之后,会将目的地列表返回给rabbit_router,之后会将消息的副本投递到每一个目的地,如果发布的消息中mandatory和immediate标记设置为false,这个过程会以异步方式执行,从客户端角度看,服务器会变得很快,否则会同步投递。
当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者,当mandatory设为false时,出现上述情形broker会直接将消息扔掉。
当immediate标志位设置为true时,如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。
假如找到了投递的队列且有消费者准备好接收消息,如果队列为空,消息会直接发送给消费者,不会经过队列这一步,会极大提升速度,所以制定容量规划并计算消息的进出率时,应尽可能让队列保持为空,如果消费滞后导致队列填满的化,服务器会收到内存告警,并将消息刷出磁盘。
还有个参数要注意:auto-ack,消费者接收到消息后,会立刻确认消息,而不用等到逻辑处理好。
以上说的提高速度的方法大部分都会牺牲可用性,要根据不同的业务场景进行平衡。
对内存和进程的考虑
在设计应用程序的时候,会有两个基本限制:选择的技术允许做什么,以及当前硬件设定允许做什么。上面讨论了第一点:不同消息路由和分发算法如何影响设计决策。关于第二点,需要考虑AMQP的元素需要多少内存,以及Erlang VM对可以创建的进程总数的硬件限制。
内存考虑
关于内存占用,书上有详细说明,这里只列出分析结果,供大家在预估容量时参考:(√表示哪些表会为队列声明添加记录)
1.队列元数据
2.交换器元数据
3.绑定元数据
一个持久化队列绑定到一个瞬时交换器会导致在rabbit_semi_durable_router表上创建条目。
Erlang进程计数
可以在节点启动时指定Erlang节点上能运行的最大Erlang进程数,默认设置是每个Erlang节点1048576,即2^20个。
Erlang应用程序在整个生命周期中会多次创建并销毁进程。比如,RabbitMQ接收到AMQP客户端的TCP连接时,会创建一个进程进行管理该连接,同时,会有很多Erlang进程来处理消息存储的逻辑。
主要通过以下事件来增加进程数:到服务器的新连接、创建新的信道以及队列声明。一条新的连接会创建四个新的进程,一个新的通道也会创建四个新的进程,队列的开销最小,每个队列一个进程。
对安全的考虑
有些消息,想以一种安全的方式进行传输,可以使用SSL协议在消息通信终端传输数据,RabbitMQ默认支持SSL,只需要配置相应的证书,使用openssl库进行设置和操作。
关于证书、openssl以及ssl,上一篇文章详细介绍了,现在来看看如何使用。
服务端
只需要修改下rabbitmq的配置即可,在rabbitmq.config中添加ssl_listeners和ssl_options配置项:
[
{rabbit,[
{ssl_listeners, [5671]},
{ssl_options, [
{cacertfile,"/path/to/rmqca/cacert.pem"},
{certfile,"/path/to/server/cert.pem"},
{keyfile,"/path/to/server/key.pem"},
{verify,verify},
{fail_if_no_peer_cert,false}
]}
]}
]
配置中指定了ca的证书,服务端的证书,以及服务端的秘钥。
客户端
require_once(__DIR__ . '/../amqp.inc');
define('HOST', 'localhost');
define('PORT', 5671);
define('USER', 'guest');
define('PASS', 'guest');
define('VHOST', '/');
define('AMQP_DEBUG', true);
define('CERTS_PATH',
'/path/to/ca/folder/');
$ssl_options = array(
'cafile' => CERTS_PATH . '/rmqca/cacert.pem',
'local_cert' => CERTS_PATH . '/phpcert.pem',
'verify_peer' => true
);
$conn = new AMQPSSLConnection(HOST, PORT, USER, PASS, VHOST, $ssl_options);
function shutdown($conn){
$conn->close();
}
register_shutdown_function('shutdown', $conn);
while(1){}
客户端代码指定了ca根证书和客户端证书和秘钥,phpcert.pem是客户端证书、秘钥、ca根证书的合并文件。
$ cat client/key.pem > phpcert.pem
$ cat client/cert.pem >> phpcert.pem
$ cat rmqca/cacert.pem >> phpcert.pem
下一篇会介绍下RabbitMQ的插件,以便自定义插件扩展RabbitMQ功能。
欢迎扫描下方二维码,关注我的个人微信公众号,查看更多文章 ~
相关推荐
**RabbitMQ实战:高效部署分布式消息队列** 在当今的软件开发中,消息队列作为异步处理和系统解耦的重要工具,被广泛应用。RabbitMQ作为一个开源的消息代理和队列服务器,以其稳定性和易用性赢得了广大开发者的好评...
《RabbitMQ实战:高效部署分布式消息队列》是一本专为希望深入理解和应用RabbitMQ的IT从业者准备的指南。RabbitMQ是一款开源的消息代理软件,它在分布式系统中承担着消息中间件的角色,负责处理应用程序之间的通信,...
### RabbitMQ实战:高效部署分布式消息队列 #### 一、引言 随着现代软件架构的不断演进,分布式系统已成为构建复杂应用的基础。在这样的系统中,消息队列作为服务间通信的重要组件,承担着数据传递与解耦的关键...
《RabbitMQ实战高效部署分布式消息队列》这本书籍详细阐述了如何在实际环境中高效地部署和使用RabbitMQ这一流行的消息中间件。RabbitMQ是基于AMQP(Advanced Message Queuing Protocol)协议实现的开源消息队列系统...
随书源码“RabbitMQ实战-随书源码”和“RabbitMQ in action 和 RabbitMQ实战-高效部署分布式消息队列”的配套代码,提供了丰富的示例,帮助读者深入理解RabbitMQ的使用和实践。 1. **RabbitMQ基础** - **AMQP协议*...
RabbitMQ是一款开源的消息队列服务软件,它实现了高级消息队列协议(AMQP),以高性能、健壮和可伸缩性闻名,主要由Erlang语言编写。Erlang是一种适合于构建并发处理能力强、高可用性系统的编程语言,这些特点使得...
【RabbitMQ超简明教程】 RabbitMQ是一个开源的消息代理和队列服务器,基于AMQP(高级消息队列...通过以上步骤,我们可以将RabbitMQ高效地融入到SpringBoot应用中,利用其强大的消息处理能力提升系统的性能和稳定性。
在本文中,我们将深入探讨Netty框架,并通过实战项目——仿写微信IM即时通讯系统,来深入了解其在高性能网络应用中的应用。Netty是Java领域中一个高效的异步事件驱动的网络应用程序框架,它为快速开发可维护的高性能...
《RabbitMQ实战》 RabbitMQ是一种广泛使用的开源消息队列系统,它基于AMQP(Advanced Message Queuing Protocol)协议,提供可靠、灵活的消息传递服务。本实战指南将深入探讨RabbitMQ的核心概念、安装配置、使用...
**RabbitMQ实战:高效部署分布式消息队列** 在当今的互联网应用开发中,分布式系统已经成为常态,而消息队列(Message Queue)作为其中的关键组件,对于系统的解耦、异步处理以及容错能力的提升起到了重要作用。...
《RabbitMQ实战:高效部署分布式消息队列》是一本深度探讨RabbitMQ技术的书籍,旨在帮助读者理解和掌握如何在分布式环境中高效地部署和使用RabbitMQ消息队列。RabbitMQ作为一款广泛使用的开源消息中间件,是实现应用...
**RabbitMQ实战指南知识点总结** RabbitMQ是一款开源的...以上是对《RabbitMQ实战指南》中核心知识点的总结,实际应用中应结合具体业务场景进行设计和优化。学习和理解这些概念有助于构建稳定、高效的RabbitMQ系统。
**RabbitMQ实战资源详解** RabbitMQ是一种广泛使用的开源消息代理和队列服务器,它基于AMQP(Advanced Message Queuing Protocol)协议实现,适用于多种编程语言,如Java、Python、Ruby、C#等。本资源集合包含了...
在 Go 语言中,我们还可以借助第三方库,如 `gin` 或 `echo` 来快速构建 RESTful API,使用 `nsq` 或 `rabbitmq` 实现消息队列,结合 `prometheus` 和 `grafana` 进行监控和报警。此外,`gRPC` 和 Protobuf 可以用于...
8. **安全性**:用户权限控制、虚拟主机和访问控制列表(ACL)是RabbitMQ安全配置的重要部分,防止未经授权的访问。 9. **监控与日志**:了解如何使用RabbitMQ的管理界面和各种工具进行性能监控和故障排查,以及...