rabbitmq(4)

Routing

上一讲所介绍的扇形交换,是将交换机将消息分发给所有的队列,而现在这个路由机制则是对这一部分的进一步优化。
下面将对这一一介绍:

Bindings

在之前的例子中,我们创建交换机和队列之间的绑定关系是这样的:
channel.queueBind(queueName, EXCHANGE_NAME, "");
大家可以看到,第三个参数“ ”,其实就是routingkey,所以现在可以这样写:
channel.queueBind(queueName, EXCHANGE_NAME, "black");
这也就意味着,如今交换关系的绑定,取决于“black”交换的类型,而之前的fanout exchanges忽视了这一点

Direct exchange

那一个日志系统来说吧,之前fanout exchanges是将所有日志信息发送给所有consumers,这样称作广播式
而现在,我们想要consumers1接收error消息,consumers2接收warning消息等等
这样我们便需要这样一个路由,来过滤这些消息,这样也被称作订阅式。

如图所示:橙色消息将被发送给Q1,而黑色和绿色消息将发送给Q2,其他消息将被丢弃。

Multiple bindings


用同样的绑定值作为路由键也是完全可以的,针对一些场景也会用到这样设置。

Emitting logs

现在改由这订阅的方式来创建日志系统

channel.exchangeDeclare(EXCHANGE_NAME, "direct");
channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
severity--可以为warn、error、info等关键字

Subscribing

String queueName = channel.queueDeclare().getQueue();

for(String severity : argv){    
  channel.queueBind(queueName, EXCHANGE_NAME, severity);
}
整体的结构:

package logs;
import java.util.Arrays;

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;

public class EmitLogDirect {

  private static final String EXCHANGE_NAME = "direct_logs";

  public static void main(String[] argv) throws Exception {
	  
	argv = new String[1];
	argv[0]="warning";

    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    channel.exchangeDeclare(EXCHANGE_NAME, "direct");
    String severity = getSeverity(argv);
    String message = getMessage(argv);

    channel.basicPublish(EXCHANGE_NAME, severity, null, message.getBytes());
    System.out.println(" [x] Sent '" + severity + "':'" + message + "'");

    channel.close();
    connection.close();
  }
  
  private static String getSeverity(String[] strings){
    if (strings.length < 1)
    	    return "info";
    return strings[0];
  }

  private static String getMessage(String[] strings){ 
    if (strings.length < 2)
    	    return "Hello World!";
    return joinStrings(strings, " ", 1);
  }
  
  private static String joinStrings(String[] strings, String delimiter, int startIndex) {
    int length = strings.length;
    if (length == 0 ) return "";
    if (length < startIndex ) return "";
    StringBuilder words = new StringBuilder(strings[startIndex]);
    for (int i = startIndex + 1; i < length; i++) {
        words.append(delimiter).append(strings[i]);
    }
    return words.toString();
  }
}

package logs;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.QueueingConsumer;

public class ReceiveLogsDirect {

  private static final String EXCHANGE_NAME = "direct_logs";

  public static void main(String[] argv) throws Exception {
//	argv = new String[3];
//	argv[0]="error";
//	argv[1]="warning";
//	argv[2]="info";
	
	argv = new String[1];
	argv[0]="error";
	
    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    Connection connection = factory.newConnection();
    Channel channel = connection.createChannel();

    channel.exchangeDeclare(EXCHANGE_NAME, "direct");
    String queueName = channel.queueDeclare().getQueue();
    
    if (argv.length < 1){
      System.err.println("Usage: ReceiveLogsDirect [info] [warning] [error]");
      System.exit(1);
    }
    
    for(String severity : argv){    
      channel.queueBind(queueName, EXCHANGE_NAME, severity);
      System.out.print(severity+"、");
    }
    System.out.println();
    
    System.out.println(" [*] Waiting for messages. 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());
      String routingKey = delivery.getEnvelope().getRoutingKey();

      System.out.println(" [x] Received '" + routingKey + "':'" + message + "'");   
    }
  }
}

结果:
[x] Sent 'warning':'Hello World!'
[x] Sent 'error':'Hello World!'
[x] Sent 'info':'Hello World!'
error、warning、info、
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received 'error':'Hello World!'
 [x] Received 'info':'Hello World!'
 [x] Received 'warning':'Hello World!'
error、
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received 'error':'Hello World!'




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值