spring boot实战(第十一篇)初识RabbitMQ

前言

最近几篇文章将围绕消息中间件RabbitMQ展开,对于RabbitMQ基本概念这里不阐述,主要讲解RabbitMQ的基本用法、Java客户端API介绍、Spring Boot与RabbitMQ整合、

Spring Boot与RabbitMQ整合源码分析。


RabbitMQ安装

在使用消息中间件RabbitMQ之前就是安装RabbitMQ。

  • 安装erlang:yum install erlang 
  • 下载RabbitMQ安装包: https://www.rabbitmq.com/releases/rabbitmq-server/v3.5.6/rabbitmq-server-generic-unix-3.5.6.tar.gz
  • 解压安装包、配置环境变量RABBITMQ_HOME


参考网址:https://www.rabbitmq.com/install-generic-unix.html
windows  https://www.rabbitmq.com/install-windows.html

RabbitMQ配置

1.安装完成后需要对RabbitMQ进行配置,在etc/rabbitmq目录下创建两个文件:
  • rabbitmq-env.conf 环境信息配置
[html]  view plain  copy
  1. RABBITMQ_NODE_IP_ADDRESS=127.0.0.1  
  2. RABBITMQ_NODE_PORT=5672  
  3. RABBITMQ_NODENAME=node01  
  • rabbitmq.config 核心配置文件

[html]  view plain  copy
  1. [{rabbit, [{loopback_users, []}]}].  
该配置表示是的默认用户guest用户可以远程访问mq(广域网不能访问,内网可以访问)

2.启动RabbitMQ 执行命令 rabbitmq-server
[html]  view plain  copy
  1.             RabbitMQ 3.5.4. Copyright (C) 2007-2015 Pivotal Software, Inc.  
  2. ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/  
  3. ##  ##  
  4. ##########  Logs: /Users/liaokailin/software/rabbitmq_server-3.5.4/sbin/../var/log/rabbitmq/node01.log  
  5. ######  ##        /Users/liaokailin/software/rabbitmq_server-3.5.4/sbin/../var/log/rabbitmq/node01-sasl.log  
  6. ##########  
  7.             Starting broker... completed with 0 plugins.  

3. RabbitMQ提供WEB-UI管理控制台,使用 rabbitmq-plugins enable rabbitmq_management命令启用,重启后可以看到

[html]  view plain  copy
  1. Starting broker... completed with 6 plugins.  

表明WEB-UI控制台启动成功,访问:http://localhost:15672/


登陆进入:



通过该控制台可以方便管理RabbitMQ。

创建Test用户

RabbitMQ默认使用guest用户,下面讲述如何创建一个test用户,最快捷的做法使用web管理控制台



这里使用命令创建:
  • rabbitmqctl add_user test test
  • rabbitmqctl set_user_tags test  administrator

    tag分为四种"management", "policymaker", "monitoring" "administrator" 详见 http://www.rabbitmq.com/management.html


RabbitMQ 其他


在实际使用RabbitMQ中还需要涉及到 RabbitMQ的集群、高可用(采用镜像队列实现) 以后有机会再详细阐述,有兴趣可参考https://www.rabbitmq.com/documentation.html


RabbitMQ Java Client


RabbitMQ 客户端支持语言种类繁多,官方都一一举例:https://www.rabbitmq.com/getstarted.html

这里主要自己开发一个小的demo

消息消费者

操作步骤:
  1. 创建连接工厂ConnectionFactory
  2. 获取连接Connection
  3. 通过连接获取通信通道Channel
  4. 声明交换机Exchange:交换机类型分为四类:

    FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念

            HeadersExchange :通过添加属性key-value匹配

            DirectExchange:按照routingkey分发到指定队列

            TopicExchange:多关键字匹配

  5. 声明队列Queue

  6. 将队列和交换机绑定

  7. 创建消费者

  8. 执行消息的消费

