RabbitMQ Java官方教程(五)----Topics
Topics(主题)
在前面的教程中,我们改进了我们的日志系统。我们使用了一个direct交换器代替了只能够广发虚拟广播的fanout交换器。使我们可以选择性的接收日志。
虽然使用direct交换器改进了我们的系统,但它仍然有局限性——它不能基于多个标准进行路线选择。
在我们的日志系统中,我们可能希望订阅的不仅是基于严重性的日志,而且还基于发出日志的源。要实现这一点,我们需要了解一个复杂一点的交换器——topic交换器。
主题交换器(Topic Exchange)
发送到topic交换器的消息不能定义任意的routing_key——它必须是一个单词列表,由点分隔。这里可以是任何单词,但通常会用一些与消息相关的特性单词,比如说: "stock.usd.nyse", "nyse.vmw", "quick.orange.rabbit".这个routin_key可以有任意多个单词,最多可以是255个字节。
说到这里你应该猜到了,对应的绑定键也必须是以这种格式对应的。Topic Exchange背后的逻辑类似于一个direct exchange的逻辑——发送带有特定路由键的消息将被传递到绑定具有匹配绑定键的所有队列。这里有两个特殊的占位符:
*(星号键)可以代替一个(任意)单词。
#(井号键)可以代替零个或多个(任意)单词。
这里有一个最简单的例子:
在这个例子中,我们发送描述动物的消息。这个消息将发送包含三个单词的routing_key(两个点)。第一个单词是速度,第二个是颜色,第三个是种类。然后我们创建了三个绑定关系:Q1使用“*.orange.*”作为绑定键,Q2使用“*.*.rabbit”和“lazy.#”。这意味着:Q1可以收到所有的橙色动物,Q2会接收关于兔子的一切信息,和关于惰性动物的一切。
就是说,如果一条路由键设置为“quick.orange.rabbit”的消息,将被递送给这两个队列。消息“lazy.orange.elephant”也是将发送个它们两个。而如“quick.orange.fox”这样的将被发送到第一个队列。“lazy.brown.fox”只能被发送给第二个。“lazy.pink.rabbit”将被递送给Q2并且只是传送一次。尽管它可以匹配两个绑定关系。“quick.brown.fox”这样没有关联任何绑定关系的消息将被直接舍弃。
那你可能会想如果我们在这里违反我们定的规则,发送一个或者四个单词的信息会怎么样,就比如说“orange”或者“quick.orange.male.rabbit”。这里要说明的是,类似于这样的信息不会匹配到任何的绑定,这样的信息会丢失。而另一方面如果是“lazy.orange.male.rabbit”,尽管也是四个单词的,但它会被Q2接收到。由此可见Topic exchange是功能很强大的一个交换器。当一个队列用“#”规定它,那么此时它将接收所有的消息,就像前面讲的fanout交换器。而当不使用“#”或“*”时,你会发现它就相当于direct交换器。
代码整合
下面我们将使用topic交换器改进之前的日志系统。
完整代码:EmitlogTopic.java 和ReceiveLogsTopic.java
这里关于Topic类型的交换器就介绍到这里了,之后我们会介绍最后一部分Remote procedure call(RPC)远程过程调用。