ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

如何确认RabbitMq发送消息的可靠性

2021-07-11 21:32:32  阅读:174  来源: 互联网

标签:可靠性 multiple 确认 RabbitMq 发送 deliveryTag 消息 param channel


如何确认RabbitMq发送消息的可靠性

消息真的发出去了吗?

消息发送后,发送端不知道RabbitMQ是否真的收到了消息,如果RabbitM异常,那么消息丢失后,业务流程就停止,发生异常,所以我们需要使用RabbitMq发送端确认机制,确认消息发送

消息确认机制分为:单条同步确认机制,多条同步确认机制和异步确认机制

我们需要使用channel开启消息确认机制

//开启消息确认机制
channel.confirmSelect();
/**
单条和多条同步确认机制都是使用此方法,返回true或false
单条意味着每发出一条消息都会进行确认

多条意味着发出多条在进行确认,但是当消息出现异常时,只会返回false,无法确定是哪条消息出错
*/
channel.waitForConfirms()
/**
异步确认消息
会开启一个异步的线程进行确认消息,但是他不确定是返回多条消息的确认还是单条消息的确认是随机产生的
*/
ConfirmListener confirmListener = new ConfirmListener() {
    /**
     * 返回成功
     * @param deliveryTag  消息的编号
     * @param multiple  true 确认多条,false 确认单条
     * @throws IOException
     */
    @Override
    public void handleAck(long deliveryTag, boolean multiple) throws IOException {
        log.info("Ack, deliveryTag:{},multiple: {}", deliveryTag, multiple);
    }

    /**
     * 返回失败
     * @param deliveryTag  消息的编号
     * @param multiple  true 确认多条,false 确认单条
     * @throws IOException
     */
    @Override
    public void handleNack(long deliveryTag, boolean multiple) throws IOException {
        log.info("Nack, deliveryTag:{},multiple: {}", deliveryTag, multiple);
    }
};
channel.addConfirmListener(confirmListener);

综上所述,最好使用单条确认消息机制

消息真的被路由了吗?

消息发送后,发送端不知道消息是否被正确路由,若路由异常,消息会被丢弃,消息丢弃后,业务发生异常,所以我们需要使用RabbitMQ消息返回机制,确认消息被正确路由

注意消息确认代表消息是否被发送到消息段

而消息路由,是消息已经发送到消息端,确认消息是否被交换机发送到队列

/*-------使用消息返回机制---------*/
channel.addReturnListener(new ReturnListener() {
    	/**
        * 只有在消息无法被路由时,才会调用此方法
        * @param replyCode  返回编号
        * @param replyText  返回消息
        * @param exchange   交换机的名字
        * @param routingKey  绑定的key
        * @param properties
        * @param body     要发送的消息
        * @throws IOException
        */
        @Override
        public void handleReturn(int replyCode, String replyText, String exchange, String routingKey, AMQP.BasicProperties properties, byte[] body) throws IOException {
        log.info("Message Return:" +
                 "replyCode:{},replyText:{},exchange:{},routingKey:{},properties:{},body:{},",
                 replyCode,replyText,exchange,routingKey,properties,new String(body));
    }
});

/**
在发送消息时,我们需要先开启消息返回机制
第三个参数代表是否开启消息返回机制
*/
channel.basicPublish("exchange.order.restaurant", "key.order", true,null, messageToSend.getBytes());
消费端处理异常怎么办

默认情况下,消费端接收消息时,消息会被自动确认(ACK),消费端消息处理异常时,发送端与消息中间件无法得知消息处理情况,所以需要使用RabbitMQ消息端确认机制,确认消息被正确处理

/**
首先需要将自动ACK关闭,改为手动ACK
第二个参数
*/
channel.basicConsume("queue.restaurant",false,deliverCallback, consumerTag -> {});
DeliverCallback deliverCallback = (consumerTag, message) -> {
    /**
    * 第一个参数表示消息的编号
    * 第二个参数使用单条确认
    */
    channel.basicAck(message.getEnvelope().getDeliveryTag(), false);
}

标签:可靠性,multiple,确认,RabbitMq,发送,deliveryTag,消息,param,channel
来源: https://blog.csdn.net/HueyLong/article/details/118660230

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有