关于rabbitmq的一些坑以及疑问

在springboot中使用rabbitmq的时候遇到了一些状况,发现很多是由于对概念不清造成的,特此记录。(以下内容纯属个人见解,欢迎指正。

1.确认机制

  publisherConfirm

  个人理解的确认机制其实是由两部分组成的,分别是rabbitmq-server对于生产者的确认,即publisherConfirm。该确认信息会在server收到生产者发送的消息以后就立即返回给server,与消息是否被消费者处理无关,只是server单纯的告诉生产者,我已经收到你的消息了。

  ack

  还有一个消息确认就是ack了,ack指的是消费者从server中取出消息,然后告诉server我把消息取出来了。严格来讲其实与消息是否处理成功也是没有关系的。ack有三种,分别是无ack,自动ack,手动ack。无ack不需要讲解,手动ack就是消费者取到消息后自动给server返回ack,不管消费者对消息的处理是否会出现异常,都会返回ack,个人猜测是在业务代码执行之后,server拿到ack以后,如果正常情况下就会把消息从server中删除。但是如果遇到了异常了就会无限重试该消息,不会被删除。这里我就有个疑问一,希望大神解答一下,问题是这样的,我设置自动ack,在代码中写了一个空指针异常用来测试异常,这个时候接到消息以后就会出现异常,然后消息被无限重试,在重试的过程中消息的状态一直是unacked,然后我手动停掉了消费者,这时候消息的状态变成了ready,这个ready是怎么变得呢? 难道是消费者还发了一个别的标志告诉server我收到了消息但是处理出现异常了?  如果发送的是ack不是应该直接就从队列中把消息删除了吗?不应该存在ready吧。

关于手动ack,没有什么难以理解的,就是自己手动控制发送ack的时机,手动ack如果异常是不会无限重试的。

以上观点是我自己的理解,起初由于理解不当,想以ack去做分布式事务的管理,理清之后豁然开朗。

2.rpc消息类型,分布式事务管理

    关于分布式事务以前没有太多的考虑,最近整合mq的时候才想到了用mq去解决一下,通过上网发现确认也是一种方案。

其实简单理解就是发送的mq消息有去有回,不过去与会的消息不是一个队列。当我们接收到消息的时候再指定一个返回的队列就可以了,在生产者中监听该队列。上一段代码吧

@Bean
    SimpleMessageListenerContainer container(ConnectionFactory connectionFactory) {
        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.setQueueNames("26Test");
        container.setExposeListenerChannel(true);
        container.setMaxConcurrentConsumers(1);
        container.setConcurrentConsumers(1);
        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        container.setMessageListener(new ChannelAwareMessageListener() {
            public void onMessage(Message message, Channel channel) throws Exception {
                byte[] body = message.getBody();
                message.getMessageProperties().getCorrelationIdString();
                CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
                AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
                        .correlationId(UUID.randomUUID().toString())
                        .replyTo("return")
                        .build();
                System.out.println(" getReplyRequest----"+props.getCorrelationId()+"==============" +new Date() );
                channel.basicPublish("", "return", props, body);
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        });
        return container;
    }

这段代码实现的功能就是监听26Test这个队列,处理完毕该队列的消息以后想return队列发送消息,实现消息的有去有回。不过这种事务的处理方式也是有
弊端的,很明显的异步处理
3.无限重试怎么处理?
  自动ack的时候可以设置不无限重试吗?


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RabbitMQ是一个开源的消息中间件,它实现了高效的消息传递机制,用于在分布式系统中进行异步通信。下面是RabbitMQ的功能和特性原理的介绍: 1. 消息队列:RabbitMQ提供了一个可靠的消息队列,用于在应用程序之间传递消息。发送方将消息发送到队列中,接收方从队列中获取消息进行处理。这种解耦的方式可以提高系统的可靠性和可扩展性。 2. 发布/订阅模式:RabbitMQ支持发布/订阅模式,允许多个消费者同时订阅同一个队列中的消息。当有新消息发布到队列时,所有订阅者都会收到该消息的副本。这种模式适用于广播消息或者需要多个消费者处理同一份消息的场景。 3. 路由和绑定:RabbitMQ使用交换机(Exchange)来路由消息到队列。发送方将消息发送到交换机,交换机根据绑定规则将消息路由到一个或多个队列中。这种灵活的路由机制可以根据需求进行配置,实现不同的消息分发策略。 4. 消息确认机制:RabbitMQ提供了消息确认机制,确保消息在发送和接收过程中的可靠性。发送方可以通过等待接收方的确认消息来确保消息已经被成功处理,或者通过设置超时时间来处理发送失败的情况。 5. 消息持久化:RabbitMQ支持消息的持久化,即使在服务器重启后也能保留消息。通过将消息标记为持久化,可以确保消息在服务器故障或重启后不会丢失。 6. 高可用性和负载均衡:RabbitMQ支持集群部署,多个节点可以组成一个集群,提供高可用性和负载均衡。当一个节点故障时,其他节点可以接管其工作,确保系统的可靠性和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值