rabbitMq基础概念,解决消息丢失问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/c_royi/article/details/86630777

rabbitMq基础概念

为啥使用rabbitmq

  如果使用Socket,那么不同的模块的确可以部署到不同的机器上,但是还是有很多问题需要解决。比如:

  1. 信息的发送者和接收者如何维持这个连接,如果一方的连接中断,这期间的数据是以什么方式丢失?
  2. 如何降低发送者和接收者的耦合度?
  3. 如何让Priority高的接收者先接到数据?
  4. 如何做到Load Balance?有效均衡接收者的负载?
  5. 如何有效的将数据发送到相关的接收者?也就是说将接收者subscribe 不同的数据,如何做有效的filter。
  6. 如何做到可扩展,甚至将这个通信模块发到cluster上?
  7. 如何保证接收者接收到了完整,正确的数据?

  AMQP协议解决了以上的问题,而RabbitMQ实现了AMQP

基础概念解析

在这里插入图片描述

  1. Publisher 消息的生产者,发布消息的客户端应用程序
  2. Exchange 交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列
  3. Binding 绑定,用于消息队列和交换器之间的关联。绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
  4. Queue 消息队列,用来保存消息直到发送给消费者。消息的容器
  5. Connection 网络连接,建立tcp连接
  6. Channel信道,多路复用连接中的一条独立的双向数据流通道。信道是建立在真实的TCP连接内地虚拟连接,AMQP 命令都是通过信道发出去的,不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁 TCP
    都是非常昂贵的开销,所以引入了信道的概念,以复用一条 TCP 连接。
  7. Consumer 消息的消费者,
  8. Virtual Host 虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同的身份认证和加密环境的独立服务器域。每个 vhost 本质上就是一个 mini 版的 RabbitMQ 服务器,拥有自己的队列、交换器、绑定和权限机制
  9. Broker 表示消息队列服务器实体

  由Exchange、Queue、RoutingKey三个才能决定一个从Exchange到Queue的唯一的线路

rabbitmq与activemq的区别

rabbitmq:AMQP 中增加了 Exchange 和 Binding 的角色。生产者把消息发布到 Exchange 上
在这里插入图片描述

exchange类型
  • direct交换器:消息中的路由键(routing key)如果和 Binding 中的 binding key 一致, 交换器就将消息发到对应的队列中。路由键与队列名完全匹配才行
  • fanout交换器:每个发到 fanout 类型交换器的消息都会分到所有绑定的队列,相当于广播
  • topic交换器:通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,符号“#”和符号“*”。#匹配0个或多个单词,*匹配不多不少一个单词。
  • headers交换器(不重要) :headers 匹配 AMQP 消息的 header 而不是路由键,此外 headers 交换器和 direct 交换器完全一致,但性能差很多,目前几乎用不到了

消息丢失问题

  问题1:在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其他意外)的情况
  解决:可以要求消费者在消费完消息后发送一个回执给RabbitMQ,RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移除。如果RabbitMQ没有收到回执并检测到消费者的RabbitMQ连接断开,则RabbitMQ会将该消息发送给其他消费者(如果存在多个消费者)进行处理。这里不存在timeout,一个消费者处理消息时间再长也不会导致该消息被发送给其他消费者


  问题2:RabbitMQ服务重启时,丢失消息
  解决:可以将Queue与Message都设置为可持久化的(durable),这样可以保证绝大部分情况下我们的RabbitMQ消息不会丢失。但依然解决不了小概率丢失事件的发生(比如RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时RabbitMQ服务器就断电了),如果我们需要对这种小概率事件也要管理起来,那么我们要用到事务。


  问题3:多个消费者同时订阅同一个Queue中的消息,Queue中的消息会被平摊给多个消费者。当每个消息的处理时间不同,就有可能会导致某些消费者一直在忙。
  解决:通过设置Prefetch count来限制Queue每次发送给每个消费者的消息数,譬如设置prefetchCount=1,当消费者处理完一条信息后,才发送下一条

猜你喜欢

转载自blog.csdn.net/c_royi/article/details/86630777