RabbitMQ快速入门
代码地址:https://gitee.com/webprogram/spring_rabbit
入门程序
需求:使用简单模式完成消息传递
步骤:
- 创建工程(生产者、消费者)
- 分别添加依赖
- 编写消费者发送消息
- 编写消费者接收消息
创建maven项目,导入依赖
<!-- rabbitMq 客户端依赖 -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.6.0</version>
</dependency>
生产者
public class MessageProducer {
public static void sendMessage() throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
// 2.设置参数
// ip,默认为本地localhost
connectionFactory.setHost("127.0.0.1");
// 端口,默认值5672
connectionFactory.setPort(5672);
// 虚拟机,默认值/
connectionFactory.setVirtualHost("my_vhost");
// 账号,默认值guest
connectionFactory.setUsername("admin");
// 密码,默认值guest
connectionFactory.setPassword("admin");
// 3.创建连接 Connection
Connection connection = connectionFactory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.创建队列
/**
* 参数说明:
* 1.queue:队列名称
* 2.durable:是否持久化,当mq重启之后,数据依旧存在
* 3.exclusive:
* - 是否独占,只能有一个监听者该队列
* - 当connection关闭时,是否删除队列
* 4.autoDelete:是否 自动删除,当没有Consumer是,自动删除
* 5.arguments:参数
*/
// 如果没有名为“first_queue”的队列,则会创建,否则不会创建
channel.queueDeclare("first_queue",true,false,false,null);
// 6.发送消息
/**
* 参数:
* 1.exchange:交换机名称,简单模式下交换机默认为""
* 2.routing key:路由mingc
* 3.props:配置信息
* 4.body:发送的消息数据
*/
channel.basicPublish("","first_queue",null,"hello rabbit".getBytes());
// 7.释放资源
// channel.close();
// connection.close();
}
}
执行生产者代码,在控制台会看到创建一个first_queue的队列,里面有消息1个
消费者
public class MessageConsumer {
public static void getMessage() throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
// 2.设置参数
// ip,默认为本地localhost
connectionFactory.setHost("127.0.0.1");
// 端口,默认值5672
connectionFactory.setPort(5672);
// 虚拟机,默认值/
connectionFactory.setVirtualHost("my_vhost");
// 账号,默认值guest
connectionFactory.setUsername("admin");
// 密码,默认值guest
connectionFactory.setPassword("admin");
// 3.创建连接 Connection
Connection connection = connectionFactory.newConnection();
// 4.创建Channel
Channel channel = connection.createChannel();
// 5.创建队列
/**
* 参数说明:
* 1.queue:队列名称
* 2.durable:是否持久化,当mq重启之后,数据依旧存在
* 3.exclusive:
* - 是否独占,只能有一个监听者该队列
* - 当connection关闭时,是否删除队列
* 4.autoDelete:是否 自动删除,当没有Consumer是,自动删除
* 5.arguments:参数
*/
// 如果没有名为“first_queue”的队列,则会创建,否则不会创建
channel.queueDeclare("first_queue",true,false,false,null);
// 6.接收消息
/**
* handleDelivery()参数:
* 1.consumerTag:标识
* 2.envelope:获取一些信息,交换机,路由key
* 3.properties:配置信息
* 4.bady:数据
*/
Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println("consumerTag:" + consumerTag);
System.out.println("exchange:" + envelope.getExchange());
System.out.println("routingkey:" + envelope.getRoutingKey());
System.out.println("properties:" + properties);
System.out.println("body" + new String(body));
}
};
channel.basicConsume("first_queue",true,consumer);
// 7.释放资源?不需要 消费者相当于一个监听者 时刻监听队列
// 此处只是不让程序结束,等待回调函数执行
while (true){}
}
}
handleDelivery()方法为回调方法,在消费之后执行
运行上述方法,成功将队列中的消息消费,控制台消息数为0
IDEA控制台输出:
consumerTag:amq.ctag-hfsqwcG_YSGZPje2Zb_lCg
exchange:
routingkey:first_queue
properties:#contentHeader(content-type=null, content-encoding=null, headers=null, delivery-mode=null, priority=null, correlation-id=null, reply-to=null, expiration=null, message-id=null, timestamp=null, type=null, user-id=null, app-id=null, cluster-id=null)
bodyhello rabbit
注:
-
handleDelivery()回调函数执行,必须保证当前程序还没结束,也就是例子中while(true)死循环的作用,否则回调函数还没执行程序中断,则打印不出相关信息
-
在生产者客户端不能关闭资源,
// channel.close();
// connection.close();在生产者中这两行代码是注释掉的,理论上资源应该及时关闭,但关闭后在消费者客户端无法执行回调函数,具体原因正在研究
handleDelivery()无法执行解决方案,相关链接:https://blog.csdn.net/qq_38668544/article/details/120380256