RabbitMQ推拉模型

聊聊消息中间件的Push模型和Pull模型

RabbitMQ两种模式都有,一般用Push模式,设置Qos避免内存爆了。

- Pull模式大致用:

--------------------

GetResponse response = channel.basicGet(QUEUE_NAME, false);

System.out.println(new String(response.getBody()));

channel.basicAck(response.getEnvelope().getDeliveryTag(),false);

--------------------

什么是推拉(Push/Pull)模式?

-一般大概把MQ分为三部分:producer、broker、consumer

- Push模式:producer生产完消息后,传递给broker,然后broker马上推给consumer(我们多数用RabbitMQ的模式)

- Pull模式:consumer会主动去broker拉取消息,根据自身消费能力拉取

推拉(Push/Pull)模式的优缺点?

- Push模式

–优点:实时(服务端broker一收到消息就推给consumer)

–缺点:

容易造成消息堆积(消息保存在服务端broker)

需维护每次传输状态,遇到问题要重试

服务短需要根据消费者能力做流控(比如rabbitmq用qos来限制)

- Pull模式

– 优点:保存在消费端,获取方便

传输失败,不需要重试

消费者可根据自身能力来决定流空(因为就是他自己拉取)

– 缺点:实时性不高,短轮询间隔时间大,实时性就低。有其他优化方式,比如CMQ、kafka(腾讯云的服务)也会采用长轮询优化(长轮询如果拉取失败不会直接断开,而是挂在那里wait,如果服务端有新消息就返回最新数据)

中间件

push模型

pull模型

RabbitMQ

支持

支持

Kafka

支持(只有短轮询+长轮询)

RocketMQ

支持

支持

上面说到rabbitmq的推模式推的太快了,那怎么限制?限制方式如下:

RabbitMq Qos prefetch 消息堵塞问题(设置Qos上限时用于 Push模式)

可以设置qos prefetch_count,指单一消费者最多能消费的unacked messages数目

如果不设置Qos?

如果不设置Qos,客户端默认是无限缓存,会一直缓存mq服务发过来的待消费消息,这样坏处如下:

1 无线缓存消息,容易撑爆客户端内存

2 如果新增mq消费者,但是消息都缓存到之前的mq待消费队列中,那这个新增的mq也拿不到消息来消费

如何设置,根据什么做指标?

假设MQ服务传递到客户端的网络IO等事件花费 50 ms(A), 客户端返回ack给MQ处理花费 50 ms(B)。客户端处理消息需要 4 ms(C)。

这样处理一条消息的总时间 = A + B + C = 104 ms,如果Qos prefetch_count设置为 1,这样同时间在客户端缓存队列中存在一条未ack数据,导致(A + B) = 100ms 都浪费掉(因为要处理完这条消息才能继续拿下一条),所以一般要根据往返处理的时间(A + B)来判断 prefetch_count的值

公式为:prefetch_count = (A + B) / 4 = 25,就是设置成25才是最完美的,但是这个很难评定,毕竟各种环境和网络都是因素

备注:如果prefetch_count设置大了,就会导致等待新的mq进来,如果没有新消息,也不能马上消费。

参考: https://segmentfault.com/a/1190000022586723?utm_source=tag-newest

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值