首先说一下,MQ全称为Message Queue消息队列是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。(来自百度百科)
使用场景:
在项目中,将一些无需即时返回且耗时的操作提取出来,进行异步处理,而这种异步处理的方式大大的节省了服务器的请求响应时间,从而提高了系统的吞吐量。
RabbitMQ
遵循AMQP协议,用erlang语言开发,一个开源的消息代理和队列服务器,用来通过普通协议在完全不同的应用之间共享数据,或者简单地将作业排队以便让分布式服务器进行处理。
RabbitMQ的结构图:
Maven项目,添加依赖:
4.0.0
cn.itcast.rabbitmq
itcast-rabbitmq
0.0.1-SNAPSHOT
com.rabbitmq
amqp-client
3.4.1
org.slf4j
slf4j-log4j12
1.7.7
org.apache.commons
commons-lang3
3.3.2
org.springframework.amqp
spring-rabbit
1.4.0.RELEASE
public class ConnectionUtil {
public static Connection getConnection() throws Exception {
//定义连接工厂
ConnectionFactory factory = new ConnectionFactory();
//设置服务地址
factory.setHost("192.168.88.128");
//端口
factory.setPort(5672);
//设置账号信息,用户名、密码、vhost
factory.setVirtualHost("/taotao");
factory.setUsername("www");
factory.setPassword("www");
// 通过工程获取连接
Connection connection = factory.newConnection();
return connection;
}
}
生产者:
public class Send {
private final static String QUEUE_NAME = "test_queue";
public static void main(String[] argv) throws Exception {
// 获取到连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
//从连接中创建通道
Channel channel = connection.createChannel();
//声明(创建)队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//消息内容
String message="Hello World";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
channel.close();
connection.close();
}
}
public class Recv {
private final static String QUEUE_NAME="test_queue";
public static void main(String[] args) throws Exception {
//获取连接以及mq通道
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//定义队列的消费者
QueueingConsumer consumer = new QueueingConsumer(channel);
//监听队列
channel.basicConsume(QUEUE_NAME,true,consumer);//true自动模式
//获取消息
while (true)
{
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
}
}
之前也写过一篇socket编程的例子。通过这个例子感觉RabbitMQ与socket编程有相似的地方
(1)相同:
socket有服务端和客户端,RabbitMQ有生产者和消费者,都可以互通消息。
socket客户端通过new Socket('主机号','端口号');服务端通过new ServerSocket('端口号');并且通过accept()方法进行监听,等待连接;它们都是通过输入输出流交换数据。
RabbitMQ通过创建通道,创建队列
(2)不同:
socket是即时连接,像打电话,如果客户端或者服务端有一个断开,那么消息连接就会中断,信息就会丢失,而RabbitMQ会将消息放入队列,消费者从队列中取消息,不存在这个问题。