RabbitMq消费消息

rabbitmq的消息消费有两种方式,推模式和拉模式。推模式采用basic.consume进行消费,而拉模式则是调用的basic.Get进行消费。

推模式:

1:推模式接收消息是最有效的一种消息处理方式。channel.basicConsume(queneName,consumer)方法将信道(channel)设置成投递模式,直到取消队列的订阅为止;在投递模式期间,当消息到达RabbitMQ时,RabbitMQ会自动地、不断地投递消息给匹配的消费者,而不需要消费端手动来拉取,当然投递消息的个数还是会受到channel.basicQos的限制。

2:推模式将消息提前推送给消费者,消费者必须设置一个缓冲区缓存这些消息。优点是消费者总是有一堆在内存中待处理的消息,所以当真正去消费消息时效率很高。缺点就是缓冲区可能会溢出。3:由于推模式是信息到达RabbitMQ后,就会立即被投递给匹配的消费者,所以实时性非常好,消费者能及时得到最新的消息。

拉模式:1:如果只想从队列中获取单条消息而不是持续订阅,则可以使用channel.basicGet方法来进行消费消息。2:拉模式在消费者需要时才去消息中间件拉取消息,这段网络开销会明显增加消息延迟,降低系统吞吐量。3:由于拉模式需要消费者手动去RabbitMQ中拉取消息,所以实时性较差;消费者难以获取实时消息,具体什么时候能拿到新消息完全取决于消费者什么时候去拉取消息。

结论

1:不能在循环中使用拉模式来模拟推模式,因为拉模式每次都需要去消息中间件中拉取消息来消费,所以会严重影响RabbitMQ性能。

2:要想实现高吞吐量,消费者需要使用推模式。

不言不语技术

https://www.cnblogs.com/hzcya1995/p/13302427.html

1.推模式

在推模式中,可以通过持续订阅的方式来消费消息,使用到的相关类有:

import com.rabbitmq.client.consumer;
import com.rabbitmq.client.defaultconsumer;

接收消息一般通过实现consumer接口或者继承defaultconsumer类实现,当调用与consumer相关的api方法时,不同的订阅采用不同的消费者标签consumerTag来区分彼此,在同一个channel中的消费者也需要通过唯一的消费者标签做区分,关键消费代码如下:

boolean autoAck=false;
channel.basicQos(64);
channel.basicConsume(queueName,autoAck,consumerTag,new DefaultConsume(channel){
public void handleDelivery(String consumerTag,Envelop envelope,AMQP.BasicProperties properties,byte[] body){
String routingKey=envelop.getRoutingKey();
String contentType=properties.getContentType();
//这里做具体的业务,我们开发中使用的注解    @RabbitListener(queues = RabbitConsts.WENKU_SDFILE_KBASE)就是在这里做的,就是AOP。aop很重要的
//这里的false表示不自动ack,为true表示自动ack,但是自动ack会有消息丢失的潜在问题
channel.basicAck(deliveryTag,false);
}
})

channel.basic有很多类似的接口。基本的参数如下:

queue:队列的名称

autoAck:设置是否自动确认,建议设置成false,就是不自动确认

consumerTag:消费者标签,用来区分对个消费者

nolocal:设置为true表示不能将同一个connection中生产者发送的消息传递给这个connection中的消费者。

exclusive:设置是否排他

arguments:设置消费者的其他参数

callBack:设置消费者的回调函数,用来处理rabbitmq推送过来的消息,比如defaultconsumer,使用客户端重写其中的方法。

当然和spring ioc中的bean的初始化一样,channel.basicConsume也有很多事件处理器,比如handleConsumerOk,handleCannelOK,handleCannel,handshutDownSign,handReconverOk等。可以去做一写前置或者后置的判断。

在使用推模式的时候有个参数需要注意:prefetch。这个参数的含义是一次性可以消费多少条消息,如果设置了改参数,消费者会通过队列进行缓存,同事rabbitmq队列中将有消费者数量*prefetch数量的消息没有收到ack,知道rabbitmq中的消息全部被ack之后,才会发送prefetch数量的消息给一个消费者。这个参数设置的过大会导致消费者的缓存队列溢出,或者oom现象。如果有上下游业务关系的还是配置成1吧!

2.拉模式

拉模式通过channel.basicGet方法可以单条的获取消息,其返回值为GetResponse,channel类的basicGet方法没有其他的重载方法,拉模式不要放在一个while循环中,那样消耗会很大,仅有:

GetResponse basicGet(String queue,boolean ack);

queue表示队列名,ack表示是否自动确认。如果设置为false,同样需要调用channel.basicAck确认消息被消费了。

GetResponse response=channel.basicGet(“ttt”,false);
//do something
channel.basicAck(response.getEnvelope().getDeliverTag(),false);
RabbitMQ中,消费消息有两种方式:自动确认和手动确认。自动确认是指当消费者收到消息后,RabbitMQ会立即将消息队列中删除,不需要消费者显式地确认。这种方式适用于对消息处理时间较短的情况。\[1\] 另一种方式是手动确认,也称为消息确认机制。当消费者收到消息后,需要显式地发送ack信号给RabbitMQ,告知已成功处理该消息。如果消费者在一定时间内没有发送ack信号,RabbitMQ会将消息重新投递给其他消费者。这种方式适用于对消息处理时间较长或需要保证消息不丢失的情况。\[2\]\[3\] 在手动确认模式下,还可以设置QoS预取模式。预取模式指定了消费者一次从队列中获取的消息数量。通过设置合适的预取数量,可以提高消费者的处理效率。\[3\] 总结起来,消费消息可以选择自动确认或手动确认。自动确认适用于消息处理时间较短的情况,而手动确认适用于消息处理时间较长或需要保证消息不丢失的情况。在手动确认模式下,可以设置QoS预取模式来提高消费者的处理效率。 #### 引用[.reference_title] - *1* *2* *3* [四、消息中间件RabbitMQ消息消费时的权衡](https://blog.csdn.net/lcc2ztt/article/details/101285546)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值