第一节 RabbitMQ生产者消费者
一、基本模型
P是就是生产者,就是生产出消息的一方。
队列就是传输媒介,可理解为传输的管道。可理解为邮递员,邮递员会把把消息投递给收信人。
C是消费者,用于接收消息,可理解为收信人。
这就是最简单的消息模型。
二、使用代码
首先运行接收端的代码,它是一个阻塞方法,会一直等待发送端的消息。
然后再运行发送端的代码,发送"我养你啊"的消息。
代码步骤
第一步 让RabbimtMQ服务器与我们的应用程序产生一条可靠的连接
第二步 通过连接创建一个传输消息的"信道"。
第三步 通过信道创建队列、路由器等。
第四步 生产者向信道发送消息。信道会将消息通过队列等保存。
第五步 消费者从信道接收消息。信道会取出队列中的数据,投递给消费者。
发送端代码。
package com.rabbitmq.helloworld.demo;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author jay.zhou
* @date 2019/4/22
* @time 16:46
* 生产者
*/
public class Producer {
private static final String QUEUE_NAME = "local::queue:01";
private static final Logger LOGGER = LoggerFactory.getLogger(Producer.class);
public static void main(String[] args) {
try {
//连接管理器:我们的应用程序与RabbitMQ建立连接的管理器。
ConnectionFactory factory = new ConnectionFactory();
//设置RabbitMQ服务器地址
factory.setHost("127.0.0.1");
//设置帐号密码,默认为guest/guest,所以下面两行可以省略
factory.setUsername("guest");
factory.setPassword("guest");
//新建一个连接
Connection connection = factory.newConnection();
//再创建一个信道,这个就相当于一个邮局
//它是消息推送使用的通道。
Channel channel = connection.createChannel();
//首先在通道中申明一个队列
/**
* 第一个参数是queue:要创建的队列名
* 第二个参数是durable:是否持久化。如果为true,可以在RabbitMQ崩溃后恢复消息
* 第三个参数是exclusive:true表示一个队列只能被一个消费者占有并消费
* 第四个参数是autoDelete:true表示服务器不在使用这个队列是会自动删除它
* 第五个参数是arguments:其它参数
*/
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//创建一条消息
String message = "我养你啊!";
//采用二进制流的方式传输
byte[] msg = message.getBytes("UTF-8");
//channel是一个邮局,它接收到msg数据,并将放入到QUEUE_NAME队列中
channel.basicPublish("", QUEUE_NAME, null, msg);
LOGGER.info("发送端发送消息:{}",message);
channel.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
接收端代码。
package com.rabbitmq.helloworld.demo;
import com.rabbitmq.client.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
/**
* @author jay.zhou
* @date 2019/4/22
* @time 16:53
*/
public class MsgConsumer {
private static final String QUEUE_NAME = "local::queue:01";
private static final Logger LOGGER = LoggerFactory.getLogger(MsgConsumer.class);
public static void main(String[] args) {
try {
//连接管理器:我们的应用程序与RabbitMQ建立连接的管理器。
ConnectionFactory factory = new ConnectionFactory();
//设置RabbitMQ服务器地址
factory.setHost("127.0.0.1");
//新建一个连接
Connection connection = factory.newConnection();
//再创建一个信道,这个就相当于一个邮局
Channel channel = connection.createChannel();
//首先在通道中申明一个队列
/**
* 第一个参数是queue:要创建的队列名
* 第二个参数是durable:是否持久化。如果为true,可以在RabbitMQ崩溃后恢复消息
* 第三个参数是exclusive:true表示一个队列只能被一个消费者占有并消费
* 第四个参数是autoDelete:true表示服务器不在使用这个队列是会自动删除它
* 第五个参数是arguments:其它参数
*/
channel.queueDeclare(QUEUE_NAME, true, false, false, null);
//创建消费者,并重写如何消费的方法,我们这里仅仅就是打印一下消息啦
//首先从信道里面获取数据
Consumer consumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)
throws IOException {
String message = new String(body, "UTF-8");
LOGGER.info("收件人收到消息:{}", message);
}
};
//收到了消息后,提示邮局,我已经收到消息了。可以给我发送其它消息
//第二个参数autoAck如果为false,那么消息会一直保存在RabbimtMQ服务器
//消费者没有确认消息被消费,消息一直留在队列中,只有当从有新的消费者加入时,消息被分发到新的消费者。
channel.basicConsume(QUEUE_NAME, true, consumer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
三、自动确认autoAck
在接收端的代码的最后一句:
channel.basicConsume(QUEUE_NAME, true, consumer);
第二个参数是自动确认。第二个参数autoAck如果为false,那么消息会一直保存在RabbimtMQ服务器。
运行三次发送端。访问http://localhost:15672,登录guest/guest可以查看拿到这个队列目前已经被投递的消息。
然后我们再运行几次接收端。
每次运行接收端,都会收到三次"我养你啊"的消息。原因是,因为接收端没有确认这个消息已经被消费。所以,RabbitMQ会将消息一直保存在消息队列中。上面的Ready数值一直是3,说明消息还保存在RabbitMQ服务器中。
最后再将代码的autoAck改为true,再运行一次接收者类。队列的Ready属性变成0,说明之前的消息已经被成功消费掉。RabbitMQ服务器最终将这些消息移除。你可以亲自尝试一下哦。
四、源代码下载
源代码地址:https://github.com/hairdryre/Study_RabbitMQ
阅读更多:从头开始学RabbimtMQ目录贴