RabbitMQ之主题(Topic)【译】

时间:2021-08-22 02:04:46

在上一节中,我们改进了我们的日志系统,替换使用fanout exchange仅仅能广播消息,使得选择性的接收日志成为可能。

虽然使用direct exchange改进了我们的系统,但是它仍然由他的局限性,——不能根据多个条件来做路由。

在我们的日志系统,我们可能不仅仅想根据严重性来订阅日志,还可以根据其发出的日志源。你可能知道UNIX的系统日志工具,它同时根据严重性(info/warn/crit...)和来源(auth/cron/kern...)来路由日志。

这就给我们一个很大的灵活性——我们可能想接收来自“cron”的严重错误日志信息,和来自“kern”的所有日志信息。

为了实现在我们的日志系统,我们需要了解一写更复杂的topic exchange。

主题交换(Topic exchange)

发送到Topic exchange的消息不能携带有任何的routing-key——它必须是一个用点分隔的单词列表。这些词可以使任何东西,但是通常他们指定连接到消息的某些功能。

一些有效的routing key:"stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit"。可以是你定义的关于路由的任何词语,最多255个字节。

binding key也必须是相同的形式,topic exchange的背后逻辑和direct exchange一样——一个带有独特routing key的消息被发送到拥有相匹配的binding key的队列。然而,有两个特殊情况下的binding key:

"*"(星号)可以替代只有一个字。

“#”(井号)可以代替零个或多个字。

如下图所示:

![](http://images2015.cnblogs.com/blog/658141/201608/658141-20160819235450312-533412558.png)

在这个例子中,我们将要发送描述动物的消息,这个消息将要被带有三个词语的routing key来发送,在路由关键的第一个字将描述速度,第二个代表颜色和第三个代表特点:".."。

我们创建三个绑定,Q1的binding key是".orange.",Q2的binding key是"..rabbit" 和 "lazy.#".

这些绑定可以概括为:

Q1对所有橙色动物感兴趣。

Q2希望知道关于兔子的一切,和关于懒惰的动物。

Routing key 为"quick.orange.rabbit"的消息将会被分发到两个队列中,"lazy.orange.elephant"也会被分发到两个队列,另一方面"quick.orange.fox" 将只会分发到第一个队列,"lazy.brown.fox" 第二个,"lazy.pink.rabbit"也是只会发送到第二个队列一次,"quick.brown.fox"没有相匹配的,就会被丢弃。

如果我们打破我们的规定,发送一个字或者四个字的消息会怎样呢?例如"orange"和"quick.orange.male.rabbit"。那么这些消息将不会匹配任何绑定,并都将丢失。

主题交换

主题交换是强大的,他可以表现的像其他exchange一样。

当队列与“#”(井号)结合键绑定 - 它会接收所有邮件,而不考虑routing key - 就像fanout exchange。

当特殊字符“*”(星号)和“#”(井号)不使用的时候,该主题交换会表现得就像direct exchange一样。

代码整合(Putting it all together)

我们将在我们的日志系统中使用主题交换,我们假设日志的routing key有两个关键字"."。

EmitLogTopic.java

public class EmitLogTopic {

    private static final String EXCHANGE_NAME = "topic_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, "topic"); String routingKey = getRouting(argv);
String message = getMessage(argv); channel.basicPublish(EXCHANGE_NAME, routingKey, null, message.getBytes());
System.out.println(" [x] Sent '" + routingKey + "':'" + message + "'"); connection.close();
}
//...
}

ReceiveLogsTopic.java

import com.rabbitmq.client.*;

import java.io.IOException;

public class ReceiveLogsTopic {
private static final String EXCHANGE_NAME = "topic_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, "topic");
String queueName = channel.queueDeclare().getQueue(); if (argv.length < 1) {
System.err.println("Usage: ReceiveLogsTopic [binding_key]...");
System.exit(1);
} for (String bindingKey : argv) {
channel.queueBind(queueName, EXCHANGE_NAME, bindingKey);
} 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);
}
}

原文地址:https://www.rabbitmq.com/tutorials/tutorial-five-java.html

代码地址:https://github.com/aheizi/hi-mq

相关:

1.RabbitMQ之HelloWorld

2.RabbitMQ之任务队列

3.RabbitMQ之发布订阅

4.RabbitMQ之路由(Routing)

5.RabbitMQ之主题(Topic)

6.RabbitMQ之远程过程调用(RPC)

