相关概念
Binding-绑定
Exchange和Queue之间的连接关系
Binding可以包含RoutingKey
Queue-消息队列
消息队列,实际存储消息数据
Durability:是否持久化
Auto delete:如果选yes,代表最后一个监听被移除之后,该Queue会自动删除
Message-消息
服务器和应用程序之间传送的数据
本质上是一段数据,由Properites和Body组成
常用属性:delivery mode(消息可以在broker做持久化,也可以在内存中做非持久化)、headers(自定义属性)
Virtual host-虚拟主机
虚拟地址,用于进行逻辑隔离,最上层的消息路由
一个Virtual Host里面可以有若干个Exchange和Queue
同一个Virtual Host里面不能有相同名称的Exchange和Queue
过程
获取连接工厂:ConnectionFactory
一个连接:Connection
数据通信信道,可以发送和接收消息:Channel
具体的消息存储队列:Queue
代码
消费者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;
public class Consumer {
public static void main(String[] args) throws Exception {
//1 创建一个ConnectionFactory, 并进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.17.17");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
// connectionFactory.setUsername("guest");
// connectionFactory.setPassword("guest");
//2 通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
//3 通过connection创建一个Channel
Channel channel = connection.createChannel();
//4 声明(创建)一个队列
String queueName = "test001";
channel.queueDeclare(queueName, true, false, false, null);
//5 创建消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//6 设置Channel
channel.basicConsume(queueName, true, queueingConsumer);
while(true){
//7 获取消息
Delivery delivery = queueingConsumer.nextDelivery();
String msg = new String(delivery.getBody());
System.err.println("消费端: " + msg);
//Envelope envelope = delivery.getEnvelope(); //可以获得消息的队列和exchange
}
}
}
channel.queueDeclare(queueName, true, false, false, null);
1、队列名称
2、是否持久化
3、是否独占 (保证消费的消息是有顺序的)
4、队列如果脱离exchange,是否会自动删除
5、扩展参数
channel.basicConsume(queueName, true, queueingConsumer);
1、消费的队列
2、是否自动签收 当消费者接受后,消费端给broker回送一条ack的消息,告诉收到,
如果false,需要代码上指定,一般是false,处理完消息后,手工返回
3、消费者对象
Envelope envelope = delivery.getEnvelope();
可以获得消息的队列和exchange
生产者
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Procuder {
public static void main(String[] args) throws Exception {
//1 创建一个ConnectionFactory, 并进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.17.17");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
// connectionFactory.setUsername("guest");
// connectionFactory.setPassword("guest");
//2 通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
//3 通过connection创建一个Channel
Channel channel = connection.createChannel();
//4 通过Channel发送数据
for(int i=0; i < 5; i++){
String msg = "Hello RabbitMQ!";
channel.basicPublish("", "test001", null, msg.getBytes());
}
//5 记得要关闭相关的连接
channel.close();
connection.close();
System.out.println("success");
}
}
channel.basicPublish("", "test001", null, msg.getBytes());
- exchange
- routingKey
- BasicProperties(修饰消息的附加属性)
- body(消息的实体)
- 如果exchange为空,使用默认的路由,此时routingkey和queue是一样的名称,如果有一样的名称才能发送成功
含有自定义消息的消费者
import java.util.Map;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.QueueingConsumer;
import com.rabbitmq.client.QueueingConsumer.Delivery;
public class Consumer {
public static void main(String[] args) throws Exception {
//1 创建一个ConnectionFactory, 并进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.17.17");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//2 通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
//3 通过connection创建一个Channel
Channel channel = connection.createChannel();
//4 声明(创建)一个队列
String queueName = "test001";
channel.queueDeclare(queueName, true, false, false, null);
//5 创建消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//6 设置Channel
channel.basicConsume(queueName, true, queueingConsumer);
while(true){
//7 获取消息
Delivery delivery = queueingConsumer.nextDelivery();
String msg = new String(delivery.getBody());
System.err.println("消费端: " + msg);
Map<String, Object> headers = delivery.getProperties().getHeaders();
System.err.println("headers get my1 value: " + headers.get("my1"));
//Envelope envelope = delivery.getEnvelope();
}
}
}
String msg = new String(delivery.getBody());
取消息体
Map<String, Object> headers = delivery.getProperties().getHeaders();
取消息头
含有自定义消息的生产者
import java.util.HashMap;
import java.util.Map;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Procuder {
public static void main(String[] args) throws Exception {
//1 创建一个ConnectionFactory, 并进行配置
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.17.17");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/");
//2 通过连接工厂创建连接
Connection connection = connectionFactory.newConnection();
//3 通过connection创建一个Channel
Channel channel = connection.createChannel();
Map<String, Object> headers = new HashMap<>();
headers.put("my1", "111");
headers.put("my2", "222");
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
.deliveryMode(2) //持久化的投递
.contentEncoding("UTF-8")
.expiration("10000") //过期时间,只存活10秒
.headers(headers)
.build();
//4 通过Channel发送数据
for(int i=0; i < 5; i++){
String msg = "Hello RabbitMQ!";
//1 exchange 2 routingKey
channel.basicPublish("", "test001", properties, msg.getBytes());
}
//5 记得要关闭相关的连接
channel.close();
connection.close();
}
}
Map<String, Object> headers = new HashMap<>();
headers.put("my1", "111");
headers.put("my2", "222");
定义消息头
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
.deliveryMode(2) //持久化的投递
.contentEncoding("UTF-8")
.expiration("10000") //存活时间,只存活10秒
.headers(headers)
.build();
deliveryMode:2为持久化投递,1为非持久化投递
expiration:存活时间
消费端自定义监听
消费端代码
channel.basicConsume(queueName, true, new MyConsumer(channel));
自定义消费者代码
import java.io.IOException;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
public class MyConsumer extends DefaultConsumer {
public MyConsumer(Channel channel) {
super(channel);
}
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.err.println("-----------consume message----------");
System.err.println("consumerTag: " + consumerTag);
System.err.println("envelope: " + envelope);
System.err.println("properties: " + properties);
System.err.println("body: " + new String(body));
}
}