简介
RabbitMQ是一个消息代理 - 一个消息系统的媒介。它可以为你的应用提供一个通用的消息发送和接收平台,并且保证消息在传输过程中的安全。RabbitMQ实现了高级消息队列协议(AMQP)的开源消息代理软件(亦称面向消息的中间件)。其采用Erlang语言编写的,群集和故障转移是构建在开放电信平台框架上的。
特点
-
RabbitMQ是部署最广泛的开源消息代理。
-
RabbitMQ有成千上万的用户,是最受欢迎的开源消息代理之一。从T-Mobile 到Runtastic,RabbitMQ在全球范围内的小型初创企业和大型企业中都得到使用。
-
RabbitMQ轻巧,易于在内部和云中部署。它支持多种消息传递协议。RabbitMQ可以部署在分布式和联合配置中,以满足大规模,高可用性的要求。
-
RabbitMQ可在许多操作系统和云环境上运行,并为大多数流行语言提供了广泛的开发人员工具。
技术亮点
可靠性
RabbitMQ提供了多种技术可以让你在性能和可靠性之间进行权衡。这些技术包括持久性机制、投递确认、发布者证实和高可用性机制。
路由灵活
消息在到达队列前是通过交换机进行路由的。RabbitMQ为典型的路由逻辑提供了多种内置交换机类型。如果你有更复杂的路由需求,可以将这些交换机组合起来使用,你甚至可以实现自己的交换机类型,并且当做RabbitMQ的插件来使用。
集群
在相同局域网中的多个RabbitMQ服务器可以聚合在一起,作为一个独立的逻辑代理来使用。
联合
对于服务器来说,它比集群需要更多的松散和非可靠链接。为此RabbitMQ提供了联合模型。
高可用的队列
在同一个集群里,队列可以被镜像到多个机器中,以确保当其中某些硬件出现故障后,你的消息仍然安全。
多协议
RabbitMQ 支持多种消息协议的消息传递。
广泛的客户端
只要是你能想到的编程语言几乎都有与其相适配的RabbitMQ客户端。
可视化管理工具
RabbitMQ附带了一个易于使用的可视化管理工具,它可以帮助你监控消息代理的每一个环节。
追踪
如果你的消息系统有异常行为,RabbitMQ还提供了追踪的支持,让你能够发现问题所在。
插件系统
RabbitMQ附带了各种各样的插件来对自己进行扩展。你甚至也可以写自己的插件来使用。
商业支持
可以提供商业支持,包括培训和咨询。
大型社区
围绕着RabbitMQ有一个大型的社区,那儿有着各种各样的客户端、插件、指南等等。
安装rabbitMQ
若提示权限不足请加上sudo
此安装教程基于centos7
http://www.rabbitmq.com/which-erlang.html查看安装rabbitmq需要安装erlang对应的版本。
在 https://github.com/rabbitmq/erlang-rpm/releases 页面找到需要下载的erlang版本。
使用wget进行安装
wget -P /home/download https://github.com/rabbitmq/erlang-rpm/releases/download/v21.2.3/erlang-21.2.3-1.el7.centos.x86_64.rpm
安装erlang
rpm -Uvh /home/download/erlang-21.2.3-1.el7.centos.x86_64.rpm
安装 socat
yum install -y socat
安装RabbitMQ
wget -P /home/download https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.7.9/rabbitmq-server-3.7.9-1.el7.noarch.rpm
rpm -Uvh /home/download/rabbitmq-server-3.7.9-1.el7.noarch.rpm
安装完成 ,关闭防火墙
systemctl stop firewalld.service
启动和关闭
启动服务
systemctl start rabbitmq-server
查看状态
systemctl status rabbitmq-server
关闭服务
systemctl stop rabbitmq-server
设置开机自启
systemctl enable rabbitmq-server
开启Web管理插件
rabbitmq-plugins enable rabbitmq_management
rabbitmq有一个默认的guest用户,但只能通过localhost访问,所以需要添加一个能够远程访问的用户。
添加用户
rabbitmqctl add_user admin admin
为用户分配操作权限
rabbitmqctl set_user_tags admin administrator
为用户分配资源权限
rabbitmqctl set_permissions -p / admin ".*" ".*" ".*"
本地访问服务ip地址加上端口号15672即可访问Web管理页面
rabbitMQ几种工作模式
导入依赖
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>5.5.1</version>
</dependency>
simple简单模式
消息生产者将消息放入队列
消息的消费者监听消息队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列中删除
生产者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 简单队列生产者
* 使用RabbitMQ的默认交换器发送消息
*/
public class Producer {
public static void main(String[] args) {
// 创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 设置连接属性
// 此处填写你的服务IP
factory.setHost("192.168.3.36");
factory.setPort(5672);
// 填写用户名和密码
factory.setUsername("admin");
factory.setPassword("admin");
Connection connection = null;
Channel channel = null;
try {
// 从连接工厂获取连接
connection = factory.newConnection("生产者");
// 从链接中创建通道
channel = connection.createChannel();
/**
* 声明(创建)队列
* 如果队列不存在,才会创建
* RabbitMQ 不允许声明两个队列名相同,属性不同的队列,否则会报错
*
* queueDeclare参数说明:
* @param queue 队列名称
* @param durable 队列是否持久化
* @param exclusive 是否排他,即是否为私有的,如果为true,会对当前队列加锁,其它通道不能访问,并且在连接关闭时会自动删除,不受持久化和自动删除的属性控制
* @param autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除
* @param arguments 队列参数,设置队列的有效期、消息最大长度、队列中所有消息的生命周期等等
*/
channel.queueDeclare("queue1", false, false, false, null);
// 消息内容
String message = "Hello World!";
// 发送消息
channel.basicPublish("", "queue1", null, message.getBytes());
System.out.println("消息已发送!");
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} finally {
// 关闭通道
if (channel != null && channel.isOpen()) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
// 关闭连接
if (connection != null && connection.isOpen()) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
消费者
package com.study.rabbitmq.a132.simple;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 简单队列消费者
*/
public class Consumer {
public static void main(String[] args) {
// 创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 设置连接属性
factory.setHost("192.168.3.36");
factory.setUsername("admin");
factory.setPassword("admin");
Connection connection = null;
Channel channel = null;
try {
// 从连接工厂获取连接
connection = factory.newConnection("消费者");
// 从链接中创建通道
channel = connection.createChannel();
channel.queueDeclare("queue1", false, false, false, null);
// 定义收到消息后的回调
DeliverCallback callback = new DeliverCallback() {
public void handle(String consumerTag, Delivery message) throws IOException {
System.out.println("收到消息:" + new String(message.getBody(), "UTF-8"));
}
};
//监听队列
channel.basicConsume("queue1", true, callback, new CancelCallback() {
public void handle(String consumerTag) throws IOException {
}
});
System.out.println("开始接收消息");
System.in.read();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} finally {
// 关闭通道
if (channel != null && channel.isOpen()) {
try {
channel.close();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
// 关闭连接
if (connection != null && connection.isOpen()) {
try {
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
work工作模式(资源的竞争)
消息产生者将消息放入队列。
消费者可以有多个,同时监听同一个队列。C1 C2共同争抢当前的消息队列内容,谁先拿到谁负责消费消息。
publish/subscribe发布订阅(共享资源)
X代表交换机(rabbitMQ内部组件),消息产生者将消息放入交换机,交换机发布订阅把消息发送到所有消息队列中,对应消息队列的消费者拿到消息进行消费(广播)
routing路由模式
消息生产者将消息发送给交换机按照路由判断,交换机根据路由的key,只能匹配上路由key对应的消息队列,对应的消费者才能消费消息。
消息生产者
channel.basicPublish("routing-exchange", "black", null, message.getBytes());
将消息发送到routing-exchange交换机上,路由key为black
topic 主题模式(路由模式的一种)
- #代表通配符
*代表多个单词,#代表一个单词
路由功能添加模糊匹配
消息产生者产生消息,把消息交给交换机
交换机根据key的规则模糊匹配到对应的队列,由队列的监听消费者接收消息消费
RPC模式
远程过程调用,消息生产者发送一个消息,等待一个返回结果。