默认情况下,消息队列不管消费者是否处理完毕消息,都会继续发送下一条消息,有一种机制可以避免这种情况,这种机制使得,使得每个消费者发送确认信号前,消息队列不会发送消息,也就是一个消费者发送确认前一次只处理一条消息,同时消息会在消息队列堆积。
package eve;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Send {
private final static String QUEUE_NAME = "hello2";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// String message = "Hello World "+i;
// channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
// System.out.println(" [x] Sent '" + message + "'");
for(int i=1;i<6;i++){
String message = "Hello World "+i;
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
}
channel.close();
connection.close();
}
}
package eve;
import java.util.concurrent.TimeUnit;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
public class Reqv {
private final static String QUEUE_NAME = "hello2";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
channel.basicQos(0,1,false); //每个消费者发送确认信号之前,消息队列不发送下一个消息过来,一次只处理一个消息
QueueingConsumer consumer = new QueueingConsumer(channel); //QueueingConsumer缓存从服务器发来的消息
channel.basicConsume(QUEUE_NAME, false, consumer); //手动确认
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery(); //在另一个来自服务器的消息到来之前它会一直阻塞着
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
//休眠30s,模拟处理任务需要30s
TimeUnit.SECONDS.sleep(30);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); //手动消息确认,反馈确认信息
}
}
}