RabbitMQ详解(三)------RabbitMQ的五种模式
RabbitMQ详解(三)------RabbitMQ的五种模式
1.简单队列(模式)
上一篇文章末尾的实例给出的代码就是简单模式.
一个生产者对应一个消费者!!!
pom.xml
必须导入RabbitMQ依赖包
<!--RabbitMQ-client-->
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.6.2</version>
</dependency>
ConnectionUtil.java
package org.alva.Utils;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* <一句话描述>,RabbitMQ的连接工具类
* <详细介绍>,
*
*/
public class ConnectionUtil {
public static Connection getConnection(String host, int port, String vhost, String username, String password) throws IOException, TimeoutException {
//1.定义连接工厂
ConnectionFactory connectionFactory = new ConnectionFactory();
//2.设置服务器地址
connectionFactory.setHost(host);
//3.设置端口
connectionFactory.setPort(port);
//4.设置虚拟主机,用户名,密码
connectionFactory.setVirtualHost(vhost);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
//5.通过连接工厂获取连接
Connection connection = connectionFactory.newConnection();
return connection;
}
}
Consumer.java
package org.alva.RabbitMQ;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* <一句话描述>,消费者
* <详细介绍>,
*
*/
public class Consumer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明通道
Channel channel = connection.createChannel();
//3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5.监听队列
/*
true:表示自动确认,只要消息从队列中获取,无论消费者获取到消息后是否成功消费,都会认为消息成功消费.
false:表示手动确认,消费者获取消息后,服务器会将该消息标记为不可用状态,等待消费者的反馈,
如果消费者一直没有反馈,那么该消息将一直处于不可用状态,并且服务器会认为该消费者已经挂掉,不会再给其发送消息,
直到该消费者反馈.
*/
channel.basicConsume(QUEUE_NAME,true,queueingConsumer);
//6.获取消息
while (true){
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[x] Received '" + message + "'");
}
}
}
Productor.java
package org.alva.RabbitMQ;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.alva.Utils.ConnectionUtil;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
* <一句话描述>,生产者
* <详细介绍>,
*
*/
public class Producer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] args) throws IOException, TimeoutException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明通道
Channel channel = connection.createChannel();
//3.声明(创建)队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//4.定义消息内容
String message = "hello rabbitmq";
//5.发布消息
channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
System.out.println("[x] send'"+message+"'");
//6.关闭通道和连接
channel.close();
connection.close();
}
}
2.work模式
一个生产者对应多个消费者,但是只能有一个消费者获得消息!!!
竞争消费者模式.
生产者
package org.alva.RabbitMQ.WorkModel; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,生产者
* <详细介绍>,Work模式下的生产者
*
*/
public class Producter {
public static final String QUEUE_NAME = "work_queue"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明(创建)队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.定义消息内容,发布多条消息
for (int i = 0; i < 10; i++) {
String message = "hello rabbitmq " + i;
//5.发布消息
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println("[x] send message is '" + message + "'");
//6.模拟发送消息延时,便于展示多个消费者竞争接受消息
Thread.sleep(i * 10);
}
//7.关闭信道
channel.close();
//8.关闭连接
connection.close();
}
}消费者
需要创建两个消费者.
消费者1:每接收一条消息后休眠10毫秒.
package org.alva.RabbitMQ.WorkModel; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,消费者
* <详细介绍>,Work模式下的消费者
*
*/
public class Consumer1 {
public static final String QUEUE_NAME = "work_queue"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明通道
Channel channel = connection.createChannel();
//3.声明队列
channel.queueDeclare(QUEUE_NAME,false,false,false,null);
//同一时刻服务器只会发送一条消息给消费者
// channel.basicQos(1); //4.定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5.监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
//6.获取消息
while (true){
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[x] received message : '"+message+"'");
//休眠10毫秒
Thread.sleep(10);
//返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
}
}
}消费者2:每接收一条消息后休眠1000毫秒
package org.alva.RabbitMQ.WorkModel; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,
* <详细介绍>,
*
*/
public class Consumer2 {
public static final String QUEUE_NAME = "work_queue"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
// channel.basicQos(1);
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME,false,queueingConsumer);
while (true){
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[x] received message : '" + message + "'");
Thread.sleep(1000);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(),false);
}
}
}测试结果
首先生产者一次打印从0-9条消息
然后是消费者1:结果为打印偶数条消息(注:先启动的消费者为消费者1)
消费者2:结果为打印奇数条消息
结论:
*消费者1和消费者2获取到的消息内容是不同的,也就是说同一个消息只能被一个消费者获取.
*消费者1和消费者2分别获取奇数条消息和偶数条消息,两种获取消息的条数是一样的.
前面我们说这种模式是竞争消费者模式,一条队列被多个消费者监听,这里两个消费者,其中消费者1和消费者2在获取消息后分别休眠了10毫秒和1000毫秒,也就是说两个消费者获取消息的效率是不一样的,但是结果却是两者获得的消息条数是一样的,这根本不构成竞争关系,那么我们应该怎么办才能让工作效率更高的消费者获取消息更多,也就是消费者1获取消息更多呢?
能者多劳
channel.basicQos(1);
增加如上代码,表示同一时刻服务器只会发送一条消息给消费者.消费者1和消费者2获取消息结果如下:
应用场景
效率高的消费者消费消息多,可以用来进行负载均衡.
3.发布/订阅模式
一个消费者将消息首先发送到交换器,交换器绑定多个队列,然后被监听该队列的消费者所接收并消费.
*在RabbitMQ中,交换器主要有四种类型:direct,fanout,topic,headers,这里的交换器是fanout.
生产者
package org.alva.RabbitMQ.PublishModel; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,发布/订阅模式下的生产者
* <详细介绍>,
*
*/
public class Producer {
private final static String EXCHANGE_NAME = "fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5674, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明交换器
channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
//4.定义消息内容
String message = "hello rabbitmq";
//5.发布消息
channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
System.out.println("[x] send'" + message + "'");
//6.关闭通道和连接
channel.close();
connection.close(); }
}消费者
消费者1:
package org.alva.RabbitMQ.PublishModel; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,消费者
* <详细介绍>,发布/订阅模式下的消费者
*
*/
public class Consumer1 {
public static final String QUEUE_NAME = "fanout_queue_1"; public static final String EXCHANGE_NAME = "fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明交换器
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.绑定队列到交换器
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "");
//同一时刻服务器只会发送一条消息给消费者
channel.basicQos(1); //5.定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5.监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME, false, queueingConsumer);
//6.获取消息
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[消费者1] received message : '" + message + "'");
//休眠10毫秒
Thread.sleep(10);
//返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}消费者2:
package org.alva.RabbitMQ.PublishModel; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,
* <详细介绍>,
*
*/
public class Consumer2 {
public static final String QUEUE_NAME = "fanout_queue_2"; private final static String EXCHANGE_NAME = "fanout_exchange"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
Channel channel = connection.createChannel();
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
channel.queueBind(QUEUE_NAME,EXCHANGE_NAME,"");
channel.basicQos(1);
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
channel.basicConsume(QUEUE_NAME, false, queueingConsumer);
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[消费者2] received message : '" + message + "'");
Thread.sleep(1000);
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}注意:消费者1和消费者2两者监听的队列名称是不一样的.
测试结果
消费者1和消费者2都消费了该消息.
ps:这是因为消费者1和消费者2都监听了被同一个交换器绑定的队列.如果消息发送到没有队列绑定的交换器时,消息将丢失,因为交换器没有存储消息的能力,消息只能存储在队列中.
应用场景:
比如一个商城系统需要在管理员上传新的商品图片时,前台系统必须更新图片,日志系统必须记录相应的日志,那么就可以将两个队列绑定到图片上传交换器上,一个用于前台系统刚更新图片,另一个用于日志系统记录日志.
4.路由模式
生产者将消息发送到direct交换器,在绑定队列和交换器的时候有一个路由key,生产者发送的消息会指定一个路由key,那么消息只会发送到相应key相同的队列,接着监听该队列的消费者消费信息.
生产者
package org.alva.RabbitMQ.DirectExchange; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,路由模式下的生产者
* <详细介绍>,
*
*/
public class Producer {
private final static String EXCHANGE_NAME = "direct_exchange"; public static void main(String[] args) throws IOException, TimeoutException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5674, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明交换器,类型为direct
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
//4.定义消息内容
String message = "hello rabbitmq";
//5.发布消息
channel.basicPublish(EXCHANGE_NAME, "update", null, message.getBytes());
System.out.println("[x] send'" + message + "'");
//6.关闭通道和连接
channel.close();
connection.close(); }
}消费者
消费者1:
package org.alva.RabbitMQ.DirectExchange; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,消费者
* <详细介绍>,路由模式下的消费者1
* <p>
* 这种模式添加了一个路由键,生产者发布消息的时候添加路由键,消费者绑定队列到交换机时添加键值,
* 这样就可以接收到需要接收的消息。
*
*/
public class Consumer1 {
public static final String QUEUE_NAME = "direct_queue_1"; public static final String EXCHANGE_NAME = "direct_exchange"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.绑定队列到交换器,指定路由key为update
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "update");
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "delete");
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "add");
//同一时刻服务器只会发送一条消息给消费者
channel.basicQos(1); //5.定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5.监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME, false, queueingConsumer);
//6.获取消息
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[消费者1] received message : '" + message + "'");
//休眠10毫秒
Thread.sleep(10);
//返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}消费者2:
package org.alva.RabbitMQ.DirectExchange; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,消费者
* <详细介绍>,路由模式下的消费者2
*
*/
public class Consumer2 {
public static final String QUEUE_NAME = "direct_queue_2"; public static final String EXCHANGE_NAME = "direct_exchange"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.绑定队列到交换器,指定路由key为select
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "select");
//同一时刻服务器只会发送一条消息给消费者
channel.basicQos(1); //5.定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5.监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME, false, queueingConsumer);
//6.获取消息
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[消费者1] received message : '" + message + "'");
//休眠10毫秒
Thread.sleep(10);
//返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}测试结果
生产者发布消息,指定的路由key为update,消费者1绑定队列和交换器时key分别是update/delete/add;消费者2绑定队列和交换器时key时select.
所以可以猜到生产者发送的消息,只有消费者1能够接收并消费,而消费者2是不能接收的.
应用场景
利用消费者能够有选择性的接收消息的特性,比如商场系统的后台管理系统对于商品进行修改、删除、新增操作都需要更新前台系统的界面展示,而查询操作不需要,那么这两个队列分开接收消息就比较好.
5.主题模式
上面的路由模式是根据路由key进行完整的匹配(完全相等才发送消息),这里的通配符模式通俗的来讲就是模糊匹配.
符号"#"表示匹配一个或多个词,符号"*"表示匹配一个词.
生产者
package org.alva.RabbitMQ.TopicExchange; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,主题模式下的生产者
* <详细介绍>,
*
*/
public class Producer {
private final static String EXCHANGE_NAME = "topic_exchange"; public static void main(String[] args) throws IOException, TimeoutException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5674, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明交换器,类型为direct
channel.exchangeDeclare(EXCHANGE_NAME, "topic");
//4.定义消息内容
String message = "hello rabbitmq";
//5.发布消息
channel.basicPublish(EXCHANGE_NAME, "update.Name", null, message.getBytes());
System.out.println("[x] send'" + message + "'");
//6.关闭通道和连接
channel.close();
connection.close(); }
}消费者1
package org.alva.RabbitMQ.TopicExchange; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,消费者
* <详细介绍>,主题模式下的消费者1
*
*/
public class Consumer1 {
public static final String QUEUE_NAME = "topic_queue_1"; public static final String EXCHANGE_NAME = "topic_exchange"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5673, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.绑定队列到交换器,指定路由key为update
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "update.#");
//同一时刻服务器只会发送一条消息给消费者
channel.basicQos(1); //5.定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5.监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME, false, queueingConsumer);
//6.获取消息
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[消费者1] received message : '" + message + "'");
//休眠10毫秒
Thread.sleep(10);
//返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}消费者2
package org.alva.RabbitMQ.TopicExchange; import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;
import org.alva.Utils.ConnectionUtil; import java.io.IOException;
import java.util.concurrent.TimeoutException; /**
* <一句话描述>,消费者
* <详细介绍>,主题模式下的消费者2
*
* @author 穆国超
* @since 设计wiki | 需求wiki
*/
public class Consumer2 {
public static final String QUEUE_NAME = "topic_queue_2"; public static final String EXCHANGE_NAME = "topic_exchange"; public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
//1.获取连接
Connection connection = ConnectionUtil.getConnection("localhost", 5672, "/", "guest", "guest");
//2.声明信道
Channel channel = connection.createChannel();
//3.声明队列
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
//4.绑定队列到交换器,指定路由key为select
channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "select.#");
//同一时刻服务器只会发送一条消息给消费者
channel.basicQos(1); //5.定义队列的消费者
QueueingConsumer queueingConsumer = new QueueingConsumer(channel);
//5.监听队列,手动返回完成状态
channel.basicConsume(QUEUE_NAME, false, queueingConsumer);
//6.获取消息
while (true) {
QueueingConsumer.Delivery delivery = queueingConsumer.nextDelivery();
String message = new String(delivery.getBody());
System.out.println("[消费者1] received message : '" + message + "'");
//休眠10毫秒
Thread.sleep(1000);
//返回确认状态
channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);
}
}
}分析结果
生产者发送消息绑定的路由key为update.Name;消费者1监听的队列和交换器绑定路由key为update.#;消费者2监听的队列和交换器绑定路由key为select.#.
很显然,消费者1会接收到消息,而消费者2接收不到
6.四种交换器
前面介绍了五种队列模式,但是实际上只有三种,第一种简单队列,第二种工作模式,剩下的三种都是和交换器绑定的合起来称为一种,这节详细介绍交换器.
交换器分为四种,分别是:direct,fanout,topic和headers.
前三种分别对应路由模式,发布订阅模式和通配符模式,headers交换器允许匹配AMQP消息的header而非路由键,除此之外,header交换器和direct交换器完全一致,但是性能却差很多,因此基本上不会用到该交换器,这不做详细介绍.
direct
如果路由键完全匹配的话,消息才会被投放到相应的队列.
fanout
当发送一条消息到fanout交换器上时,它会把消息投放到所有附加在此交换器的上的队列.
topic
设置模糊的绑定方式,"*"操作符将"."视为分隔符,匹配单个字符;"#"操作符没有分块的概念,它将任意"."均视为关键字的匹配部分,能够匹配多个字符.
7.总结
关于RabbitMQ的五种队列,其实实际使用最多的是最后一种主题模式,通过模糊匹配,使得操作更加自如.
RabbitMQ详解(三)------RabbitMQ的五种模式的更多相关文章
- rabbitmq五种模式详解(含实现代码)
一.五种模式详解 1.简单模式(Queue模式) 当生产端发送消息到交换机,交换机根据消息属性发送到队列,消费者监听绑定队列实现消息的接收和消费逻辑编写.简单模式下,强调的一个队列queue只被一个消 ...
- spring-boot(五) RabbitMQ详解 定时任务
学习文章来自:springboot(八):RabbitMQ详解 springboot(九):定时任务 RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分 ...
- .Net使用RabbitMQ详解 转载http://www.cnblogs.com/knowledgesea/p/5296008.html
.Net使用RabbitMQ详解 序言 这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其 ...
- Spring Boot(八):RabbitMQ详解
Spring Boot(八):RabbitMQ详解 RabbitMQ 即一个消息队列,主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用. 消息中间件在互联网公司的使用中越来越多 ...
- RabbitMQ传输原理、五种模式
本文代码基于SpringBoot,文末有代码连接 .首先是一些在Spring Boot的一些配置和概念,然后跟随代码看下五种模式 MQ两种消息传输方式,点对点(代码中的简单传递模式),发布/订阅(代码 ...
- RabbitMQ详解(一)------简介与安装(Docker)
RABBITMQ详解(一)------简介与安装(DOCKER) 刚刚进入实习,在学习过程中没有接触过MQ,RabbitMQ 这个消息中间件,正好公司最近的项目中有用到,学习了解一下. 首先什么是MQ ...
- Java线程创建形式 Thread构造详解 多线程中篇(五)
Thread作为线程的抽象,Thread的实例用于描述线程,对线程的操纵,就是对Thread实例对象的管理与控制. 创建一个线程这个问题,也就转换为如何构造一个正确的Thread对象. 构造方法列表 ...
- 执行对象Statement、PreparedStatement和CallableStatement详解 JDBC简介(五)
执行对象是SQL的执行者,SQL是“安排好的任务”,执行对象就是“实际工作的人”. 执行对象有三种: Statement.PreparedStatement和CallableStatement,他们都 ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
随机推荐
- Ubuntu 14.04 LTS 系统空间不足,输入密码后,无法进入桌面的解决办法
问题场景:系统空间不足,在没有清理空间的情况下,重启机器,可能会出现,输入密码后,无法进入桌面的现象. 如何解决? 解决方法:以访客身份登录系统,可以看到你的ip地址,然后以ssh的方式登录你的主机, ...
- 查看java内存情况命令
转自:http://boendev.iteye.com/blog/882479 jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程 ...
- IOS gallery
https://github.com/mengxianliang/XLCardSwitch
- thinkphp5中使用PHPExcel(转载)
thinkphp5中可以使用composer来获取第三方类库,使用起来特别方便,例如:可是使用composer下载PHPMailer,think-captcha(验证码)等等…… 接下来说一下怎么使用 ...
- 多线程之批量插入小demo
多线程之批量插入 背景 昨天在测试mysql的两种批量更新时,由于需要入库大量测试数据,反复执行插入脚本,过程繁琐,档次很低,测试完后我就想着写个批量插入的小demo,然后又想写个多线程的批量插入的d ...
- PAT甲级1080 Graduate Admission【模拟】
题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805387268571136 题意: 模拟高考志愿录取. 考生根据总 ...
- CLOSE_WAIT状态的原因与解决方法(转载留自己看)
这个问题之前没有怎么留意过,是最近在面试过程中遇到的一个问题,面了两家公司,两家公司竟然都面到到了这个问题,不得不使我开始关注这个问题.说起CLOSE_WAIT状态,如果不知道的话,还是先瞧一下TCP ...
- pycharm import pygame 出现报错:No module named 'pygame'
首先发现装的Python 有问题原来的Python3.6.4版本安装完成后Scripts文件夹里空白的,什么也没有,从https://www.python.org/downloads/windows/ ...
- java并发包消息队列(也即阻塞队列BlockingQueue)
下面是典型的消息队列的生产者与消费者模式的例子
- Cocos 2dx项目lua调用OC出现卡死但不闪退的坑
最近新上线的一个游戏,发现线上游戏有部分功能在点击的时候出现了没有反应的情况.通过调试源码,发现是原生OC的代码出现了崩溃,但是比较奇怪的是线上的Bugly没有任何记录,这个功能属于高频高能,而且又是 ...