默认情况下,消息队列不管消费者是否处理完毕消息,都会继续发送下一条消息,有一种机制可以避免这种情况,这种机制使得,使得每个消费者发送确认信号前,消息队列不会发送消息,也就是一个消费者发送确认前一次只处理一条消息,同时消息会在消息队列堆积。
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); //手动消息确认,反馈确认信息 } } }