RabbitMQ入门
- 1 安装和启动
- 1.1 erlang安装
- 1.2 RabbitMQ安装及启动
- 2 Java代码示例
- 2.1 静态工厂类——获取连接
- 2.2 RabbitMQ消费者线程类
- 2.3 RabbitMQ生产者线程类
- 2.4 测试实例
- 参考链接
1 安装和启动
1.1 erlang安装
RabbitMQ 是由 Erlang语言编写的,在安装RabbitMQ 之前需要安装 Erlang。Erlang 官网下载:http://www.erlang.org/downloads
windows下安装erlang后,需要配置erlang的环境变量:
ERLANG_HOME:C:\szh\erl
Path:;%ERLANG_HOME%\bin
接着在cmd命令窗口输入"erl",若安装配置erlang成功,会显示erlang的版本信息。
1.2 RabbitMQ安装及启动
RabbitMQ官网下载:https://www.rabbitmq.com/install-rpm.html
windows下安装RabbitMQ后,需要配置环境变量:
RABBITMQ_SERVER:C:\szh\RabbitMQ Server\rabbitmq_server
Path:;%RABBITMQ_SERVER%\sbin
RabbitMQ的相关启动命令如下:
1、以应用方式启动
rabbitmq-server -detached // 后台启动
rabbitmq-server 直接启动,// 如果你关闭窗口或者需要在改窗口使用其他命令时应用就会停止
rabbitmqctl stop // 关闭
2、以服务方式启动(安装完之后在任务管理器中服务一栏能看到RabbtiMq)
rabbitmq-service install // 安装服务
rabbitmq-service start // 开始服务
Rabbitmq-service stop // 停止服务
Rabbitmq-service enable // 使服务有效
Rabbitmq-service disable // 使服务无效
rabbitmq-service help // 帮助
rabbitmqctl stop // 关闭
当rabbitmq-service install之后默认服务是enable的,如果这时设置服务为disable的话,rabbitmq-service start就会报错。
当rabbitmq-service start正常启动服务之后,使用disable是没有效果的。
3、Rabbitmq 管理插件启动,可视化界面
Rabbitmq 管理插件启动,可视化界面
rabbitmq-plugins enable rabbitmq_management // 启动
rabbitmq-plugins disable rabbitmq_management // 关闭
启动可视化界面后,在浏览器输入"ip地址:15672"可进入可视化界面。
4、Rabbitmq节点管理方式
Rabbitmqctl
2 Java代码示例
RabbitMQ的默认用户名和密码是guest:guest,默认传递消息的端口为5672,下面的代码是直接在本地测试,故访问地址为127.0.0.1
下面通过建立多个线程来模拟消息的生产和消费。
2.1 静态工厂类——获取连接
这里创建了一个静态工厂来获取连接,可以直接调用getConnection方法获取
class RabbitMQFactory{
// RabbitMQ的IP
private final static String MQ_HOST = "127.0.0.1";
// RabbitMQ的端口
private final static Integer MQ_PORT = 5672;
// RabbitMQ的用户名
private final static String USER_NAME = "guest";
// RabbitMQ的密码
private final static String PASSWORD = "guest";
// RabbitMQ工厂类
private final static ConnectionFactory connectionFactory = new ConnectionFactory();
static{
// 设置RabbitMQ连接参数
connectionFactory.setHost(MQ_HOST);
connectionFactory.setPort(MQ_PORT);
connectionFactory.setUsername(USER_NAME);
connectionFactory.setPassword(PASSWORD);
}
// 获取连接
public static Connection getConnection() throws IOException {
// 建立连接
Connection connection = connectionFactory.newConnection();
return connection;
}
}
2.2 RabbitMQ消费者线程类
class Consumer implements Runnable{
// RabbitMQ队列名称
private String queueName;
public Consumer(String queueName){
this.queueName = queueName;
}
public void run() {
Connection connection = null;
Channel channel = null;
try {
// 创建连接
connection = RabbitMQFactory.getConnection();
// 创建连接通道
channel = connection.createChannel();
/*
声明要连接的队列
参数说明:
1、name: 队列名称
2、durable: 是否持久化,为 true 则设置队列为持久化。持久化的队列会存盘,在服务器重启的时候可以保证不丢失相关信息。
3、exclusive: 是否排外的,为 true 则设置队列为排他的。如果一个队列被声明为排 他队列,该队列仅对首次声明它的连接可见,并在连接断开时自动删除。这里需要注意 三点:排他队列是基于连接( Connection) 可见的,同 个连接的不同信道 (Channel) 是可以同时访问同一连接创建的排他队列; "首次"是指如果 个连接己经声明了 排他队列,其他连接是不允许建立同名的排他队列的,这个与普通队列不同:即使该队 列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除,这种队列 适用于一个客户端同时发送和读取消息的应用场景。
4、autoDelete: 是否自动删除队列,为 true 则设置队列为自动删除。自动删除的前提是: 至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会 自动删除。不能把这个参数错误地理解为: "当连接到此队列的所有客户端断开时,这 个队列自动删除",因为生产者客户端创建这个队列,或者没有消费者客户端与这个队 列连接时,都不会自动删除这个队列。
5、args: 相关参数,如 x-rnessage-ttl 、x-expires 、x-rnax-length 、x-rnax-length-bytes、 x-dead-letter-exchange、 x-deadletter-routing-key 、 x-rnax-priority 等。
*/
channel.queueDeclare(queueName, false, false, false, null);
// 创建消费者对象,用于读取消息
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
/**
* 启动一个消费者,并返回服务端生成的消费者标识
* queue:队列名
* autoAck:true 接收到传递过来的消息后acknowledged(应答服务器),false 接收到消息后不应答服务器
* callback: 消费者对象的回调接口
* @return 服务端生成的消费者标识
*/
channel.basicConsume(queueName, true, queueingConsumer);
while (true){
// 读取队列,在读到消息前再这里阻塞,直到等到消息
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("消费者" + Thread.currentThread().getName() + "收到消息:" + message);
// 模拟执行处理消息时间
Thread.sleep(3000);
System.out.println("消费者" + Thread.currentThread().getName() + "处理完消息:" + message);
}
} catch (IOException e) {
e.printStackTrace();
}catch (InterruptedException e) {
e.printStackTrace();
}finally {
/* 关闭连接 */
try {
channel.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
channel.queueDeclare(name, durable, exclusive, autoDelete, args)方法参数说明:
1、name: 队列名称
2、durable: 是否持久化,为 true 则设置队列为持久化。持久化的队列会存盘,在服务器重启的时候可以保证不丢失相关信息。
3、exclusive: 是否排外的,为 true 则设置队列为排他的。如果一个队列被声明为排 他队列,该队列仅对首次声明它的连接可见,并在连接断开时自动删除。这里需要注意 三点:排他队列是基于连接( Connection) 可见的,同 个连接的不同信道 (Channel) 是可以同时访问同一连接创建的排他队列; "首次"是指如果 个连接己经声明了 排他队列,其他连接是不允许建立同名的排他队列的,这个与普通队列不同:即使该队 列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除,这种队列 适用于一个客户端同时发送和读取消息的应用场景。
4、autoDelete: 是否自动删除队列,为 true 则设置队列为自动删除。自动删除的前提是: 至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会 自动删除。不能把这个参数错误地理解为: “当连接到此队列的所有客户端断开时,这 个队列自动删除”,因为生产者客户端创建这个队列,或者没有消费者客户端与这个队 列连接时,都不会自动删除这个队列。
5、args: 相关参数,如 x-rnessage-ttl 、x-expires 、x-rnax-length 、x-rnax-length-bytes、 x-dead-letter-exchange、 x-deadletter-routing-key 、 x-rnax-priority 等。
channel.basicConsume(queue, autoAck, callback)方法参数说明:
1、queue:队列名
2、 autoAck:true 接收到传递过来的消息后acknowledged(应答服务器),false 接收到消息后不应答服务器
3、 callback: 消费者对象的回调接口
2.3 RabbitMQ生产者线程类
class Provider implements Runnable{
// RabbitMQ队列名称
private String queueName;
public Provider(String queueName){
this.queueName = queueName;
}
public void run() {
Connection connection = null;
Channel channel = null;
try {
// 创建连接
connection = RabbitMQFactory.getConnection();
// 创建连接通道
channel = connection.createChannel();
// 声明要连接的队列
channel.queueDeclare(queueName, false, false, false, null);
String message = "message";
// 每3秒发送一条消息,总共发送10条
for(int i = 1; i <= 10; i++){
// 创建消息队列,并且发送消息
System.out.println("生产者" + Thread.currentThread().getName() + "发布了新消息:" + message + i);
channel.basicPublish("", queueName, null, (message + i).getBytes());
Thread.sleep(2000);
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
/* 关闭连接 */
try {
channel.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
channel.basicPublish(exchange, routingKey, props, body)方法参数说明:
1、exchange: 要将消息发送到的交换器
2、routingKey: 路由KEY
3、props: 消息的其它属性,如:路由头等
4、body: 消息体
2.4 测试实例
建立一个生产者线程和两个消费者线程来实现消息的读取操作
public class RabbitMQDemo {
public static void main(String[] args) {
Provider provider = new Provider("queue");
Consumer consumer1 = new Consumer("queue");
Consumer consumer2 = new Consumer("queue");
Thread providerThread = new Thread(provider);
Thread consumerThread1 = new Thread(consumer1);
Thread consumerThread2 = new Thread(consumer2);
providerThread.start();
consumerThread1.start();
consumerThread2.start();
}
}
参考链接
1、一文搞懂 RabbitMQ 的重要概念以及安装2、Java中简单使用RabbitMQ进行消息收发3、java调用rabbitmq消息队列发送和接收消息实例4、WINDOWS环境下RABBITMQ的启动和停止命令5、RabbitMq 之queueDeclare 方法详解6、RabbitMQ之basicConsume、basicCancel、basicPublish等方法详解