RabbitMq路由选择 (Routing)

1、绑定(Bindings)
channel.queueBind(queueName, EXCHANGE_NAME, "");
绑定表示转发器与队列之间的关系。我们也可以简单的认为:队列对该转发器上的消息感兴趣。
绑定可以附带一个额外的参数routingKey。为了与避免basicPublish方法(发布消息的方法)的参数混淆,我们准备把它称作绑定键(binding key)。下面展示如何使用绑定键(binding key)来创建一个绑定:
channel.queueBind(queueName, EXCHANGE_NAME, "black");
绑定键的意义依赖于转发器的类型。对于fanout类型,忽略此参数。
2、直接转发(Direct exchange)

我们将会使用direct类型的转发器进行替代。direct类型的转发器背后的路由转发算法很简单:消息会被推送至绑定键(binding key)和消息发布附带的选择键(routing key)完全匹配的队列。

3、多重绑定(multiple bindings)

使用一个绑定键(binding key)绑定多个队列是完全合法的

4、发送日志(Emittinglogs)

我们准备将这种模式用于我们的日志系统。我们将消息发送到direct类型的转发器而不是fanout类型。我们将把日志的严重性作为选择键(routing key)。这样的话,接收程序可以根据严重性来选择接收。我们首先关注发送日志的代码:

像以前一样,我们需要先创建一个转发器:

channel.exchangeDeclare(EXCHANGE_NAME,"direct");

然后我们准备发送一条消息:

channel.basicPublish(EXCHANGE_NAME,severity, null, message.getBytes());

为了简化代码,我们假定‘severity’是‘info’,‘warning’,‘error’中的一个。

5、订阅

接收消息的代码和前面的博客的中类似,只有一点不同:我们给我们所感兴趣的严重性类型的日志创建一个绑定。

StringqueueName = channel.queueDeclare().getQueue();

for(Stringseverity : argv)

{

channel.queueBind(queueName, EXCHANGE_NAME, severity);

}

6、完整的实例
发送端
@Test
	public void sendMessage() throws IOException, TimeoutException{
		// 创建连接和频道
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		// 声明转发器的类型
		channel.exchangeDeclare(EXCHANGE_NAME, "direct");
 
		//发送6条消息
		for (int i = 0; i < 6; i++){
			String severity = getSeverity();
			String message = severity + "_log :" + UUID.randomUUID().toString();
			// 发布消息至转发器,指定routingkey
			channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
			System.out.println(" [x] Sent '" + message + "'");
		}
 
		channel.close();
		connection.close();
	}
	/**
	 * 随机产生一种日志类型
	 * 
	 * @return
	 */
	private static String getSeverity(){
		Random random = new Random();
		int ranVal = random.nextInt(3);
		return SEVERITIES[ranVal];
	}

接收端代码:

@Test
	public void receiveMessage() throws IOException, TimeoutException, ShutdownSignalException, ConsumerCancelledException, InterruptedException{
		// 创建连接和频道
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		// 声明direct类型转发器
		channel.exchangeDeclare(EXCHANGE_NAME, "direct");
 
		String queueName = channel.queueDeclare().getQueue();
		String severity = getSeverity();
		// 指定binding_key
		channel.queueBind(queueName, EXCHANGE_NAME, severity);
		System.out.println(" [*] Waiting for "+severity+" logs. To exit press CTRL+C");
 
		QueueingConsumer consumer = new QueueingConsumer(channel);
		channel.basicConsume(queueName, true, consumer);
 
		while (true){
			QueueingConsumer.Delivery delivery = consumer.nextDelivery();
			String message = new String(delivery.getBody());
 
			System.out.println(" [x] Received '" + message + "'");
		}

	}
	
	/**
	 * 随机产生一种日志类型
	 * 
	 * @return
	 */
	private static String getSeverity(){
		Random random = new Random();
		int ranVal = random.nextInt(3);
		return SEVERITIES[ranVal];
	}

总结:发送消息时可以设置routing_key,接收队列与转发器间可以设置binding_key,接收者接收与binding_key与routing_key相同的消息。

转自https://blog.csdn.net/lmj623565791/article/details/37669573

猜你喜欢

转载自blog.csdn.net/BingoXing/article/details/81015726