JAVA面试题分享一百六十四:消息堆积如何解決?

一、消息堆积对业务的影响

过量的消息堆积可能会引起内存或磁盘告警,从而造成所有connection阻塞,进而影响到其他队列的使用,导致整体服务质量的下降。

二、消息堆积产生的原因
  1. 一般来说消息堆积是由于生产消息的速率远大于消费消息的速率所导致的。比如某个时间段消费端处理消息异常缓慢,发送一条消息只要3秒钟,而消费一条消息需要1分钟,每分钟发送20个消息,只有一个消息被消费端处理,这样队列中就会产生大量的消息堆积。
  2. 消费者出现异常,生产者一直在发送消息,但是消费者不能消费,造成消息积压。
  3. 消费者没有出现异常,但是消费者与队列间的订阅可能出现了异常,也会导致消息无法被消费从而造成堆积的情况。
  4. 消费者正常,与队列间的订阅也正常,但是消费端的代码本身逻辑耗费时间长导致了消费能力降低,这时候就会出现1中的情况从而导致消息堆积。
三、解决消息堆积的办法

 1、生产速率较快,消费速率较慢:您可以通过以下方法解决。

  • 增加消费者数量提高消费速率。
  • 采用生产者确认的发送模式,并监控生产端消息生产速度和时长,当消息生产时长有明显增加时进行流控措施。

2、消费者异常:建议排查消费者逻辑是不是有问题,优化程序。

3、消费者与队列间的订阅异常:建议排查队列和消费者之间的订阅是否正常。

4、消费端的代码本身逻辑耗费时间长:建议给消息设置过期时间,设置方法如下: 

 在生产消息时,设置消息过期时间。消息过期时间以expiration值体现。

在properties中设置expiration值,单位为毫秒(ms)。

AMQP.BasicProperties properties = new AMQP.BasicProperties().builder()
    .deliveryMode(2)
    .contentEncoding("UTF-8")
    .expiration("10000")
    .build();

String message = "hello rabbitmq";
channel.basicPublish(exchange, routingKey, properties, message.getBytes(StandardCharsets.UTF_8));

在Web界面中设置expiration值,单位为毫秒(ms)。

登录Web界面,在“Exchanges”页签,单击Exchange名称,进入Exchange详情页。在“Publish message”区域,设置expiration值,如下图所示。 

 设置队列过期时间。队列过期时间以x-message-ttl值体现。从消息进入队列开始计算,超过了配置的队列过期时间,消息会自动被删除。

在客户端代码中设置x-message-ttl值,单位为毫秒(ms)。

Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-message-ttl", 10000);
channel.queueDeclare(queueName, true, false, false, arguments);

在Web界面新建队列时,设置x-message-ttl值,单位为毫秒(ms)。

登录Web界面,在“Exchanges”页签,新建队列时 ,设置x-message-ttl值,如下图所示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之乎者也·

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值