[html]  view plain  copy
  1. package org.lkl.mq.rabbitmq.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.concurrent.TimeUnit;  
  5. import java.util.concurrent.TimeoutException;  
  6.   
  7. import com.rabbitmq.client.Channel;  
  8. import com.rabbitmq.client.Connection;  
  9. import com.rabbitmq.client.ConnectionFactory;  
  10. import com.rabbitmq.client.ConsumerCancelledException;  
  11. import com.rabbitmq.client.QueueingConsumer;  
  12. import com.rabbitmq.client.QueueingConsumer.Delivery;  
  13. import com.rabbitmq.client.ShutdownSignalException;  
  14.   
  15. /**  
  16.  * 客户端01  
  17.  *   
  18.  * @author liaokailin  
  19.  * @version $Id: Receive01.java, v 0.1 2015年11月01日 下午3:47:58 liaokailin Exp $  
  20.  */  
  21. public class Receive01 {  
  22.     public static void main(String[] args) throws IOException, TimeoutException, ShutdownSignalException,  
  23.                                           ConsumerCancelledException, InterruptedException {  
  24.         ConnectionFactory facotry = new ConnectionFactory();  
  25.         facotry.setUsername("test");  
  26.         facotry.setPassword("test");  
  27.         facotry.setVirtualHost("test");  
  28.         facotry.setHost("localhost");  
  29.   
  30.         Connection conn = facotry.newConnection(); //获取一个链接  
  31.         //通过Channel进行通信  
  32.         Channel channel = conn.createChannel();  
  33.         int prefetchCount = 1;  
  34.         channel.basicQos(prefetchCount); //保证公平分发  
  35.   
  36.         boolean durable = true;  
  37.         //声明交换机  
  38.         channel.exchangeDeclare(Send.EXCHANGE_NAME, "direct", durable); //按照routingKey过滤  
  39.         //声明队列  
  40.         String queueName = channel.queueDeclare("queue-01", true, true, false, null).getQueue();  
  41.         //将队列和交换机绑定  
  42.         String routingKey = "lkl-0";  
  43.         //队列可以多次绑定,绑定不同的交换机或者路由key  
  44.         channel.queueBind(queueName, Send.EXCHANGE_NAME, routingKey);  
  45.   
  46.         //创建消费者  
  47.         QueueingConsumer consumer = new QueueingConsumer(channel);  
  48.           
  49.         //将消费者和队列关联  
  50.         channel.basicConsume(queueName, false, consumer); // 设置为false表面手动确认消息消费  
  51.   
  52.         //获取消息  
  53.   
  54.         System.out.println(" Wait message ....");  
  55.         while (true) {  
  56.             Delivery delivery = consumer.nextDelivery();  
  57.             String msg = new String(delivery.getBody());  
  58.             String key = delivery.getEnvelope().getRoutingKey();  
  59.   
  60.             System.out.println("  Received '" + key + "':'" + msg + "'");  
  61.             System.out.println(" Handle message");  
  62.             TimeUnit.SECONDS.sleep(3); //mock handle message  
  63.             channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false); //确定该消息已成功消费  
  64.         }  
  65.   
  66.     }  
  67. }  


消息生产者

操作步骤:
  1. 创建连接工厂ConnectionFactory
  2. 获取连接Connection
  3. 通过连接获取通信通道Channel
  4. 发送消息

[html]  view plain  copy
  1. package org.lkl.mq.rabbitmq.test;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.concurrent.TimeoutException;  
  5.   
  6. import com.rabbitmq.client.Channel;  
  7. import com.rabbitmq.client.ConfirmListener;  
  8. import com.rabbitmq.client.Connection;  
  9. import com.rabbitmq.client.ConnectionFactory;  
  10. import com.rabbitmq.client.MessageProperties;  
  11.   
  12. /**  
  13.  * 消息publish  
  14.  *   
  15.  * @author liaokailin  
  16.  * @version $Id: Send.java, v 0.1 2015年10月22日 下午3:48:09 liaokailin Exp $  
  17.  */  
  18. public class Send {  
  19.     public final static String EXCHANGE_NAME = "test-exchange";  
  20.   
  21.     public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {  
  22.         /**  
  23.          * 配置amqp broker 连接信息  
  24.          */  
  25.         ConnectionFactory facotry = new ConnectionFactory();  
  26.         facotry.setUsername("test");  
  27.         facotry.setPassword("test");  
  28.         facotry.setVirtualHost("test");  
  29.         facotry.setHost("localhost");  
  30.   
  31.         Connection conn = facotry.newConnection(); //获取一个链接  
  32.         //通过Channel进行通信  
  33.         Channel channel = conn.createChannel();  
  34.   
  35.         // channel.exchangeDeclare(Send.EXCHANGE_NAME, "direct", true); //如果消费者已创建,这里可不声明  
  36.         channel.confirmSelect(); //Enables publisher acknowledgements on this channel  
  37.         channel.addConfirmListener(new ConfirmListener() {  
  38.   
  39.             @Override  
  40.             public void handleNack(long deliveryTag, boolean multiple) throws IOException {  
  41.                 System.out.println("[handleNack] :" + deliveryTag + "," + multiple);  
  42.   
  43.             }  
  44.   
  45.             @Override  
  46.             public void handleAck(long deliveryTag, boolean multiple) throws IOException {  
  47.                 System.out.println("[handleAck] :" + deliveryTag + "," + multiple);  
  48.             }  
  49.         });  
  50.   
  51.         String message = "lkl-";  
  52.         //消息持久化 MessageProperties.PERSISTENT_TEXT_PLAIN  
  53.         //发送多条信息,每条消息对应routekey都不一致  
  54.         for (int i = 0; i < 10; i++) {  
  55.             channel.basicPublish(EXCHANGE_NAME, message + (i % 2), MessageProperties.PERSISTENT_TEXT_PLAIN,  
  56.                 (message + i).getBytes());  
  57.             System.out.println("[send] msg " + (message + i) + " of routingKey is " + (message + (i % 2)));  
  58.         }  
  59.   
  60.     }  
  61. }  



在设置消息被消费的回调前需显示调用
[html]  view plain  copy
  1. channel.confirmSelect()  
否则回调函数无法调用

先执行消费者,消费者会轮询是否有消息的到来,在web控制也可以观察哦~~,再启动生产者发送消息。



小结

本篇的主要目的为简单介绍下RabbitMQ的使用,下一遍讲解Spring Boot与RabbitMQ的整合。


本文转自http://blog.csdn.net/liaokailin/article/details/48186331

猜你喜欢

转载自blog.csdn.net/tongtong_use/article/details/78651749
今日推荐