RabbitMQ之主题(Topic)【译】的更多相关文章

  1. RabbitMQ之任务队列【译】

    在第一个教程里面,我们写了一个程序从一个有名字的队列中发送和接收消息,在这里我们将要创建一个分发耗时任务给多个worker的任务队列. 任务队列核心思想就是避免执行一个资源密集型的任务,而程序要等待其 ...

  2. RabbitMQ之HelloWorld【译】

    简介 RabbitMQ是一个消息代理,主要的想法很简单:它接收并转发消息.你可以把它当做一个邮局,当你发送邮件到邮筒,你相信邮差先生最终会将邮件投递给收件人.RabbitMQ在这个比喻里,是一个邮筒, ...

  3. Windows Azure Service Bus &lpar;5&rpar; 主题&lpar;Topic&rpar; 使用VS2013开发Service Bus Topic

    <Windows Azure Platform 系列文章目录> 项目文件,请在这里下载 在笔者之前的文章中Windows Azure Service Bus (1) 基础 介绍了Servi ...

  4. MQTT主题Topic讲解

    文章转载于https://www.cnblogs.com/hayasi/p/7792191.html 我们已经把相关的连接报文搞定了.笔者想来想去还是决定先讲解一下订阅报文(SUBSCRIBE ).如 ...

  5. RabbitMQ入门&lpar;5&rpar;——主题&lpar;Topic&rpar;

    前面我们介绍了通过使用direct exchage,改善了fanout exchange只能进行虚拟广播的方式.尽管如此,直接交换也有自身的局限,它不能基于多个条件路由. 在我们的日志系统中,也许我们 ...

  6. (转)RabbitMQ学习之主题topic(java)

    http://blog.csdn.net/zhu_tianwei/article/details/40887775 参考:http://blog.csdn.NET/lmj623565791/artic ...

  7. RABBITMQ&sol;JAVA &lpar;主题&rpar;

    上篇博文中,我们进一步改良了日志系统.即使用Direct类型的转换器,使得接受者有能力进行选择性的接收日志,而非fanout那样,只能够无脑的转发. 虽然使用Direct类型的转换器改进了日志系统.但 ...

  8. rabbitmq消息队列——&quot&semi;topic型交换器&quot&semi;

    在之前的章节中我们改进了我们的日志系统,我们使用direct型交换器代替了只能盲目广播消息的fanout型交换器,这使得我们可以有选择性地接收日志. 尽管使用direct型交换器改进了我们的日志系统, ...

  9. RabbitMQ通过Exchange&period;topic 对routingkey 进行正则表达式匹配

    消费者: static void Main(string[] args) { ConnectionFactory factory = new ConnectionFactory() { HostNam ...

随机推荐

  1. visual studio 2012 插件

    下面来分享几个好用的插件:直接在Tools-Extensions and Updates-Online中搜索就可以安装了 (中文版位于:菜单-工具-扩展和更新-联机-Visual Studio库) 1 ...

  2. iOS 10&period;0 更新点(开发者视角)

    html, body {overflow-x: initial !important;}html { font-size: 14px; } body { margin: 0px; padding: 0 ...

  3. ODI 12c中使用Groovy脚本创建工程

    本文主要介绍在ODI中使用groovy创建工程,并添加一个表转换的映射.要创建groovy脚本,可以从ODI Studio的菜单:工具->Groovy->新脚本 打开一个编辑窗口.在执行下 ...

  4. 【转载】MySQL被慢sql hang住了,用shell脚本快速清除不断增长的慢sql的办法

    原文地址:MySQL被慢sql hang住了,用shell脚本快速清除不断增长的慢sql的办法 作者:mchdba 某个初级dba误删index,mysql漫山遍野全是10S以上的慢sql,mysql ...

  5. iOS开发——OC篇&amp&semi;协议篇/NSCoder/NSCoding/NSCoping

    协议篇/NSCoder/NSCoding/NSCoping 协议声明类需要实现的的方法,为不同的类提供公用方法,一个类可以有多个协议,但只能有一个父类,即单继承.它类似java中的接口. 正式协议(f ...

  6. &lbrack;POJ&rsqb; 3461 Oulipo &lbrack;KMP算法&rsqb;

    Oulipo Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23667   Accepted: 9492 Descripti ...

  7. RedisDesktopManager

    下载地址: https://github.com/uglide/RedisDesktopManager/releases

  8. Linux内核通用队列的使用笔记&lpar;读linux内核设计与实现&rpar;

    Linux内核通用队列实现 Kfifo位置:kernel/kififo.c 使用需要包含头文件#include <kernel/kififo> 1.创建队列(动态创建)int kfifo_ ...

  9. MySQL各版本解释和下载

    MySQL 的官网下载地址:http://www.mysql.com/downloads/ 个人理解: 1.不要再纠结是否是5.1还是5.5.5.6.5.7这些,一般选择时不要选择太新,选择5.1或者 ...

  10. Database学习 - mysql 数据库 外键

    外键 外键约束子表的含义:如果在父表中赵达不到候选键,则不允许在子表上进行insert/update 外键预约对父表的含义:在父表上进行update/delete以更新或删除子表中有一条或多条对应匹配 ...