2007年,Rabbit技术公司基于AMQP(Advanced Message Queuing Protocol,高级消息队列协议)开发的 RabbitMQ1.0 发布。
RabbitMQ由 Erlang 语言开发。Erlang尤其以高性能、健壮以及可伸缩性出名,是专门用于高并发和分布式的一种语言。
另外,RabbitMQ是开源的。
这张图解极其重要!!!
❶ Broker
接收和分发消息的应用,其实Broker就是RabbitMQ Server。
❷ Virtual Host
出于多用户和安全因素的设计,引入了Virtual Host的概念。这其实是一个虚拟分组(类似于namespace),多个用户使用同一个Broker的时候,会在各自的Virtual Host中创建自己的Exchange/Queue。
❸ Connection
是Producer与Broker,Consumer与Broker之间的TCP连接。
❹ Channel
如果每访问一次Broker就建立一个Connection,那么开销将是巨大的。Channel是在Connection内部建立的、相互独立的、一个线程一个的逻辑连接。你可以这么记忆:Channel就是小小Connection。
❺ Exchange
交换机是消息到到达Broker的第一站。一个Exchange可以绑定(Blinding)若干个Queue,并且Exchange可以根据消息的不同将其路由(Routing)到不同的Queue中。
❻ Queue
其实可以说Exchange和Queue组成了RabbitMQ的核心。Exchange不具备存储能力,只进行转发;消息被放到Queue中被暂存,并等待被取走。
快速说明
前两种模式发送方本质相同([面向队列]不使用交换机;实际上用的是默认的;路由键与队列同名)
channel.basicPublish("", "hello_Queue", null, "我是一个消息".getBytes());
channel.basicPublish("", "workqueue_Queue", null, "我是一个消息".getBytes());
后三种模式发送方本质相同([面向交换机]使用交换机;交换机的类型不同)
channel.basicPublish("fanout_Exchange", "", null, "我是一个消息".getBytes());
channel.basicPublish("direct_Exchange", "apple", null, "我是一个消息".getBytes());
channel.basicPublish("topic_Exchange", "apple.com", null, "我是一个消息".getBytes());
而从接收方的角度看,都是面向队列的(看图很好理解)
这里我们用一个HelloWorld来快速入门,使用的是Hello简单模式(即一个Producer,一个Consumer,不使用交换机)。
❶ 在虚拟机中安装并开启RabbitMQ服务
$ service rabbitmq-server start
$ service rabbitmq-server stop
$ service rabbitmq-server restart
❷ 新建两个模块
workspace
├── rabbitmq-producer
└── rabbitmq-consumer
❸ 在两个pom.xml中都添加依赖
<dependency>
<groupId>com.rabbitmqgroupId>
<artifactId>amqp-clientartifactId>
<version>5.6.0version>
dependency>
❹ 编写生产者代码
public class ProducerHello {
public static void main(String[] args) throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("10.211.55.4");
factory.setPort(5672);
factory.setVirtualHost("/lolivm");
factory.setUsername("admin");
factory.setPassword("admin");
// 3.创建连接(Connection)
Connection connection = factory.newConnection();
// 4.创建通道(Channel)
Channel channel = connection.createChannel();
// 5.创建队列(Queue)
channel.queueDeclare("hello_Queue", true, false, false, null);
// 6.发送消息
channel.basicPublish("", "hello_Queue", null, "我是一个消息".getBytes());
// 7.释放资源
channel.close();
connection.close();
}
}
// 参数说明
// queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map arguments)
// 1.queue:队列名称
// 2.durable:是否持久化
// 3.exclusive:是否独占
// 4.autoDelete:是否自动删除(失去最后一个消费者时)
// 5.arguments:参数
// 注意:如果存在同名队列,则不会发生创建
// basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
// 1.exchange:交换机名称
// 2.routingKey:路由名称
// 3.props:配置信息
// 4.body:发送的消息数据
❺ 编写消费者代码
public class ConsumerHello {
public static void main(String[] args) throws IOException, TimeoutException {
// 1.创建连接工厂
ConnectionFactory factory = new ConnectionFactory();
// 2.设置参数
factory.setHost("10.211.55.4");
factory.setPort(5672);
factory.setVirtualHost("/lolivm");
factory.setUsername("admin");
factory.setPassword("admin");
// 3.创建连接(Connection)
Connection connection = factory.newConnection();
// 4.创建通道(Channel)
Channel channel = connection.createChannel();
// 5.创建队列(Queue)
channel.queueDeclare("hello_Queue", true, false, false, null);
// 6.接收消息
channel.basicConsume("hello_Queue", true, new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.out.println(new String(body));
}
});
}
}
// 参数说明
// basicConsume(String queue, boolean autoAck, Consumer callback)
// 1.queue:队列名称
// 2.autoAck:是否自动确认
// 3.callback:回调对象
❻ 开启RabbitMQ图形化管理界面查看效果
// 端口号是固定的,具体IP地址要看你在哪里开的RabbitMQ服务
http://10.211.55.4:15672
Rabbit~