RabbitMQ Routing

路由
    在先前的教程中,我们创建一个简单的日志系统,我们能够广播日志消息给许多接受者。
    在这个教程中,我们将添加一个特性--我们能够订阅消息的一个子集。例如,我们将可以直接传送危急的错误消息给日志文件(保存到硬盘中),能够打印所有的日志消息在控制台上。

绑定

    在先前的教程中,我们已经创建了绑定,你可能想起这样的代码:

channel.queueBind(queueName, EXCHANGE_NAME, "");

    绑定是交换机和队列之间的关系,这个可以简单地理解为:队列对交换机中的消息感兴趣

    绑定会添加额外的routingkey参数。为了避免和basic_public 参数混淆,我们将叫它为binding key.这是我们创建一个带有key的绑定:

channel.queueBind(queueName, EXCHANGE_NAME, "black")

    绑定key的含义取决于交换机的类型,fanout交换机,我们之前使用的,忽略了这个值。

direct 交换机

    我们先前教程的日志系统将所有的消息广播给所有的消费者。我们想要扩展基于服务器允许过滤消息的功能。例如,我们可能需要一个写仅仅接受危急的错误日志信息到硬盘中,不为警告和消息日志信息浪费磁盘空间。
    我们使用direct交换机,direct交换机背后的routing算法很简单-消息进入队列,它的bindingkey 和routing key匹配。
 

为了解释清楚,考虑以下的设置:

    在这个设置中,我们可以看到direct交换机x,有两个队列和它绑定,第一个队列和binding key orange绑定,第二个有两个绑定,一个和binding key black绑定,另外一个和 green绑定。

    在这样设置的消息发布给一个带有routing key orange的交换机将会路由到队列Q1。带有routing key black 或者green的消息将去Q2,所有其他的消息将会被丢弃。

多重绑定

    多个队列绑定相同的binding key是完全合法的。在我们的例子中,我们能够将给交换机x队列Q1添加一个binding key black。在那个例子中,direct 交换机将和fanout交换机一样将消息、广播给所有匹配的队列。带有routing key black的消息将会传送给Q1和Q2.

 

发送日志

    我们的日志系统使用这个模型,我们将发送消息给direct exchange而不是fanout 交换机。我们将提供日志严重性作为路由键。这样接受程序就可以接受它想接收的的严重性。让我们关注发送日志先。
 

    一如既往的,我们需要先创建一个交换机。

channel.exchangeDeclare(EXCHANGE_NAME, "direct");

    我们准备好发送消息:

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

    为了简化,我们假设严重性可以为 info warnning error这三个之一。

订阅

接受消息和先前的教程一样。除了一个例子外,我们将会为每一个我们感兴趣的严重消息创建一个新的绑定。

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

for(String severity : argv){
  channel.queueBind(queueName, EXCHANGE_NAME, severity);
}

将所有代码放在一起。

EmitLogDirect.java类的代码。

import com.rabbitmq.client.*;

import java.io.IOException;

public class EmitLogDirect {

    private static final String EXCHANGE_NAME = "direct_logs";

    public static void main(String[] argv)
                  throws java.io.IOException {

        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();
    }
    //..
}

ReceiveLogsDirect.java的代码。

import com.rabbitmq.client.*;

import java.io.IOException;

public class ReceiveLogsDirect {

  private static final String EXCHANGE_NAME = "direct_logs";

  public static void main(String[] argv) throws Exception {
    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.println(" [*] Waiting for messages. To exit press CTRL+C");

    Consumer consumer = new DefaultConsumer(channel) {
      @Override
      public void handleDelivery(String consumerTag, Envelope envelope,
                                 AMQP.BasicProperties properties, byte[] body) throws IOException {
        String message = new String(body, "UTF-8");
        System.out.println(" [x] Received '" + envelope.getRoutingKey() + "':'" + message + "'");
      }
    };
    channel.basicConsume(queueName, true, consumer);
  }
}


    像以前一样编译代码(看教程1的编译和类路径建议)。为了方便,在类路径上运行例子的时候,我们将使用一个
环境变量$CP(在windows为%CP%).

 

javac -cp $CP ReceiveLogsDirect.java EmitLogDirect.java

    如果你想要仅仅保存warning和error的日志到一个文件中(而不是info)。仅仅是打开console和敲。

java -cp $CP ReceiveLogsDirect warning error > logs_from_rabbit.log

    如果你想要在你的屏幕上看到所有的日志信息,打开一个新的终端:

java -cp $CP ReceiveLogsDirect info warning error
# => [*] Waiting for logs. To exit press CTRL+C

    例如,为了发送error日志信息,只需要敲:

java -cp $CP EmitLogDirect error "Run. Run. Or it will explode."
# => [x] Sent 'error':'Run. Run. Or it will explode.'

移动到教程5学习如何基于一个模式来监听消息。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值