`
情情说
  • 浏览: 38881 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

RabbitMQ实战:可用性分析和实现

 
阅读更多

 

本系列是「RabbitMQ实战:高效部署分布式消息队列」书籍的总结笔记。

上一篇介绍了各种场景下的最佳实践,大部分场景可以使用「发后即忘」的模式,不需要响应,如果需要响应,可以使用RabbitMQ的RPC模型。

RabbitMQ以异步的方式解耦系统间的关系,调用者将业务请求发送到Rabbit服务器,就可以返回了,Rabbit会确保请求被正确处理,即使遇到网络异常、Rabbit服务器崩溃、整个机房断电等特殊场景,针对这些场景,Rabbit提供了各种机制确保其可用性。

本篇通过总结可能出现的特殊场景,对Rabbit提供的可用性保证进行分析,学习它的实现方式,你会了解到:

  • 总结异常场景
  • 集群并处理失败
  • 连接丢失和故障转移
  • 主/备方式
  • 跨机房复制

推广下我的个人公众号「情情说」,第一时间分享我的工作、学习和生活,如果对你有帮助,希望可以关注下。

异常场景

在实际工作中,有很大一部分时间用在解决各种异常情况,比如针对用户输入的验证,JDK中提供的各种异常类,网络异常等,这些相对来说比较好解决。

Rabbit服务作为调用者和处理者的桥梁,至关重要,如果因为网络异常、单台服务器崩溃、机房瘫痪等原因导致Rabbit服务不可用,会影响所有依赖的业务系统。

网络异常

处理者和服务端是通过长连接交互的,这样可以将消息实时推送,网络异常可能会导致长连接断开,如果客户端无法感知,处理者将接收不到任何消息,这种情况称为「连接丢失」。

通过捕获连接异常,进行重连,可以解决这种问题,另外,Rabbit客户端进行了封装,很容易处理这种问题。

服务器崩溃

如果只有一台服务器服务,服务器崩溃将导致服务不可用,一般会使用集群将多个服务器看成一个整体对外提供服务,这样,单台服务器崩溃不会影响整体的服务。

使用集群后,就要考虑一些问题:

  • 客户端连接到哪台服务器是随机的,而一个队列只会在某个服务器中,所以,每台服务器都要保存队列元数据(类似索引),并且可从其他服务器获取实际的队列数据;
  • 服务器崩溃,会导致非持久化的队列、交换器丢失,客户端端重连后,要再次进行创建,但未消费的消息将无法恢复;
  • 如果队列、交换器、消息等是持久化的,如何进行恢复呢,Rabbit提供了几种方式进行处理,后面会详细介绍;
  • 订阅者也需要重新建立连接,进行监听;
机房瘫痪

如果考虑机房瘫痪,就要建多个数据中心,RabbitMQ提供了一种机制,可以方便地在不同数据中心的Rabbit间复制消息。

集群并处理失败

RabbitMQ最优秀的功能之一就是其内建集群,主要用于完成2个目标:

  • 允许消费者和生产者在Rabbit节点崩溃的情况下继续运行;
  • 通过添加更多的节点线性扩展消息通信的吞吐量;
集群架构

RabbitMQ会始终记录四种类型的内部元数据(类似索引):

  • 队列元数据:队列名称和它的属性;
  • 交换器元数据:交换器名称、类型和属性;
  • 绑定元数据:一张简单的表格展示了如何将消息路由到队列;
  • vhost元数据:为vhost内的队列、交换器和绑定提供命名空间和安全属性;

当引入集群时,就需要追踪新的元数据类型:集群节点位置,以及节点与已记录的其他类型元数据的关系。

不是每个节点都有所有队列的完全拷贝,如果在集群中创建队列,只会在单个节点上创建完整的队列信息(元数据、状态、内容),所有其他节点只知道队列的元数据和指向该队列的节点指针。

如果节点崩溃了,附加在队列上的消费者也就无法接收新的消息了。可以让消费者重连到集群并重新创建队列,这种做法仅当队列没设置持久化时才可行,这是为了确保当失败的节点恢复后加入集群,节点上的队列消息不会丢失。

为什么不将队列内容和状态复制到所有节点:第一,存储空间,如果每个集群节点都拥有所有队列的完全拷贝,添加新节点不会带来更多存储空间;第二,性能,消息的发布者需要将消息复制到每一个集群节点,对于持久化消息,网络和磁盘复制都会增加。

而交换器只是一张查询表,而非实际的消息路由器,因此将交换器在整个集群中进行复制会更加简单

可以把每个队列想象成节点上运行的进程,每个进程拥有自己的进程ID,交换器只是路由模式列表和匹配消息应发往的队列进程ID列表。

集群架构中的交换器和队列

每个Rabbit节点,要么是内存节点,要么是磁盘节点,单节点系统只运行磁盘类型的节点,在集群中,可以选择配置部分节点为内存节点。

在集群中声明队列、交换器或绑定的时候,这些操作直到所有集群节点都成功提交元数据变更后才返回。

RabbitMQ只要求集群中至少有一个磁盘节点,如果只有一个磁盘节点,刚好又崩溃了,集群可以继续路由消息,但不能创建队列、交换器、绑定、添加用户、更改权限等操作。所以,建议设置两个磁盘节点,当内存节点重启后,会连接到预先配置的磁盘节点,下载当前集群元数据拷贝,所以要将所有磁盘节点告诉内存节点。

镜像队列

前面提到,队列只会在集群中的一个节点,节点崩溃后,队列消息就会丢失,RabbitMQ2.6版本之后,提供了镜像队列,一旦主队列不可用,从队列将被选举为新的主队列。

对于镜像队列,除了将消息按照路由绑定规则投递到合适的队列,也会将消息投递到镜像队列的从拷贝。

对于发送方确认消息,Rabbit会在所有队列和队列的从拷贝安全地接收到消息时,才会通知发送方。

另外,使用镜像队列时,有一个问题:如果主拷贝节点发送故障,从队列会选举Wie主队列,所有该队列的消费者需要重新附加并监听新的队列主拷贝。对于通过故障节点进行连接的消费者,可以通过丢失到节点的TCP连接检测到,但对于那些通过节点附加到镜像队列且正常运行的消费者将无法检测到。

Rabbit通过给消费者发送一个消费者取消通知,告知不再附加在队列主拷贝了,需要重新连接。

连接丢失和故障转移

这一小节主要讨论消费者如何检测连接丢失,并进行重连操作。

处理到集群的重连有多重策略,比较好的一种方式是使用负载均衡,不仅可以减少应用程序处理节点故障代码的复杂性,又能确保在集群中连接的平均分配。

关于负载均衡,网上介绍的比较多了,这里就不再过多介绍了,主要看看如何感知故障,并进行重连操作。

感知故障比较简单,当长连接断开时,会抛出异常,捕获对应的异常即可。

当集群节点出现故障时,应用程序需要考虑:下一个该连向哪里?这个工作已经交由负载均衡器决定。

关于重连处理,要考虑:

  • 如果重连到新的服务器,信道以及其上的所有消费循环都会失效,需要对他们进行重建;
  • 当进行重连时,所有的队列、绑定有可能都不存在了,需要重新构造队列和绑定。

主/备方式

当对可用性要求特别高时,不允许消息丢失,需要将队列、交换器、消息设置成持久化,如果一个节点崩溃了,在恢复之前,将无法转发消息,因为默认的群集架构不允许在集群其他节点创建队列,防止故障节点恢复后,历史消息丢失。

可以通过构建主/备机的独立RabbitMQ,也就是warren模式,解决这个问题。一个warren是指一对主/备独立服务器,并前置一套负载均衡器来处理故障转移。

主服务器和备用服务器之间没有协作,只有当主服务器崩溃时,备用服务器才会处理消息。可以保证,主节点故障后,通过备用节点重新创建队列、交换器继续服务,故障节点恢复后,可以继续消费主节点未消费的消息。

跨机房复制

在只有一个数据中心的时候,RabbitMQ集群对于提升消息通信性能来说是很棒的方案,但需要把消息从一个程序路由到另一个城市的时候,就比较麻烦了,可以通过Shovel解决。

Shovel是RabbitMQ的一个插件,可以使你能够定义RabbitMQ上的队列和另一个RabbitMQ上的交换器之间的复制关系。说白了就是生产者和消费者离得比较远。

通过在机房1创建一个新的队列,用于接收网站发布的消息,然后让shovel消费这些消息并重新将消息通过WAN连接发布到机房2上的交换器。

这样对于用户来说,只要发布到机房1的队列即可返回,减少了响应时间。机房1可以持续将消息发布到机房2上。

Shovel处理过程

通过上面的介绍可以看到,保证高可用需要做很多工作,可以根据业务对可用性的要求,选择不同的架构方式。

下一篇重点介绍RabbitMQ管理界面和监控。

欢迎扫描下方二维码,关注我的个人微信公众号 ~

 


情情说

 

 

0
0
分享到:
评论

相关推荐

    RabbitMQ实战:高效部署分布式消息队列 pdf版

    - **集群模式**:实现RabbitMQ的高可用性和负载均衡,提高服务的可靠性。 - **镜像队列**:数据复制和故障转移,确保消息的持久性和一致性。 - **网络分区处理**:了解和处理网络分区(Network Partition)情况下的...

    RabbitMQ实战 高效部署分布式消息队列 带目录 高清版 PDF

    同时,会涉及集群(Cluster)和高可用性(High Availability)的设置,通过创建RabbitMQ集群,可以实现多节点之间的数据同步,确保服务的连续性。 此外,结合Java开发,书里将展示如何使用RabbitMQ的Java客户端库...

    RabbitMQ实战 高效部署分布式消息队列 PDF下载

    6. **高可用性**:RabbitMQ支持集群模式,允许多个节点组成一个集群,提供故障转移和负载均衡能力。此外,通过镜像队列,可以实现队列级别的数据冗余和高可用。 7. **持久化与可靠性**:RabbitMQ支持消息和队列的...

    RabbitMQ实战:高效部署分布式消息队列 带目录书签高清PDF

    RabbitMQ作为业界广泛使用的开源消息代理,它提供了可靠的消息传递机制,是构建微服务、解耦系统和实现异步处理的关键组件。下面,我们将深入讲解RabbitMQ的核心概念、关键功能以及在分布式环境中的应用策略。 一、...

    RabbitMQ实战:高效部署分布式消息队列

    《RabbitMQ实战:高效部署分布式消息队列》是一本深度解析RabbitMQ技术的书籍,旨在帮助读者理解和掌握如何在实际环境中有效地部署和利用分布式消息队列。RabbitMQ作为一个开源的消息代理和队列服务器,是实现异步...

    RabbitMQ实战 高效部署分布式消息队列pdf

    - **集群搭建**:通过多台服务器构建RabbitMQ集群,实现高可用性和故障转移。 5. **分布式消息队列** - **分布式消息队列的优势**:提高系统性能,通过异步处理减轻后端服务压力;增强系统容错性,消息持久化避免...

    RabbitMQ实战 高效部署分布式消息队列

    - 集群部署:多个RabbitMQ节点组成一个集群,提供高可用性和数据冗余,当一个节点故障时,其他节点可以接管服务。 - 镜像队列:队列的数据在集群中的所有节点上都存在,确保消息不丢失。 - Federation和Shovel:...

    RabbitMQ实战高效部署分布式消息队列

    《RabbitMQ实战高效部署分布式消息队列》这本书籍详细阐述了如何在实际环境中高效地部署和使用RabbitMQ这一流行的消息中间件。RabbitMQ是基于AMQP(Advanced Message Queuing Protocol)协议实现的开源消息队列系统...

    RabbitMQ实战指南-rabbitmq-action.zip

    通过学习RabbitMQ实战指南,你可以掌握如何在实际项目中运用RabbitMQ,实现高效、可靠的异步通信,提升系统的稳定性和可扩展性。在实践中,结合具体的业务场景,灵活运用上述知识,将有助于构建出更加健壮的分布式...

    RabbitMQ实战 高效部署分布式消息队列.pdf

    - **监控与日志收集**:通过RabbitMQ收集系统日志,进行集中分析和报警。 7. **最佳实践与性能优化** - **消息设计**:如何合理设计消息结构,提高处理效率。 - **资源管理**:队列长度控制、内存使用优化、磁盘...

    RabbitMQ实战-随书源码

    - **节点与集群**:RabbitMQ服务器可以单机运行,也可以组建集群,实现高可用性和负载均衡。 - **Exchange**:消息的路由中心,根据预设的绑定规则将消息分发到相应的队列。 - **Queue**:消息的存储容器,消费者...

    RabbitMQ实战高效部署分布式消息队列.pdf+rabbitmq学习手册.pdf

    - **高可用性**:通过集群和镜像队列实现跨节点的数据复制,确保服务的连续性。 - **多种协议支持**:除了AMQP外,还支持STOMP、MQTT等多种消息协议。 - **多语言客户端**:提供了丰富的编程语言客户端,包括Java...

    RabbitMQ实战.高效部署分布式消息队列.rar

    3. **日志收集**:集中收集各个服务的日志,便于分析和故障排查。 4. **事件驱动**:实现事件驱动架构,如订单处理、支付通知等。 5. **流处理**:构建实时数据流处理系统,如实时分析、数据清洗。 综上所述,...

    RabbitMQ实战带目录版本

    5. **高可用性**:通过集群和镜像队列来实现RabbitMQ的高可用性,确保服务的连续性。 通过深入学习并实践本书中的内容,读者将能够熟练掌握RabbitMQ的使用,将其应用于各种分布式系统中,解决异步通信、解耦系统、...

    rabbitMQ实战java版-rabbitMQ-demo.zip

    《RabbitMQ实战Java版——基于rabbitMQ-demo.zip的详解》 在当今的分布式系统中,消息队列作为异步处理、解耦组件的关键技术,得到了广泛应用。RabbitMQ作为一款开源的消息代理和队列服务器,以其稳定性和易用性...

    RabbitMQ实战pdf高清

    - **集群模式**:通过创建RabbitMQ集群,可以实现数据的冗余备份和负载均衡,提高服务的可用性和可靠性。 - **持久化**:启用消息持久化,即使服务器重启,消息也不会丢失。 - **镜像队列**:主队列和镜像队列之间的...

    RabbitMQ实战 高效部署分布式消息队列(高清带标签)

    通过集群和镜像队列,可以实现高可用性和数据一致性。集群能够扩展RabbitMQ的处理能力,镜像队列则提供了主备复制,保证即使节点故障,服务也能不间断。 最后,书中还会涉及RabbitMQ与其他系统的集成,如Spring框架...

Global site tag (gtag.js) - Google Analytics