H__D  

准备工作

  1、安装RabbitMQ,参考【RabbitMQ】 RabbitMQ安装

  2、新建Java项目,引入RabbitMQ的Maven依赖

1 <dependency>
2     <groupId>com.rabbitmq</groupId>
3     <artifactId>amqp-client</artifactId>
4     <version>5.5.0</version>
5 </dependency>

单生产者消费者

  流程图:

    

  1、创建生产者Producer1

 1 public class Producer1 {
 2 
 3     private final static String QUEUE_NAME = "rabbitMQ.test.queue";
 4 
 5     public static void main(String[] args) throws IOException, TimeoutException {
 6 
 7         // 创建连接工厂
 8         ConnectionFactory factory = new ConnectionFactory();
 9         // 设置RabbitMQ相关信息
10         factory.setHost("localhost");
11         factory.setUsername("guest");
12         factory.setPassword("guest");
13         factory.setPort(5672);
14         // 创建一个新的连接
15         Connection connection = factory.newConnection();
16         // 创建一个通道
17         Channel channel = connection.createChannel();
18         
19         // 声明一个队列 
20         // queueDeclare(队列名称,是否持久化(true表示是,队列将在服务器重启时生存),是否是独占队列(创建者可以使用的私有队列,断开后自动删除),
21         //                        当所有消费者客户端连接断开时是否自动删除队列,队列的其他参数)
22         channel.queueDeclare(QUEUE_NAME, false, false, false, null);
23         String message = "Hello RabbitMQ ~";
24         
25         // 发送消息到队列中
26         // basicPublish(交换机名称,队列映射的路由key,消息的其他属性,发送信息的主体)
27         channel.basicPublish("", QUEUE_NAME, null, message.getBytes("UTF-8"));
28          System.out.println("Producer Send +'" + message + "'");
29         // 关闭通道和连接
30         channel.close();
31         connection.close();
32 
33     }
34 
35 }

  2、创建消费者Customer1

 1 public class Customer1 {
 2 
 3     private final static String QUEUE_NAME = "rabbitMQ.test.queue";
 4 
 5     public static void main(String[] args) throws IOException, TimeoutException {
 6         // 创建连接工厂
 7         ConnectionFactory factory = new ConnectionFactory();
 8         // 设置RabbitMQ地址
 9         factory.setHost("localhost");
10         factory.setUsername("guest");
11         factory.setPassword("guest");
12         factory.setPort(5672);
13         // 创建一个新的连接
14         Connection connection = factory.newConnection();
15         // 创建一个通道
16         final Channel channel = connection.createChannel();
17         // 声明要关注的队列
18         channel.queueDeclare(QUEUE_NAME, false, false, false, null);
19         channel.basicQos(1);//保证一次只分发一个
20         System.out.println("Customer Waiting Received messages");
21         
22         // DefaultConsumer类实现了Consumer接口,通过传入一个频道,
23         // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
24         Consumer consumer = new DefaultConsumer(channel) {
25             @Override
26             public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
27                     byte[] body) throws IOException {
28                 String message = new String(body, "UTF-8");
29                 System.out.println("Customer Received '" + message + "'");
30             }
31         };
32         
33         // 自动回复队列应答 -- RabbitMQ中的消息确认机制
34         channel.basicConsume(QUEUE_NAME, true, consumer);
35     }
36 
37 }

  3、运行结果

    a、生产者

    

    b、消费者

    

