个人笔记
概念
简单消息机制模型:
上图中,“ p”是生产者,“ c”是消费者。中间的框是一个队列—— RabbitMQ 代表使用者保存的消息缓冲区。
内部结构基础模型:
上图中,需要了解的名词以及概念:
Broker:可以简单的理解为安装了RabbitMQ服务的这台机器就可以称为一个Broker
Exchange:交换机,消息经由它,通过路由键来判断并决定把消息投递给哪个队列,它类似于一个路由器的角色
Queue:队列,最终将消息投递到队列中,由消费端监听队列进行消费
Binding:绑定关系,需要给交换机绑定队列,绑定时需要给一个路由键
Routingkey:路由键,交换机和队列进行绑定时,需要指定路由键或通配符路由键。
交换机根据路由键来决定消息投递到哪个或哪些队列
大致流程:使用RabbitMQ前,首先需要根据业务来创建交换机和队列,创建完成后需要给交换机绑定队列(交换机和队列可以是多对多的关系),绑定队列时要指定具体的路由键或者通配符路由键
当生产者发送一条消息的时候,需要指定交换机和路由键,消息到达Broker后先转给刚才指定的交换机,交换机再根据路由键来决定把消息投递给与自己绑定的哪一个或哪一些队列,最后再由消费端来监听这些队列,消费处理对应的消息
创建连接:
public static Channel getChannel() throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setPassword("guest");
factory.setHost("guest");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
return channel;
}
生产者创建:
public static void send() throws IOException {
Channel channel = MqConnectionUtils.getChannel();
channel.queueDeclare(QUEUE_NAME, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null);
String message = "hello world ";
for (int i = 0; i < 10; i++) {
String x = message + i;
channel.basicPublish("", QUEUE_NAME, MessageProperties.MINIMAL_BASIC, x.getBytes());
}
}
方法参数说明:
queueDeclare(String queue, Boolean durable, Boolean exclusive, Boolean autoDelete, IDictionary arguments);
queue:队列的名称。
durable:设置是否持久化。为true则设置队列为持久化。持久化的队列会存盘,在服务器重启的时候可以保证不丢失相关信息。
exclusive:设置是否排他。为true则设置队列为排他的。如果一个队列被声明为排他的队列,该队列仅对首次声明它的连接可见,并在连接断开时自动删除。这里需要注意三点:排他的队列是基于连接(Connection)可见的,同一个连接的不同信道(Channel)是可以同时访问同一连接创建的排他队列;“首次”是指如果一个连接已经声明了一个排他队列,其它连接是不允许建立同名的排他队列的,这个与普通队列不同;即使该队列是持久化的,一旦连接关闭或者客户端退出,该排他队列都会被自动删除,这种队列适用于一个客户端同时发送和读取消息的应用场景。
autoDelete:设置是否自动删除。为true则设置队列为自动删除的。自动删除的前提是:至少有一个消费者连接到这个队列,之后所有与这个队列连接的消费者都断开时,才会自动删除(即使队列中存在消息)。不能把这个参数删除的理解为:“当连接到此队列的所有客户端都断开时,这个队列自动删除”,因为生产者客户端创建这个队列,或者没有消费者客户端与这个队列连接时,都不会自动删除这个队列。
arguments:设置队列的其他一些参数,如x-message-ttl、x-expires、x-max-length、x-max-length-bytes、x-dead-letter-exchange、x-dead-letter-routing-key、x-max-priority等。
basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
exchange: 要将消息发送到的交换器
routingKey: 路由KEY 若不存在则可填写队列
props: 消息的其它属性,如:路由头等
body: 消息体
props:
使用MessageProperties类:
MINIMAL_BASIC:默认设置,什么参数都没有设置
MINIMAL_PERSISTENT_BASIC:仅仅设置 deliveryMode为2
BASIC :内容类型为以流的方式, deliveryMode为1, 优先级为0
PERSISTENT_BASIC :内容类型为以流的方式, deliveryMode为2, 优先级为0
TEXT_PLAIN :内容类型为以文本的方式, deliveryMode 为1, 优先级为0
PERSISTENT_TEXT_PLAIN :内容类型为以文本的方式, deliveryMode 为2, 优先级为0
消费者创建:
public static void recOne() throws IOException {
Channel channel = MqConnectionUtils.getChannel();
channel.queueDeclare(QUEUE_NAME, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, null);
DeliverCallback deliverCallback = (consumerTag, deliver) -> {
String message = new String(deliver.getBody(), StandardCharsets.UTF_8);
System.out.println("消费者1:" + message);
};
channel.basicConsume(QUEUE_NAME, Boolean.TRUE, deliverCallback, consumerTag -> {
});
}
方法参数说明:
basicConsume(String queue, boolean autoAck, DeliverCallback deliverCallback, CancelCallback cancelCallback);
queue:队列的名称。
autoAck:true 接收到传递过来的消息后acknowledged(应答服务器),false 接收到消息后不应答服务器
deliverCallback: 当一个消息发送过来后的回调接口
cancelCallback:当一个消费者取消订阅时的回调接口;取消消费者订阅队列时除了使用{@link Channel#basicCancel}之外的所有方式都会调用该回调方法