Mq的一些理解和思考

130 阅读3分钟

消息队列(Mq)是在消息的传输过程中保存消息的容器,主要用于业务的异步处理、解耦和流量削峰。Mq由Publisher(生产者),Broker(代理),Cousmer(消费者)组成,以实现消息的生产、路由转发、存储和消费。为保证了Mq的高可用性,针对Mq的结构,提出了各种机制。

1. Mq的组成

Mq主要由Publisher、Broker、Cousmer组成,其中Broker是Mq的核心部分,由交换机与队列组成。Publisher生产并传递消息给交换机,交换机依据routing-key进行路由与转发,向队列发送信息,队列存储消息,Cousmer通过监听队列中的消息进行消费。 exchange通过对消息进行路由与转发,在Mq中起着承上启下的作用。exchange有三种模式,分别为Fanout、Direct、Topic。Fanout广播模式,会向绑定该交换机的队列转发消息;Direct定向模式,会向指定的routing-key的队列发送消息;Topic组播模式,会向一组队列发送消息。

2. Mq的高可用性

Publisher的可靠性需要保证Publisher可以连接上Broker,并能够通过交换机路由到指定的队列中;Broker的可靠性需要保证数据持久化;Cousmer的可靠性需要保证Cousmer一定能够接收消息并及时反馈,并需要保证业务幂等性。

2.1 Publisher的可靠性

Publisher的可靠性通过重连和确认机制保证

  • 通过配置Publisher重连机制,保证能够及时连接Mq。
  • 依靠Publisher的确认机制,通过发送ack与nack消息,保证Publisher的消息能够到达队列中。
2.2 Broker的可靠性

Broker的可靠性通过持久化机制,保证交换机、队列和数据不丢失。 Mq为了保证性能,将数据存储到内存中,当内存空间不够时就会触发PageOut,线程阻塞并将部分数据存储至磁盘中,严重影响性能,且系统宕机后数据丢失。

  • 通过持久化,将消息在内存和磁盘中都存储一份,有效解决了上述问题,但是仍然存在性能问题。
  • Mq提出的LazyQueue机制,直接存储到磁盘而非内存,Cousmer需要消息时再放入内存,并通过一系列优化机制保证性能。
2.3 Consumer的可靠性

Cousmer的可靠性通过确认机制和失败处理策略,保证数据能且只能被Cousmer消费一次的同时,设置失败处理机制,避免消息重复入队给Mq带来不必要的压力,最后,还要求程序员在业务代码层面能够保证业务幂等性,以防止重复消费消息导致的问题。

  • 确认机制通过ack、nack、reject三种方式向队列提供反馈。
  • 设置失败处理策略RepublishMessageRecoverer,当消息多次投递失败后进入消息error-queue,由人工进行处理。
  • 当网络出现故障时,会出现重复消费的问题。为了解决这个问题,就需要再业务层面保证幂等性,保证即使重复消费消息,也不会对最终的结果。

3.Mq的拓展性

依靠Broker的特性可以实现延迟消息:故意不消费消息,等消息到达过期时间后进入指定的死信交换机,最后被指定的消费者消费。 延迟消息在撤销订单中有较为广阔的应用,可以阻止频繁查询数据库导致的压力激增问题。 但是延迟消息会导致消息堆积的问题出现,所以只能够在较小的时间延迟中使用,在设计时可以采用时间分片的方式缓解问题。