执行流程:
组成部分说明如下:
Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。 Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。 Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。 Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。 Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。
消息发布接收流程:
- ----发送消息-----
1 、生产者和Broker建立TCP连接。
2 、生产者和Broker建立通道。
3 、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。
4 、Exchange将消息转发到指定的Queue(队列)
- ---接收消息-----
1 、消费者和Broker建立TCP连接
2 、消费者和Broker建立通道
3 、消费者监听指定的Queue(队列)
4 、当有消息到达Queue时Broker默认将消息推送给消费者。
5 、消费者接收到消息。
1,创建maven项目,在pom.xml中加入依赖
<!-- rabbitmq依赖 -->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.0.3</version>
</dependency>
2,创建生产者类
package cn.pika.mq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.Queue;
import java.util.concurrent.TimeoutException;
/**
* 生产者01
*/
public class Producer01 {
//队列的名称
private static final String QUEUE="hello_queue";
public static void main(String[] args) {
Connection connection=null;
Channel channel=null;
try {
//1,创建链接的工厂对象
ConnectionFactory factory = new ConnectionFactory();
//1.1 设置链接的参数
factory.setHost("localhost"); //本地链接地址
factory.setPort(5672); //端口号
factory.setUsername("guest"); //用户名
factory.setPassword("guest"); //密码
factory.setVirtualHost("/"); //rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
//1.2 创建链接对象
connection =factory.newConnection();
//2,创建与Exchange(交换机)的通道,每个连接可以创建多个通道,每个通道代表一个会话任务
channel =connection.createChannel();
//3,声明一个队列,如果Rabbit中没有此队列将自动创建
/**
* 参数介绍:
* * param1:队列名称
* * param2:是否持久化,若持久化,mq重启后该队列仍然存在
* * param3:队列是否独占此连接,队列只允许在该连接中访问,如果连接关闭,则队列自动删除
* * param4:队列不再使用时是否自动删除此队列
* * param5:扩展参数
*/
channel.queueDeclare(QUEUE,true,false,false,null);
//4,发送消息
// 定义发送的消息内容
String message="hello word 皮卡丘~"+System.currentTimeMillis();
/**
* * param1:Exchange(交换机)的名称,如果没有指定,则使用Default Exchange 注意:不可以写null
* * param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
* * param3:消息包含的属性,没有可以写null
* * param4:消息体,要发送的消息,字节数组 byte【】类型
*/
channel.basicPublish("",QUEUE,null,message.getBytes());
System.out.println("发送的消息是:"+message);
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}finally {
try {
//5,关闭连接对象,倒着关!
if(channel != null){
channel.close();
}
if(connection != null){
connection.close();
}
} catch (IOException | TimeoutException e) {
e.printStackTrace();
}
}
}
}
3,创建消费者类
package cn.pika.mq;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* 消费者01类
*/
public class Consumer01 {
//队列的名称
private static final String QUEUE="hello_queue";
public static void main(String[] args) {
Connection connection = null;
Channel channel = null;
try {
//1,创建链接的工厂对象
ConnectionFactory factory = new ConnectionFactory();
//1.1 设置链接的参数
factory.setHost("localhost"); //本地链接地址
factory.setPort(5672); //端口号
factory.setUsername("guest"); //用户名
factory.setPassword("guest"); //密码
factory.setVirtualHost("/"); //rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
//1.2 创建链接对象
connection =factory.newConnection();
//2,创建与Exchange(交换机)的通道,每个连接可以创建多个通道,每个通道代表一个会话任务
channel =connection.createChannel();
//3,声明一个队列,如果Rabbit中没有此队列将自动创建
/**
* 参数介绍:
* * param1:队列名称
* * param2:是否持久化,若持久化,mq重启后该队列仍然存在
* * param3:队列是否独占此连接,队列只允许在该连接中访问,如果连接关闭,则队列自动删除
* * param4:队列不再使用时是否自动删除此队列
* * param5:扩展参数
*/
channel.queueDeclare(QUEUE,true,false,false,null);
//4,定义消费方法,监听到队列中有消息以后要做什么
DefaultConsumer consumer = new DefaultConsumer(channel){
//4.1重写handleDelivery()方法,消费着接受消息以后会自动调用此方法
/**
*
* @param consumerTag 消费者的标签,在channel.basicConsume()去指定
* @param envelope 消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)
* @param properties
* @param body 消息体(接受到的消息内容)
* @throws IOException
*/
@Override
public void handleDelivery(String consumerTag, Envelope envelope,
AMQP.BasicProperties properties, byte[] body) throws IOException {
//4.2 获取接收到的消息
String message=new String(body);
System.out.println("接收到的消息是:"+message);
}
};
//5,监听队列
/**
* 参数1:String queue:队列名称
* 参数2:boolean autoAck:是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动回复
* 参数3:Consumer callback:消费方法,消费者接收到消息后调用此方法
*/
channel.basicConsume(QUEUE,true,consumer);
} catch (TimeoutException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4,运行生产者,在运行消费者!
结果:消费者接收到了生产者着发送的消息。