RabbitMQ的推拉模式

在rabbitmq中有两种消息处理的模式,一种是推模式/订阅模式/投递模式(也叫push模式),消费者调用channel.basicConsume方法订阅队列后,由RabbitMQ主动将消息推送给订阅队列的消费者;另一种是拉模式/检索模式(也叫pull模式),需要消费者调用channel.basicGet方法,主动从指定队列中拉取消息。

  • 推模式:消息中间件主动将消息推送给消费者
  • 拉模式:消费者主动从消息中间件拉取消息

推模式(push)

  1. 推模式接收消息是最有效的一种消息处理方式。channel.basicConsume(queneName,consumer)方法将信道(channel)设置成投递模式,直到取消队列的订阅为止;在投递模式期间,当消息到达RabbitMQ时,RabbitMQ会自动地、不断地投递消息给匹配的消费者,而不需要消费端手动来拉取,当然投递消息的个数还是会受到channel.basicQos的限制。
  2. 推模式将消息提前推送给消费者,消费者必须设置一个缓冲区缓存这些消息。优点是消费者总是有一堆在内存中待处理的消息,所以当真正去消费消息时效率很高。缺点就是缓冲区可能会溢出。
  3. 由于推模式是信息到达RabbitMQ后,就会立即被投递给匹配的消费者,所以实时性非常好,消费者能及时得到最新的消息。

拉模式(pull)

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

结论

  1. 推模式更关注消息的实时性
  2.  推模式直接从内存缓冲区中获取消息,能有效的提高消息的处理效率以及吞吐量
  3. 拉模式更关注消费者的消费能力,只有消费者主动去拉取消息才会去获取消息
  4. 默认使用推消息,由于某些限制,消费者在某个条件成立时才能消费消息的场景需要从批量获取消息的场景

Qos相关内容

为什么要设置Qos:

在RabbitMQ中,队列向消费者发送消息,如果没有设置Qos的值,那么队列中有多少消息就发送多少消息给消费者,完全不管消费者是否能够消费完,这样可能就会形成大量未ack的消息在缓存区堆积,因为这些消息未收到消费者发送的ack,所以只能暂时存储在缓存区中,等待ack,然后删除对应消息。

这样的话,因此希望开发人员能限制此缓冲区的大小,以避免缓冲区里面无限制的未确认消息问题。这个时候就可以通过使用 basic.qos 方法设置“预取计数”值来完成的。该值定义通道上允许的未确认消息的最大数量,一旦数量达到配置的数量,RabbitMQ 将停止在通道上传递更多消息,除非至少有一个未处理的消息被确认,例如,假设在通道上有未确认的消息 5、6、7,8,并且通道的预取计数设置为 4,此时 RabbitMQ 将不会在该通道上再传递任何消息,除非至少有一个未应答的消息被 ack。比方说 tag=6 这个消息刚刚被确认 ACK,RabbitMQ 将会感知这个情况到并再发送一条消息。

消息应答和 QoS 预取值对用户吞吐量有重大影响。通常,增加预取将提高向消费者传递消息的速度。虽然自动应答传输消息速率是最佳的,但是,在这种情况下已传递但尚未处理的消息的数量也会增加,从而增加了消费者的RAM 消耗(随机存取存储器)应该小心使用具有无限预处理的自动确认模式或手动确认模式,消费者消费了大量的消息如果没有确认的话,会导致消费者连接节点的内存消耗变大,

所以找到合适的预取值是一个反复试验的过程,不同的负载该值取值也不同 100 到 300 范围内的值通常可提供最佳的吞吐量,并且不会给消费者带来太大的风险。预取值为 1 是最保守的。当然这将使吞吐量变得很低,特别是消费者连接延迟很严重的情况下,特别是在消费者连接等待时间较长的环境中。对于大多数应用来说,稍微高一点的值将是最佳的。

Qos的取值问题:

在传输效率和消费者消费速度之间做一个平衡。这个值是需要不断尝试的,

因为太低,信道传输消息效率太低,

如果太高,消费者来不及确认消息导致消息积累问题,内存消耗不断增大。

不公平分发:

Qos是一个典型的不公平分发的场景:

能者多劳

对于两个消费者,设置同样preCount的值,消费能力快的,给其推送的消息是最多的

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RabbitMQ是一个消息中间件,支持推拉模式。在Java中使用RabbitMQ的方式如下: 1. 导入RabbitMQ的Java客户端库,可以使用Maven或Gradle等工具自动导入依赖。 2. 创建一个连接工厂对象,设置RabbitMQ服务器的地址和端口。 ``` ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); factory.setPort(5672); ``` 3. 创建一个连接对象,使用连接工厂创建。 ``` Connection connection = factory.newConnection(); ``` 4. 创建一个通道对象,使用连接对象创建。 ``` Channel channel = connection.createChannel(); ``` 5. 声明一个队列,使用通道对象声明。 ``` String queueName = "hello"; channel.queueDeclare(queueName, false, false, false, null); ``` 6. 发送消息到队列中,使用通道对象发布消息。 ``` String message = "Hello World!"; channel.basicPublish("", queueName, null, message.getBytes("UTF-8")); ``` 7. 接收队列中的消息,创建一个消费者对象,使用通道对象消费消息。 ``` Consumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); System.out.println("Received message: " + message); } }; channel.basicConsume(queueName, true, consumer); ``` 以上就是使用RabbitMQ推拉模式的基本步骤。注意在使用完连接、通道等资源后需要及时关闭,以免资源泄漏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值