一、模式图

- P:生产者
- C:消费者
- 中间红色:队列,可以缓存消息,生产者向其投递消息,消费者从中取出消息
二、消息传输过程
1、生产者发送消息
- 生产者和broker建立TCP连接
- 生产者和broker建立通道
- 生产者通过通道将消息发送给broker,有exchange将消息进行转发
- exchange将消息发送给指定的queue(队列)
2、消费者接收消息
- 消费者和broker建立TCP连接
- 消费者和broker建立通道
- 消费者监听指定的queue(队列)
- 当有消息到达queue时,broker默认将消息推送给消费者
- 消费者接收消息
- ACK回复
三、代码模拟(生产者和消费者绑定队列的参数必须保持一致)
1、工具类
package com.java.study.rabbitmq.utils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class RabbitMQUtils {
private static ConnectionFactory connectionFactory;
static{
//1.创建连接mq的连接工厂对象
connectionFactory = new ConnectionFactory();
//2.设置连接rabbitmq主机
connectionFactory.setHost("192.168.8.222");
//3.设置端口号
connectionFactory.setPort(5672);
//4.设置连接那个虚拟主机
connectionFactory.setVirtualHost("/ems");
//5.设置访问虚拟主机的用户名和密码
connectionFactory.setUsername("ems");
connectionFactory.setPassword("123");
}
public static Connection getConnections(){
try{
//6.获取连接
return connectionFactory.newConnection();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public static void closeConnectionAndChannel(Channel channel,Connection connection){
try {
channel.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2、生产者
package com.java.study.rabbitmq.helloworld;
import com.java.study.rabbitmq.utils.RabbitMQUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.MessageProperties;
import org.junit.Test;
/**
* 生产者 发送 消息
*/
public class Producer {
private final static String QUEUE_NAME = "hello";
@Test
public void sendMessages() throws Exception {
//6.获取连接
Connection connection = RabbitMQUtils.getConnections();
//7.获取通道
Channel channel = connection.createChannel();
//8.通道绑定对应的消息队列
//参数1:queue 队列名称,在队列不存在的情况下,自动创建
//参数2:durable 用来定义队列的特性是否要持久化(消息不会持久化) true:持久化 false:不持久化
//参数3:exclusive 是否独占队列 true:独占队列,false:不独占队列
//参数4:autoDelete 是否在消费彻底完成(消费者停掉)后自动删除队列 true:自动删除,false:不自动删除
//参数5:arguments 额外附加参数
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
String message = "hello rabbitmq";
//9.发布消息
//参数1:exchange 交换机名称
//参数2:routingKey 队列名称(由这里具体指定发送到具体哪个队列中)
//参数3:props 传递消息额外设置(由这里设置消息是否持久化,MessageProperties.PERSISTENT_TEXT_PLAIN:重启不会消失)
//参数4:body 消息的具体内容
channel.basicPublish("", QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
//关闭连接
RabbitMQUtils.closeConnectionAndChannel(channel, connection);
}
}
3、消费者
package com.java.study.rabbitmq.helloworld;
import com.java.study.rabbitmq.utils.RabbitMQUtils;
import com.rabbitmq.client.*;
import java.io.IOException;
/**
* 消费者 接收 消息
*/
public class Consumer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws Exception {
//6.获取连接
Connection connection = RabbitMQUtils.getConnections();
//7.获取通道
Channel channel = connection.createChannel();
//8.通道绑定对应的消息队列
//参数1:queue 队列名称,在队列不存在的情况下,自动创建
//参数2:durable 用来定义队列的特性是否要持久化(消息不会持久化) true:持久化 false:不持久化
//参数3:exclusive 是否独占队列 true:独占队列,false:不独占队列
//参数4:autoDelete 是否在消费彻底完成(消费者停掉)后自动删除队列 true:自动删除,false:不自动删除
//参数5:arguments 额外附加参数
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//9.消费消息
//参数1:队列名称
//参数2:开启消息的自动确认机制
//参数3:消费消息时的回调接口
channel.basicConsume(QUEUE_NAME, true, new DefaultConsumer(channel) {
//参数1:consumerTag 消费者标签,用来标识消费者的,在
//参数2:envelope 信封
//参数3:properties 消息属性
//参数4:body 消息队列中取出的消息
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
// super.handleDelivery(consumerTag, envelope, properties, body);
System.out.println("接收到的信息为:" + new String(body));
}
});
}
}