一、消息确认
消息确认是为了让消息不丢失。当消费者在处理消息的时候突然服务器宕机,这个消息还没有处理完成,而RabbitMQ代理服务器又将该消息删除这样就会造成消息的丢失,但是我们又希望这个消息不能就这样丢失而是将这个消息重新推送给新的一个消费者,
为了确保消息不会丢失,RabbitMQ支持消息确认。使用者将一个ack(nowledgement)发回给RabbitMQ,告诉它已经接收、处理了一个特定的消息,并且RabbitMQ可以自由地删除它。如果使用者在没有发送ack的情况下死亡(通道关闭、连接关闭或TCP连接丢失),
RabbitMQ将理解消息没有被完整地处理,并将它重新排队。如果同时有其他消费者在线,它将很快重新交付给另一个消费者。这样你就可以确保没有信息丢失,
RabbitMQ处理消息的时间没有设置超时可以一直等待下去,这样有利于消费者处理消息的时间较长
默认情况下,手动消息确认被打开。我们通过autoAck=true标志显式地关闭它们。
二、消息持久化
当RabbitMQ退出或崩溃时,它将忘记队列和消息,除非您告诉它不要这样做。确保消息不丢失需要两件事情:我们需要将队列和消息标记为持久的。
1、确保RabbitMQ不会丢失队列
boolean durable = true;
channel.queueDeclare("hello", durable, false, false, null);
RabbitMQ不允许您重新定义具有不同参数的现有队列,并将向任何试图这样做的程序返回错误。
2、确保消息持久化
通过设置MessageProperties 的值为PERSISTENT_TEXT_PLAIN
channel.basicPublish("", "task_queue", MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes());
三、消息公平分配
如果有多个消费者的时候比如消费者A、消费者B、消费者C,RabbitMQ 的分配方式是循环轮询,即当有消息放入队列的时候第一次分配给A,第二次分配给B、第三次分配给C以此轮询,从表面上看是公平的分配,其实背后隐藏一个问题,如果某一个消费者出现问题
然后RabbitMQ 又一直给它推送消息,这就造成这个消费者堆积了很多待处理消息而其他消费者很清闲
处理方式:通过设置int prefetchCount = 1; channel.basicQos(prefetchCount);使用basicQos方法,将prefetchCount = 1设置。这告诉RabbitMQ不要一次向消费者发送多个消息。或者,换句话说,在处理并确认之前的消息之前,不要向消费者发送新的消息。
消息确认是为了让消息不丢失。当消费者在处理消息的时候突然服务器宕机,这个消息还没有处理完成,而RabbitMQ代理服务器又将该消息删除这样就会造成消息的丢失,但是我们又希望这个消息不能就这样丢失而是将这个消息重新推送给新的一个消费者,
为了确保消息不会丢失,RabbitMQ支持消息确认。使用者将一个ack(nowledgement)发回给RabbitMQ,告诉它已经接收、处理了一个特定的消息,并且RabbitMQ可以自由地删除它。如果使用者在没有发送ack的情况下死亡(通道关闭、连接关闭或TCP连接丢失),
RabbitMQ将理解消息没有被完整地处理,并将它重新排队。如果同时有其他消费者在线,它将很快重新交付给另一个消费者。这样你就可以确保没有信息丢失,
RabbitMQ处理消息的时间没有设置超时可以一直等待下去,这样有利于消费者处理消息的时间较长
默认情况下,手动消息确认被打开。我们通过autoAck=true标志显式地关闭它们。
二、消息持久化
当RabbitMQ退出或崩溃时,它将忘记队列和消息,除非您告诉它不要这样做。确保消息不丢失需要两件事情:我们需要将队列和消息标记为持久的。
1、确保RabbitMQ不会丢失队列
boolean durable = true;
channel.queueDeclare("hello", durable, false, false, null);
RabbitMQ不允许您重新定义具有不同参数的现有队列,并将向任何试图这样做的程序返回错误。
2、确保消息持久化
通过设置MessageProperties 的值为PERSISTENT_TEXT_PLAIN
channel.basicPublish("", "task_queue", MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes());
三、消息公平分配
如果有多个消费者的时候比如消费者A、消费者B、消费者C,RabbitMQ 的分配方式是循环轮询,即当有消息放入队列的时候第一次分配给A,第二次分配给B、第三次分配给C以此轮询,从表面上看是公平的分配,其实背后隐藏一个问题,如果某一个消费者出现问题
然后RabbitMQ 又一直给它推送消息,这就造成这个消费者堆积了很多待处理消息而其他消费者很清闲
处理方式:通过设置int prefetchCount = 1; channel.basicQos(prefetchCount);使用basicQos方法,将prefetchCount = 1设置。这告诉RabbitMQ不要一次向消费者发送多个消息。或者,换句话说,在处理并确认之前的消息之前,不要向消费者发送新的消息。
相反,它将把它分派给下一个不太忙的消费者。
四、exchange、binding说明
RabbitMQ中的消息传递模型的核心思想是,生产者永远不会直接向队列发送任何消息。实际上,生产者常常甚至不知道消息是否会被发送到任何队列
可以使用的交换类型有:direct、topic、header和fanout。
exchange有两个作用:一方面,它接收来自生产者的消息,另一边则将消息推送到队列中。
绑定binding:是用来连接交换器exchange和队列的queue
绑定可以使用一个额外的路由键参数(routingKey),绑定键的含义取决于交换类型