Work Queues(点对多)

Work Queues(点对多)

多个消费者在同一个消息队列中获取消息的情况。在有些应用当中,消费端接收到消息任务需要长时间的处理,如果等上一个消息处理完成以后再取下一个数据进行处理的话,势必会有一些延迟。在消息队列中的数据也会不断增多,延迟将越来越大。当然对于一个消费进程来说,在某些情况下可以起多个线程来处理,而在这里将介绍另一种处理方式,多个消费进程的情况。而RabbitMQ在这方面进行了很好的处理和封装,使客户程序可以很方便的使用。

默认的,RabbitMQ会顺序的把消息发送到下一个Consumer,这种发送消息的方式称为循环发送(round-robin)

 1 package com.rabbitmq.www.work_queues;
 2 
 3 
 4 
 5 import com.rabbitmq.client.Channel;
 6 import com.rabbitmq.client.Connection;
 7 import com.rabbitmq.client.ConnectionFactory;
 8 import com.rabbitmq.client.MessageProperties;
 9 
10 public class NewTask {
11 
12   private static final String TASK_QUEUE_NAME = "task_queue";
13   private final static String HOST_ADDR = "172.18.112.102";
14 
15   public static void main(String[] argv) throws Exception {
16       
17       
18     ConnectionFactory factory = new ConnectionFactory();
19     factory.setHost(HOST_ADDR);
20     Connection connection = factory.newConnection();
21     Channel channel = connection.createChannel();
22     
23     //durable 设置true,queue持久化,server重启,此queue不丢失
24     channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
25     for(int i=0;i<=10;i++){
26         String message = "hello world";
27         message=message+i;
28         //BasicProperties设置MessageProperties.PERSISTENT_TEXT_PLAIN,信息持久化
29         channel.basicPublish("", TASK_QUEUE_NAME,MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes("UTF-8"));
30         System.out.println(" [x] Sent '" + message);
31     }
32 
33     channel.close();
34     connection.close();
35   }
36 
37 }
package com.rabbitmq.www.work_queues;

import com.rabbitmq.client.*;

import java.io.IOException;

public class Worker {

  private static final String TASK_QUEUE_NAME = "task_queue";
  private final static String HOST_ADDR = "172.18.112.102";

  public static void main(String[] argv) throws Exception {
      
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost(HOST_ADDR);
    final Connection connection = factory.newConnection();
    final Channel channel = connection.createChannel();
  //durable 设置true,queue持久化,server重启,此queue不丢失
    channel.queueDeclare(TASK_QUEUE_NAME, true, false, false, null);
    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
    //一次只接受一条信息
    channel.basicQos(1);

    final Consumer consumer = new DefaultConsumer(channel) {
      @Override
      public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
        String message = new String(body, "UTF-8");

        System.out.println(" [x] Received '" + message + "'");
        try {
          doWork(message);
        } finally {
          System.out.println(" [x] Done");
          //向服务器发送应答
          channel.basicAck(envelope.getDeliveryTag(), false);
        }
      }
    };
    //autoAck 设置false,消费端挂掉,信息不会丢失,server会re-queue
    channel.basicConsume(TASK_QUEUE_NAME, false, consumer);
  }

  private static void doWork(String task) {
    for (char ch : task.toCharArray()) {
      if (ch == '.') {
        try {
          Thread.sleep(1000);
        } catch (InterruptedException _ignored) {
          Thread.currentThread().interrupt();
        }
      }
    }
  }
}

 

posted @ 2017-06-17 17:30  woms  阅读(409)  评论(0编辑  收藏  举报