推送确认和消费应答

  流程图

    

  1、创建推送确认生产者Producer2

 1 public class Producer2 {
 2 
 3     private final static String QUEUE_NAME = "rabbitMQ.test.queue";
 4 
 5     public static void main(String[] args) throws IOException, TimeoutException {
 6 
 7         // 创建连接工厂
 8         ConnectionFactory factory = new ConnectionFactory();
 9         // 设置RabbitMQ相关信息
10         factory.setHost("localhost");
11         factory.setUsername("guest");
12         factory.setPassword("guest");
13         factory.setPort(5672);
14         // 创建一个新的连接
15         Connection connection = factory.newConnection();
16         // 创建一个通道
17         Channel channel = connection.createChannel();
18 
19         // 声明一个队列
20         // queueDeclare(队列名称,是否持久化(true表示是,队列将在服务器重启时生存),是否是独占队列(创建者可以使用的私有队列,断开后自动删除),
21         // 当所有消费者客户端连接断开时是否自动删除队列,队列的其他参数)
22         channel.queueDeclare(QUEUE_NAME, false, false, false, null);
23 
24         // 开启发送方确认模式
25         channel.confirmSelect();
26 
27         // 存储未确认的消息标识tag
28         final SortedSet<Long> confirmSet = Collections.synchronizedNavigableSet(new TreeSet<Long>());
29 
30         // 异步监听确认和未确认的消息
31         channel.addConfirmListener(new ConfirmListener() {
32 
33             /**
34              * 处理返回确认成功
35              * 
36              * @param deliveryTag 如果是多条,这个就是最后一条消息的tag
37              * @param multiple    是否多条
38              * @throws IOException
39              */
40             public void handleAck(long deliveryTag, boolean multiple) throws IOException {
41                 System.out.println("消息发送成功,    deliveryTag:" + deliveryTag + "        multiple:" + multiple + "");
42                 if (multiple) {
43                     // 移除发送成功的多条消息标识tag
44                     confirmSet.headSet(deliveryTag + 1).clear();
45                 } else {
46                     // 移除发送成功的一条消息标识tag
47                     confirmSet.remove(deliveryTag);
48                 }
49             }
50 
51             /**
52              * 处理返回确认失败
53              * 
54              * @param deliveryTag 如果是多条,这个就是最后一条消息的tag
55              * @param multiple    是否多条
56              * @throws IOException
57              */
58             public void handleNack(long deliveryTag, boolean multiple) throws IOException {
59                 System.out.println("失败,deliveryTag:" + deliveryTag + "multiple:" + multiple + "");
60                 if (multiple) {
61                     confirmSet.headSet(deliveryTag + 1).clear();
62                 } else {
63                     confirmSet.remove(deliveryTag);
64                 }
65             }
66 
67         });
68 
69         String message = "Hello RabbitMQ ~ ";
70 
71         // 发送消息到队列中
72         // basicPublish(交换机名称,队列映射的路由key,消息的其他属性,发送信息的主体)
73         for (int i = 1; i <= 10; i++) {
74             String msg = message + i;
75             long tag = channel.getNextPublishSeqNo();
76             confirmSet.add(tag);
77             System.out.println("tag:" + tag);
78             
79             channel.basicPublish("", QUEUE_NAME, null, msg.getBytes("UTF-8"));
80             System.out.println("Producer Send +'" + msg + "'");
81             
82         }
83         
84         System.out.println("============================");
85         // 关闭通道和连接
86         // channel.close();
87         // connection.close();
88 
89     }
90 }

  2、创建消费应答消费者Customer2

 1 public class Customer2 {
 2 
 3     private final static String QUEUE_NAME = "rabbitMQ.test.queue";
 4 
 5     public static void main(String[] args) throws IOException, TimeoutException {
 6         // 创建连接工厂
 7         ConnectionFactory factory = new ConnectionFactory();
 8         // 设置RabbitMQ地址
 9         factory.setHost("localhost");
10         factory.setUsername("guest");
11         factory.setPassword("guest");
12         factory.setPort(5672);
13         // 创建一个新的连接
14         Connection connection = factory.newConnection();
15         // 创建一个通道
16         final Channel channel = connection.createChannel();
17         // 声明要关注的队列
18         channel.queueDeclare(QUEUE_NAME, false, false, false, null);
19         channel.basicQos(1);// 保证一次只分发一个
20         System.out.println("Customer Waiting Received messages");
21 
22         // DefaultConsumer类实现了Consumer接口,通过传入一个频道,
23         // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
24         Consumer consumer = new DefaultConsumer(channel) {
25             @Override
26             public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
27                     byte[] body) throws IOException {
28                 String message = new String(body, "UTF-8");
29                 System.out.println("Customer Received '" + message + "'");
30 
31                 // 返回消费确认状态
32                 channel.basicAck(envelope.getDeliveryTag(), false);
33             }
34         };
35 
36         // 消费手动确认 -- RabbitMQ中的消息确认机制
37         channel.basicConsume(QUEUE_NAME, false, consumer);
38     }
39 
40 }

  3、运行结果

    生产者:
      

    消费者:
      

多消费者

  流程图
    

  1、创建推送确认生产者Producer3(与示例Producer2一样)

  2、创建消费应答消费者Customer3

 1 public class Customer3 {
 2 
 3     private final static String QUEUE_NAME = "rabbitMQ.test.queue";
 4 
 5     public static void main(String[] args) throws IOException, TimeoutException {
 6         Customer3 customer3 = new Customer3();
 7         customer3.createCustomer("customer1");
 8         customer3.createCustomer("customer2");
 9     }
10 
11     public void createCustomer(final String customerName) throws IOException, TimeoutException{
12         
13         // 创建连接工厂
14         ConnectionFactory factory = new ConnectionFactory();
15         // 设置RabbitMQ地址
16         factory.setHost("localhost");
17         factory.setUsername("guest");
18         factory.setPassword("guest");
19         factory.setPort(5672);
20         // 创建一个新的连接
21         Connection connection = factory.newConnection();
22         // 创建一个通道
23         final Channel channel = connection.createChannel();
24         // 声明要关注的队列
25         channel.queueDeclare(QUEUE_NAME, false, false, false, null);
26         channel.basicQos(1);// 保证一次只分发一个
27         System.out.println(customerName + " Waiting Received messages");
28 
29         // DefaultConsumer类实现了Consumer接口,通过传入一个频道,
30         // 告诉服务器我们需要那个频道的消息,如果频道中有消息,就会执行回调函数handleDelivery
31         Consumer consumer = new DefaultConsumer(channel) {
32             @Override
33             public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties,
34                     byte[] body) throws IOException {
35                 String message = new String(body, "UTF-8");
36                 System.out.println(customerName + " Received '" + message + "'");
37                 
38                 // doWork处理任务
39                 doWork(customerName);
40                 
41                 // 返回消费确认状态
42                 channel.basicAck(envelope.getDeliveryTag(), false);
43             }
44         };
45 
46         // 消费手动确认 -- RabbitMQ中的消息确认机制
47         channel.basicConsume(QUEUE_NAME, false, consumer);
48     }
49     
50     
51     private void doWork(String customer) {
52         try {
53             Thread.sleep(2000); // 暂停2秒钟
54             System.out.println(customer + ": completion of the job!");
55         } catch (InterruptedException _ignored) {
56             Thread.currentThread().interrupt();
57         }
58     }
59 }

  3、运行结果
    生产者与前面相同

    消费者
      
  

 

posted on 2018-11-25 19:05  H__D  阅读(2600)  评论(0编辑  收藏  举报