【Rabbitmq消息队列】

本文详细介绍了RabbitMQ,包括其工作模式:点对点和发布订阅模型,以及消息队列在解决消息不丢失、异步处理、应用解耦、流量削峰等问题上的应用。同时探讨了消息的事务支持、持久化和高可用性策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

01 RabbitMQ介绍

MQ:
	消息队列;

RabbitMQ:
	MQ的框架消息队列系统,实现消息的发送和接收,一种消息代理和队列的服务器;
	
AMQP(Advanced Message Queuing Protocol):
    高级消息队列协议。提供统一消息服务的应用层标准高级消息队列,是应用层协议的一个开放标准,为面向消息的中间件设计;
    
AMQP的主要特征是:
    面向消息、队列、路由、安全性、可靠。
    

02 工作模式
在这里插入图片描述

消息:
    包括两个部分:有效载荷(你想要传输的数据)和标签(描述有效载荷,并决定了谁将获取消息);
	
生产者(消费者):
   	发送消息到消息队列;
   		
消费者:
    从消息队列接收消息;
    	
队列:
    存储着即将被消费的消息, 在创建队列时,要指定队列名称;
    	
交换机交换机和队列:
    持久化:将交换机和队列的数据保存在磁盘上,服务器重启或宕机之后仍然存在;
    非持久化:将交换机和队列的数据保存在内存上,服务器重启或宕机后不存在(性能高于持久化);


在这里插入图片描述

根据需求来确定是否需要持久化,上图可以看出,针对每一种交换机有不同的type。
	
	交换机的类型:
        默认交换机
        直连交换机(direct)
        主题交换机(topic)
        头交换机(headers)
        扇形交换机(fanout)

	消息确认:
    	自动确认:消息发送给应用后立即删除;
    	显示确认:待应用发送一个确认回执后再删除消息;

03 队列模型

点对点消息队列模型:1对1模型

特点:
    消息一旦被消息,消息队列就被删除;
    生产者和消费者不存在时间上的依赖性;
    消费者接收成功后,需要向队列应答成功;
    	

在这里插入图片描述

发布订阅消息模型:n对n模型

 	特点:
	    每个消息可以有多个消费者,发布的消息可以被多个消费者消费;
	    发布者和订阅者有时间上的依赖关系;
	    针对每个主题的订阅者,必须创建一个订阅者之后,才能消费发布者的消息;
	    为了消费消息,订阅者必须保持订阅状态; 

在这里插入图片描述

04 消息队列问题

1)消息不丢失问题

	消费者挂掉消息丢失--消费者可以通过AMQP 的basic.ack 命令显式地向RabbitMQ 发送一个确认;
	或者在订阅到队列的时候就将auto_ack 参数设置为true 。当设置了auto_ack=true 时,一旦消费者接收消息,RabbitMQ 会自动视其确认了消息。而当auto_ack=false时,需要消费者通过确认命令告诉RabbitMQ 它
	已经正确地接收了消息,同时RabbitMQ才能安全地把消息从队列中删除;

	Rabbitmq自己挂掉消息丢失--RabbitMQ 确保持久性消息能从服务器重启中恢复的方式是,将它们写入磁盘上的一个持久化日志文件。当发布一条持久性消息到持久交换器上时, Rabbit 会在消息提交到日志文件后才发送响应;

2)异步处理

 引用应用场景:用户注册信息后,写入数据库,需要发送注册短信和注册邮件。
    传统串行方式:300ms,1s可处理3次请求;
    传统并行方式:200ms,1s可处理5次请求;
    消息队列:105ms,1s可处理9次请求;

在这里插入图片描述

3)应用解耦

	在项目启动之初是很难预测未来会遇到什么困难的,消息中间件在处理过程中插入了一个隐含的,基于数据的接口层,两边都实现这个接口,这样就允许独立的修改或者扩展两边的处理过程,只要两边遵守相同的接口约束即可。

	传统模式:两个系统耦合,相互依赖,一个系统出现问题,则都会失败;
	消息队列:发货系统发货后,发货系统完成持久化处理,将消息写入消息队列,返回发货成功,订单系统订阅发货的消息,获取发货信息,订单系统根据信息,进行更新操作。发货系统在发货的时候不用关心后续操作了,如果订单系统不能正常使用。也不影响正常发货,实现订单系统与发货系统的应用解耦;


在这里插入图片描述

4)流量削峰

	对于一些类似淘宝双11这种秒杀活动,访问量剧增,瞬时间流量过大,服务器可能承受不了那么大的流量压力,导致服务宕机,使用消息中间件采用队列的形式,将压力转移到消息队列上,可以减少突发访问压力,不会因为突发的超时负荷要求而崩溃,起到缓冲作用。

5)消息队列积压

	ready准备状态,如果消息数比较多,认为是消费者的处理能力不足,通过增加消费者来可以解决;
   
    unacked未确认状态是因为,消费者取走消息后没有及时做消息确认,没有收到ack的应答,对于开启手动确认机制的,不进行ack则消息会一直以unacked状态留在队列中;
	或者是消费者处理能力不足。生产者投放消息的速度较快,当消费者按照prefetch_count设置的值取走相应数量的消息时,这些消息都会暂时处于unacked状态;

	当积压很多的时候会导致程序无法消费数据,这时候监控系统就会提示我们了,然后运维或开发自己发现后,就要迅速解决积压问题(有一次提交代码的时候有一个值没有处理好,导致监控飙升)


在这里插入图片描述
在这里插入图片描述

解决办法:
	增加消费者的处理能;
	考虑使用队列最大长度限制;
	给消息设置年龄,超时就丢弃;
		
	默认情况下,rabbitmq消费者为单线程串行消费,设置并发消费两个关键属性concurrentConsumers和prefetchCountoncurrentConsumers设置的是对每个listener在初始化的时候设置的并发消费者的个数,prefetchCount是每次一次性从broker里面取的待消费的消息的个数;
	
	建立新的queue,消费者同时订阅新旧queue,采用订阅模式;
	
	生产者端缓存数据,在mq被消费完后再发送到mq,打破发送循环条件,设置合适的qos值,当qos值被用光,而新的ack没有被mq接收时,就可以跳出发送循环,去接收新的消息;消费者主动block接收进程,消费者感受到接收消息过快时主动block,利用block和unblock方法调节接收速率,当接收线程被block时,跳出发送循环。
	
	新建一个topic,partition是原来的10倍;然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue;接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据;等快速消费完积压数据之后,得恢复原先部署架构,重新用原先的consumer机器来消费消息(目前采用过这种方法来应对紧急消息堆积情况);
	

6)消息的事务支持

	即是原子性的,一次处理的多个消息应该在一个事务支持范围内,一个消息失败则即回滚到消息队列中去;

7)消息的持久化

	启用消息持久化后,消息队列宕机重启后,消息可以从持久化存储恢复,消息不丢失,可以继续消费处理;

8)消息队列的高可用性

	遇到宕机、重启等情况,消息队列可能无法服务,所以需要消息队列的高可用的支持,可以采用Rabbitmq的镜像集群模式;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值