本博文件详细的介绍RabbitMQ的消息追踪和均衡负载的相关的原理。
消息追踪在使用任何消息中间件的过程中,难免会出现消息异常丢失的情况。对于RabbitMQ 而言,可能是生产者与Broker断开了连接并且也没有任何重试机制;也可能是消费者在处理消息时发生了异常,不过却提前进行了ack; 甚至是交换器并没有与任何队列进行绑定,生产者感知不到或者没有采取相应的措施;另外RabbitMQ 本身的集群策略也可能导致消息的丢失。这个时候就需要有一个良好的机制来跟踪记录消息的投递过程,以此协助开发或者运维人员快速地定位问题。
Firehose在RabbitMQ 中可以使用Firehose功能来实现消息追踪,Firehose 可以记录每一次发送或者消费消息的记录,方便RabbitMQ 的使用者进行调试、排错等。
Firehose的原理是将生产者投递给RabbitMQ的消息,或者RabbitMQ 投递给消费者的消息按照指定的格式发送到默认的交换器上。这个默认的交换器的名称为amq.rabbitmq.trace,它是一个topic 类型的交换器。发送到这个交换器上的消息的路由键为publish.{exchangenamel}和deliver.{queuename}。其中exchangename 和queuename 为交换器和队列的名称,分别对应生产者投递到交换器的消息和消费者从队列中获取的消息。
开启Firehose 命令: rabbitmqctl trace_on [-p vhost] 。其中[-p vhost] 是可选参数,用来指定虚拟主机vhost。对应的关闭命令为rabbitmqctl trace off [-p vhost] 。Firehose 默认情况下处于关闭状态,并且Firehose 的状态也是非持久化的,会在RabbitMQ 服务重启的时候还原成默认的状态。Firehose 开启之后多少会影响RabbitMQ 整体服务的性能,因为它会引起额外的消息生成、路由和存储。
在Firehose 开启状态下, 当有客户端发送或者消费消息时, Firehose 会自动封装相应的消息体,并添加详细的headers 属性。对于前面的将" 位ace test pay load. "这条消息发送到交换器exchange 来说, Firehore 会将其封装成如图11-2 中所示的内容。
在消费queue 时, 会将这条消息封装成如图11-3 中所示的内容:
rabbitrnq_tracing 插件相当于Firehose 的GUI 版本, 它同样能跟踪RabbitMQ 中消息的流入流出情况。rabbitrnq tracing 插件同样会对流入流出的消息进行封装, 然后将封装后的消息日志存入相应的trace 文件之中。
面对大量业务访问、高并发请求,可以使用高性能的服务器来提升RabbitMQ 服务的负载能力。当单机容量达到极限时,可以采取集群的策略来对负载能力做进一步的提升,但这里还存在一个负载不均衡的问题。试想如果一个集群中有3 个节点,那么所有的客户端都与其中的单个节点nodel 建立TCP 连接,那么nodel 的网络负载必然会大大增加而显得难以承受,其他节点又由于没有那么多的负载而造成硬件资源的浪费,所以负载均衡显得尤为重要。
对于RabbitMQ 而言,客户端与集群建立的TCP 连接不是与集群中所有的节点建立连接,而是挑选其中一个节点建立连接。如图11-10 所示,在引入了负载均衡之后,各个客户端的连接可以分摊到集群的各个节点之中,进而避免了前面所讨论的缺陷。
负载均衡(Load balance ) 是一种计算机网络技术,用于在多个计算机(计算机集群)、网络连接、CPU、磁盘驱动器或其他资源中分配负载,以达到最佳资源使用、最大化吞吐率、最小响应时间及避免过载的目的。使用带有负载均衡的多个服务器组件,取代单一的组件,可以通过冗余提高可靠性。负载均衡通常分为软件负载均衡和硬件负载均衡两种。
软件负载均衡是指在一个或者多个交互的网络系统中的多台服务器上安装一个或多个相应的负载均衡软件来实现的一种均衡负载技术。软件可以很方便地安装在服务器上,并且实现一定的均衡负载功能。软件负载均衡技术配置简单、操作也方便,最重要的是成本很低。
硬件负载均衡是指在多台服务器间安装相应的负载均衡设备,也就是负载均衡器(如F5 )来完成均衡负载技术,与软件负载均衡技术相比,能达到更好的负载均衡效果。由于硬件负载均衡技术需要额外增加负载均衡器,成本比较高,所以适用于流量高的大型网站系统。
这里主要讨论的是如何有效地对RabbitMQ 集群使用软件负载均衡技术,目前主流的方式有在客户端内部实现负载均衡,或者使用HAProxy 、LVS 等负载均衡软件来实现。
客户端内部实现负载均衡对于RabbitMQ 而言可以在客户端连接时简单地使用负载均衡算法来实现负载均衡。负载均衡算法有很多种,主流的有以下几种。
1.轮训算法将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器, 而不关心服务器实际的连接数和当前的系统负载。
2.加权轮询法不同的后端服务器的配置可能和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请求;而配置低、负载高的集群,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序和权重分配到后端。
3.随机法通过随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。
4.加权随机法与加权轮询法一样,加权随机法也根据后端机器的配置、系统的负载分配不同权重。不同的是,它按照权重随机请求后端服务器,而非顺序。
5.源地址后希法源地址哈希的思想是根据获取的客户端IP 地址,通过啥希函数计算得到面一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客户端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP 地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。
6 . 最小连接数法最小连接数算法比较灵活和智能, 由于后端服务器的配置不尽相同,对于请求的处理有块 有慢,它根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器 来处理当前的请求,尽可能地提高后端服务的利用效率,将负载合理地分流到每一台服务器。
使用HAProxy 实现负载均衡HAProxy 提供高可用性、负载均衡及基于TCP 和HTTP 应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案,包括Twitter、Reddit 、StackOverflow 、GitHub 在内的多家知名互联网公司在使用。HAProxy 实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。自行做好相关的配置文件。
试想如果前面配置的HAProxy 主机192.168.0.9 突然岩机或者网卡失效,那么虽然RabbitMQ集群没有任何故障,但是对于外界的客户端来说所有的连接都会被断开, 结果将是灾难性的。确保负载均衡服务的可靠性同样显得十分重要。这里就需要引入Keepalived 工具, 它能够通过自身健康检查、资源接管功能做高可用(双机热备),实现故障转移。
Keepalived 采用VRRP(Virtual Router Redundancy Protocol,虚拟路由冗余协议)以软件的形式实现服务的热备功能。通常情况下是将两台Linux 服务器组成一个热备组(Master 和Backup ) ,同一时间内热备组只有一台主服务器Master 提供服务,同时Master 会虚拟出一个公用的虚拟E 地址,简称VIP。这个VIP 只存在于Master 上并对外提供服务。如果Keepalived检测到Master 宿机或者服务故障,备份服务器Backup 会自动接管VIP 并成为Master , Keepalived将原Master 从热备组中移除。当原Master 恢复后,会自动加入到热备组,默认再抢占成为Master ,起到故障转移的功能。
整条调用链路为:客户端通过VIP 建立通信链路; 通信链路通过Keeaplived 的Master 节点路由到对应的HAProxy 之上;HAProxy 通过负载均衡算法将负载分发到集群中的各个节点之上。正常情况下客户端的连接通过图11-1 2 中左侧部分进行负载分发。当Keepalived 的Master 节点挂掉或者HAProxy 挂掉无法恢复时, B ackup 提升为Master , 客户端的连接通过图11-1 2 中右侧部分进行负载分发。
使用Keepalived+LVS 实现负载均衡负载均衡的方案有很多,适合RabbitMQ 使用的除HAProxy 外还有LVSoLVS 是Linux Virtual Server 的简称,也就是Linux 虚拟服务器,是一个由章文嚣博士发起的自由软件项目,它的官方站点是www.linuxvirtualserver.org 。现在LVS 己经是Linux 标准内核的一部分,在Linux2.6 .32内核以前,使用LVS 时必须要重新编译内核以支持LVS 功能模块,但是从Linux2.6 .32 内核以后,己经完全内置了LVS 的各个功能模块,无须给内核打任何补丁,可以直接使用LVS 提供的各种功能。
LVS 是4 层负载均衡,也就是说建立在OSI 模型的传输层之上。LVS 支持TCP用DP 的负载均衡,相对于其他高层负载均衡的解决方案,比如DNS 域名轮流解析、应用层负载的调度、客户端的调度等,它是非常高效的。LVS 自从1998 年开始,发展到现在己经是一个比较成熟的技术项目了。可以利用LVS 技术实现高可伸缩的、高可用的网络服务。例如, www 服务、Cache服务、DNS 服务、FTP 服务、MAIL 服务、视频/音频点播服务等。有许多比较著名网站和组织都在使用LVS 架设的集群系统。例如, Linux 的门户网站( www.linux.com) 、向ReaIPlayer 提供音频视频服务而闻名的Real 公司( www.real. com) 、全球最大的开源网站( sourceforge.net) 等。
LVS 主要由3 部分组成。
负载调度器(Load BalancerlD irector): 它是整个集群对外面的前端机,负责将客户的请求发送到一组服务器上执行,而客户认为服务是来自一个E 地址(VIP) 上的。
服务器池(Server PooIJRealServer): 一组真正执行客户端请求的服务器,如RabbitMQ服务器。
共享存储(Shared Storage ) : 它为服务器池提供一个共事的存储区,这样很容易使服务器池拥有相同的内容,提供相同的服务。
目前LVS 的负载均衡方式也分为三种
- VS/NAT: Vi阳al Se凹er via Network Address Translation 的简称。VS/NAT 是一种最简单的方式,所有的RealServer 只需要将自己的网关指向Director 即可。客户端可以是任意的操作系统,但此方式下一个Director 能够带动的RealServer 比较有限。
- 今VSITUN: Virtual Server via IP Tunneling 的简称。E 隧道( IP 刊nneling ) 是将一个IP报文封装再另一个IP 报文的技术,这可以使目标为一个IP 地址的数据报文能够被封装和转发到另一个IP地址。IP 隧道技术也可以称之为IP 封装技术(IP encapsulation ) 。
- VSIDR: 即Virtual Server via Direct Routing 的简称。VSIDR 方式是通过改写报文中的MAC 地址部分来实现的。Director 和RealServer 必须在物理上有一个网卡通过不间断的局域网相连。RealServer 上绑定的VIP 配置在各自Non-ARP 的网络设备上(如10 或tunl) , Director 的VIP 地址对外可见,而RealServer 的VIP 对外是不可见的。RealServer的地址既可以是内部地址,也可以是真实地址。
是RabbitMQ 的两个扩展:消息追踪和负载均衡。消息追踪可以有效地定位消息丢失的问题: 是在发送端,还是在服务端, 又或者是在消费端?消息追踪主要包含Firehose和rabb工tmq_tracing 插件,任意开启一个都会耗费服务器的性能。有资料表明在开启Firehose (或rabbi t mq tracing 插件〉时,临界情况能耗费服务器性能的3 0%~40% ,故不适合在正常运行环境中使用,只是作为一个扩展功能方便在遇到问题时复现后的定位。负载均衡本身属于运维层面,将此剥离出第7 章的运维范畴是因为本书前面所有篇幅都在介绍RabbitMQ 本身的功能,而这里的负载均衡指的是服务端入站连接的负载均衡, 一般需要借助第三方工具一-HAProxy 、Keepalived 和LVS 来实现,故视作扩展之用。有关RabbitMQ 的扩展还可以包含Spring 与RabbitMQ 的整合、Storm 与RabbitMQ 的整合等,由于篇幅所限,这里就不多做介绍,有兴趣的读者可以自行查阅相关资料。
博文参考