1. 消息队列 RabbitMQ
消息队列是一种在应用程序之间发送和接收消息的方法,可以实现异步通信、解耦应用、提高系统性能等效果。RabbitMQ 是一款常用的开源消息中间件,它实现了 AMQP 协议规范,并提供了可靠性、灵活性、易用性等优秀特性。本文将介绍 RabbitMQ 的特点、工作模式、延迟队列和消息可靠性等方面的内容。
2. 特性
RabbitMQ 最突出的特点是可靠性和扩展性。具体来说,RabbitMQ 提供了如下特性:
-
可靠性:确定性传输、持久化机制、生产者确认、消费者确认、事务机制等,确保消息传递的可靠性。
-
灵活性:支持多种消息类型和传输模式、可根据需求选择不同的路由策略、支持集群部署、横向扩展等,满足不同场景的应用需求。
-
易用性:提供了简单易用的 API 接口、交换机、队列和路由等功能模块、丰富的插件和工具支持,便于开发人员上手使用。
3. 工作模式
RabbitMQ 支持多种工作模式,常见的有点对点、工作、发布订阅、路由和主题等。
-
点对点模式(Point-to-Point):消息发送方将消息发送到队列中,接收方从队列中取出消息并处理,一个消息只能被一个消费者接收。优点是简单可靠,缺点是无法广播消息。
-
工作模式(Work Queues):一个消息被多个消费者同时消费,每个消费者消费一个消息后,该消息就被标记为“已消费”,其他消费者不会再次处理该消息。优点是提高了消息处理的并发性,缺点是无法对消息进行广播。
-
发布订阅模式(Publish/Subscribe):在该模式下,消息发送方将消息发送到交换机中,订阅了该交换机的所有队列都会接收到该消息。优点是可以广播消息,缺点是无法保证消息传递的顺序。
-
路由模式Routing:在该模式下,发送方将消息发送到指定的交换机中,而接收方则只接收满足特定条件(通过路由键标识)的消息。优点是可以针对特定条件进行过滤,缺点是需要对路由键进行配置,不够灵活。
-
主题模式(Topic):主题模式是路由模式的扩展,可以使用通配符进行路由键的匹配。优点是支持更灵活的条件过滤,缺点是需要进行复杂的路由键配置。
RabbitMQ安装可以参考我的另一篇博客:
Linux安装RabbitMQ_源末coco的博客-CSDN博客进入erlang安装目录下的bin,erlang安装到了 /usr/local/erlang下。只要没提示 bash: erl: command not found... 就是安装成功了。创建/opt/rabbitmq目录,进入该目录。查看是否安装成功:任意位置输入erl。注意:防火墙放行对应的端口15672。下载比较慢,建议从本地上传。需要先解压成tar包再解压。https://blog.csdn.net/weixin_58724261/article/details/131235062
4. 延迟队列
RabbitMQ 延迟队列是指将消息先放入队列中,但是并不立即消费该消息,而是在一定时间后再进行消费的队列。延迟队列可以用来解决某些需要经过一段时间才能处理的任务,例如超时未支付订单的关闭、定时发送消息等场景。
在 RabbitMQ 中实现延迟队列有多种方法,比如使用 RabbitMQ 自带的插件 rabbitmq_delayed_message_exchange,或者结合 TTL 和死信队列来实现。
延迟队列的应用场景比较广泛,以下是几个典型的场景:
-
超时未支付订单的关闭
在某些电商网站中,如果用户下单后一段时间内没有完成支付,系统会自动取消该订单。这种场景可以使用延迟队列来实现。当用户下单时,系统将该订单的信息发送到延迟队列中,设置一定的延迟时间,如果在延迟期间用户还未支付,则系统自动关闭该订单。
-
定时发送消息
在某些场景下,需要在一定时间后向用户发送消息,比如提醒用户进行缴费、发送定期报告等。这种场景可以使用延迟队列,将消息先存储在队列中,设置一定的延迟时间,到达指定的时间后再将消息发送给用户。
-
秒杀活动的处理
在秒杀活动中,大量用户同时抢购某种商品,如果系统一下子将所有订单信息发送给 RabbitMQ,可能会导致系统瘫痪。这时可以使用延迟队列,设置一定的延迟时间,逐步将订单信息发送到 RabbitMQ 中,避免一次性突发的流量压垮系统。
TTl和死信队列原理:
在 RabbitMQ 中,可以为队列设置 TTL。当消息达到设置的 TTL 时,RabbitMQ 会自动将其标记为过期并从队列中删除,并添加到死信交换机DLX中,死信交换机和普通交换机没有区别,它会将私信发送到私信队列中,消费者只需要消费死信队列中的消息。
RabbitMQ配置工作模式可以参考我的另一篇博客:
RabbitMQ配置工作模式_源末coco的博客-CSDN博客以上是简单模式和工作模式,工作模式只需要创建多个消费者即可。消费者只需要消费对应队列即可。https://blog.csdn.net/weixin_58724261/article/details/131235268
5. 消息可靠性
Rabbit提供消息确认机制、return、消费者手动ACK机制确保消息的可靠性
-
消息确认:
当消费提供者将消息发送到交换机时,交换机会对消费提供者进行反馈。
-
return:
当交换机把消息分发到队列后,会将分发的结果反馈给消息提供者。
-
消费者手动ACK:
消费者正常处理完消息后手动确认已消费,如果处理过程出现故障则不确认,此时消息会回到队列中,然后将故障信息记录日志。
RabbitMQ消费端的确认机制分为3种:none、manual、auto(默认)
none:
表示没有任何应答会被发送。
manual:
表示监听者必须通过调用channel.basicAck()来告知消息被处理。
- channel.basicAck(long,boolean):确认收到消息,消息将从队列中被移除,为false时只确认当前一个消费者收到的消息,为true时确认所有消费者收到的消息。
- channel.basicNack(long,boolean,boolean):确认没有收到消息,第一个boolean表示是一个消费者还是所有的消费者,第二个boolean表示消息是否重新回到队列,为true时表示重新入队。
- channel.basicReject(long,boolean):拒绝消息,requeue=false表示消息不再重新入队,如果配置了死信队列,则消息进入死信队列。消息重回队列时,该消息不会回到队列尾部,仍在队列头部,这时消费者又会接收到这条消息,如果想让消息进入队列尾部,需确认消息后再次发送消息。
auto:
表示自动应答,除非MessageListener(消费者)抛出异常,这是默认配置方式。
- 如果消息成功处理,则自动确认。
- 当发生异常抛出AmqpRejectAndDontRequeueException时,则消息会被拒绝且不重新进入队列。
- 当发生异常抛出ImmediateAcknowledgeAmqpException时,则消费者会被确认。
- 当抛出其他的异常时,则消息会被拒绝,且requeue=true时会发生死循环,可以通过setDefaultRequeueRejected(默认是true)设置抛弃消息。