1、什么是MQ
消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已。
其主要用途:不同进程Process/线程Thread之间通信。
1.1 MQ产生的原因
- 不同进程(process)之间传递消息时,两个进程之间耦合程度过高,改动一个进程,引发必须修改另一个进程,为了隔离这两个进程,在两进程间抽离出一层(一个模块),所有两进程之间传递的消息,都必须通过消息队列来传递,单独修改某一个进程,不会影响另一个;
- 不同进程(process)之间传递消息时,为了实现标准化,将消息的格式规范化了,并且,某一个进程接受的消息太多,一下子无法处理完,并且也有先后顺序,必须对收到的消息进行排队,因此诞生了事实上的消息队列;
2、RabbitMQ
2.1 RabbitMQ的简介
- MQ是Message Queue,消息队列时应用程序和应用程序之间的通信方法。
- RabbitMQ是一个开源的,在AMQP基础上完整的、可复用的企业消息系统。
- 支持主流的操作系统,linux、windows、MacOX等。
- 多种开发语言支持,Java、Python、Ruby、.NET、PHP、C/C++、node.js等
开发语言是Erlang - 面向并发的编程语言。
[外链图片转存失败(img-87sVK1k5-1562122094571)(D:\笔记整理\消息队列\消息队列2.assets\1561514353934.png)]
2.1.1 AMQP
AMQP是消息队列的一个协议。
[外链图片转存失败(img-3Zbfyg1T-1562122094572)(D:\笔记整理\消息队列\消息队列2.assets\1561514652639.png)]
2.2 rabbitMQ的五种队列
[外链图片转存失败(img-50P69anz-1562122094573)(D:\笔记整理\消息队列\消息队列2.assets\1561515639419.png)]
首先引入pom文件
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.4.1</version>
</dependency>
工具类ConnectionUtils.java
package com.example.demo_mq.util;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class ConnectionUtils {
public static Connection getConnection(){
return getConnection("192.168.93.129", 5672, "/", "haosc", "123456");
}
public static Connection getConnection(String host, int port, String vHost, String userName, String passWord){
try {
//1、定义连接工厂
ConnectionFactory factory = new ConnectionFactory();
//2、设置服务器地址
factory.setHost(host);
//3、设置端口
factory.setPort(port);
//4、设置虚拟主机、用户名、密码
factory.setVirtualHost(vHost);
factory.setUsername(userName);
factory.setPassword(passWord);
//5、通过连接工厂获取连接
Connection connection = factory.newConnection();
return connection;
}catch (Exception e){
System.out.println("创建连接异常");
e.printStackTrace();
}
return null;
}
}
2.2.1 简单队列
[外链图片转存失败(img-a7cllzlp-1562122094573)(D:\笔记整理\消息队列\消息队列2.assets\1561516769138.png)]
一个生产者对应一个消费者!!!
生产者将消息发送到“hello”队列。消费者从该队列接收消息。
生产者将消息发送到“hello”队列。消费者从该队列接收消息。
生产者:
package com.example.demo_mq.samplequeue;
import com.example.demo_mq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
public class Producer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception{
//1、获取连接
Connection connection = ConnectionUtils.getConnection("192.168.93.129",5672,"/","haosc","123456");
//2、声明信道
Channel channel = connection.createChannel();
//3、声明(创建)队列
/**
* param1:队列名
* param2:是否持久化
* param3:是否排外
* param4:是否自动删除
* param5:其他参数
*/
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4、定义消息内容
String message = "sample rabbitmq queue.";
//5、发布消息
/**
* param1:交换器名称
* param2:队列名称
* param3:一些配置参数
* param4:消息内容
*/
channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
System.out.println("[x] Sent'"+message+"'");
//6、关闭通道
channel.close();
//7、关闭连接
connection.close();
}
}
消费者:
package com.example.demo_mq.samplequeue;
import com.example.demo_mq.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
public class Consumer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception {
//1、获取连接
Connection connection = ConnectionUtils.getConnection("192.168.93.129", 5672, "/", "haosc", "123456");
//2、声明通道
Channel channel = connection.createChannel();
//3、声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4、定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5、监听队列
/*
true:表示自动确认,只要消息从队列中获取,无论消费者获取到消息后是否成功消费,都会认为消息已经成功消费
false:表示手动确认,消费者获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,
如果消费者一直没有反馈,那么该消息将一直处于不可用状态,并且服务器会认为该消费者已经挂掉,不会再给其
发送消息,直到该消费者反馈。
*/
channel.basicConsume(QUEUE_NAME, true, queueingConsumer);
//6、获取消息
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println(" [x] Received '" + message + "'");
}
}
}
剩下的几种模式在我下篇文章中