参考:
https://www.rabbitmq.com/getstarted.html
1、简单模式
- 一个生产者,一个队列,一个消费者。
- 生产者生产消息放入队列,消费者监听消息队列,如果队列中有消息,就消费掉,消息被拿走后,自动从队列中删除
未定义和指定Exchange的情况下,使用的是AMQP default这个内置的Exchange。
消息可能没有被消费者正确处理,造成消息的丢失
2、工作队列模式
- 一个生产者,一个队列,多个消费者。但多个消费者中只会有一个会成功地消费消息
- 生产者将消息放入队列,多个消费者同时监听同一个队列,谁先抢到谁负责消费消息
高并发情况下,可能会导致某一个消息被多个消费者消费
3、发布/订阅模式
- 一个生产者,一个交换机,多个队列,多个消费者。每个消费队列中消息一致,且每个消息消费者都从自己的消息队列的第一个消息开始消费,直到最后
- 交换机为rabbitMQ中内部组件。消息生产者将消息发送给rabbitMQ后,rabbitMQ会根据订阅的消费者个数,生成对应数目的消息队列,每个消费者都能获取生产者发送的全部消息
4、路由模式
- 一个消息生产者,一个交换机,多个队列,多个消息消费者。
- 一个交换机绑定多个消息队列,每个消息队列都有自己唯一的Routekey,每个消费者监听对应的消息队列
- 生产者将消息发送给交换机,交换机按照路由判断,将路由到的RouteKey的消息,推送与之绑定的队列,对应的消费者才能消费消息
5、Topics模式
同上,只是routeKey不是固定的值,而是正则表达式
6、RPC模式
- 客户端即是生产者也是消费者,向RPC请求队列发送RPC调用消息,同时监听RPC响应队列。
- 服务端监听RPC请求队列的消息,收到消息后执行服务端的方法,得到方法返回的结果。
- 服务端将RPC方法 的结果发送到RPC响应队列。
- 客户端(RPC调用方)监听RPC响应队列,接收到RPC调用结果。
7、Publisher Confirms发送发确认模式
- 生产者将信道设置成confirm模式,一旦信道进入confirm模式,所有在该信道上面发布的消息都会被指派一个唯一的ID
- 一旦消息被投递到所有匹配的队列之后,broker就会发送一个ack给生产者(包含消息的唯一ID),通知生产者消息已经正确到达目的队列了,如果消息和队列是可持久化的,那么确认消息会将消息写入磁盘之后发出。
- 若生产者等待ack超时或者broker发出的不是ack而是nack(内部错误或者网络问题导致消息丢失),可进行异常捕获或者监听nack
client有3种策略实现生产者confirm模式:
- 普通confirm模式:每发送一条消息后,调用waitForConfirms()方法,等待服务器端confirm。实际上是一种串行confirm了
while (thereAreMessagesToPublish()) {
byte[] body = ...;
BasicProperties properties = ...;
channel.basicPublish(exchange, queue, properties, body);
// uses a 5 second timeout
channel.waitForConfirmsOrDie(5_000);
}
- 批量confirm模式:每发送一批消息后,调用waitForConfirms()方法,等待服务器端confirm
int batchSize = 100;
int outstandingMessageCount = 0;
while (thereAreMessagesToPublish()) {
byte[] body = ...;
BasicProperties properties = ...;
channel.basicPublish(exchange, queue, properties, body);
outstandingMessageCount++;
if (outstandingMessageCount == batchSize) {
channel.waitForConfirmsOrDie(5_000);
outstandingMessageCount = 0;
}
}
if (outstandingMessageCount > 0) {
channel.waitForConfirmsOrDie(5_000);
}
- 异步confirm模式:提供2个回调方法,服务端confirm了一条或者多条消息后Client端会回调这个方法,低于或等于序列号的消息都将被ack或者nack
Channel channel = connection.createChannel();
channel.confirmSelect();
channel.addConfirmListener((sequenceNumber, multiple) -> {
// code when message is confirmed
}, (sequenceNumber, multiple) -> {
// code when message is nack-ed
});
8、事务模式
RabbitMQ中事务默认关闭,与事务机制有关的方法有三个:
- txSelect() 用于将当前channel设置成transaction模式
- txCommit() 用于提交事务
- txRollback() 用于回滚事务
txSelect开启事务之后,发布消息给broker服务器,如果txCommit提交成功了,则代表消息一定到达了broker了;如果在txCommit执行之前broker崩溃或者其他原因抛出异常,可以捕获异常通过txRollback回滚事务。
try {
channel.txSelect();
channel.basicPublish(exchange, routingKey, MessageProperties.PERSISTENT_TEXT_PLAIN, msg.getBytes());
channel.txCommit();
} catch (Exception e) {
e.printStackTrace();
channel.txRollback();
}
confirm模式与transaction模式都能保证消息从生产者到broker正确性,两者不能同时开启。transaction模式是同步操作,confirm模式支持异步,性能更优