1、RabbitMQ是什么?
RabbitMQ是实现了AMQP(高级消息队列协议)的消息中间件的一种,RabbitMQ主要是为了实现系统之间的双向解耦而实现的,当多次进行服务器写操作时,并且这个操作对实时性的要求不是很高,也可以理解为是耗时操作,请求量比较大时,就需要一个中间层来做缓冲,慢慢处理数据。
AMQP,即 Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。AMQP 的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
RabbitMQ 是一个开源的 AMQP 实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP 等,支持 AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
2、入门示例:
(1)生产者producing:生产者,是指产生消息的一方,在程序中,向队列发送消息的一方称之为生产者。
(2)队列queue:队列,队列就是临时存储消息的地方,它可以把消息存储在内存中,或者磁盘中,存储在内存中的数据在机器挂掉后数据就会丢失,所以一般在生产环境中会将消息落到磁盘中,防止数据丢失,它更像是一个消息缓冲区一样,可以有多个生产者向队列中发送消息,也可以有多个消费者从队列中取数据
(3)消费者consuming:一个消费者会不断的从队列中读取消息,并且进行相关的业务处理
对于呢些异步并且耗时的操作,使用MQ可以将业务进行异步化,可以提升系统的响应速度,并且可以减少大流量对系统带来的冲击,RabbitMQ中最简单的模型就是这种的,一个生产者,一个消费者和一个队列,生产者不断向队列发送数据,消费者不断的消费数据。
消息发送类代码:
package com.learnning.rabbitmq.helloworld;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
/**
* rabbitmq发送消息类
*/
public class RabbitmqSendDemo {
//声明队列名称
private final static String QUEUE_DEMO_NAME = "demoqueue";
public static void main(String[] args) {
//创建链接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置rabbitmq server 的地址,默认端口为5672使用默认端口可以不用写
connectionFactory.setHost("localhost");
try {
//通过链接工厂创建一个链接
Connection connection = connectionFactory.newConnection();
//创建一个channel
Channel channel = connection.createChannel();
//声明一个队列,如果该队列不存在将会自动创建
channel.queueDeclare(QUEUE_DEMO_NAME,false,false,false,null);
String message = "Hello RabbitMQ!";
channel.basicPublish("",QUEUE_DEMO_NAME,null,message.getBytes());
System.out.println("send message ... "+ message);
}catch (Exception e){
e.printStackTrace();
}
}
}
消息接受示例:
package com.learnning.rabbitmq.helloworld;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 消息接受示例
*/
public class RabbitmqReciveDemo {
//声明队列名称
private final static String QUEUE_DEMO_NAME = "demoqueue";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("localhost");
Connection connection = connectionFactory.newConnection();
Channel channel = connection.createChannel();
//声明队列是为了防止在生产者启动之前启动消费者
channel.queueDeclare(QUEUE_DEMO_NAME,false,false,false,null);
System.out.println(" [*] Waiting for messages. To exit press CTRL+C");
//官方提供的回调接口
// we provide a callback in the form of an object that will buffer the messages until we're ready to use them.
DeliverCallback deliverCallback = (consumerTag,delivery) -> {
String message = new String(delivery.getBody(),"UTF-8");
System.out.println(" [x] Received '" + message + "'");
};
channel.basicConsume(QUEUE_DEMO_NAME, true, deliverCallback, consumerTag -> { });
}
}
声明队列时的参数说明:
/*
* 1 队列名称
* 2 如果我们声明一个持久队列,则为true(队列将在服务器重启后继续存在)
* 3 声明一个独占队列则为true,此队列仅用于本次连接使用
* 4 是否开启自动删除功能,当服务器不再使用时自动删除队列
* 5 队列的其他属性
*
*/
channel.queueDeclare(QUEUE_TASK_NAME,false,false,false,null);