12、Topic Based Routing 主题路由

RabbitMQ有一个很酷的功能,基于主题的路由,这个功能允许订阅者基于多个条件过滤消息。一个主题是由点句号分隔的单词列表,随消息一同发布。例如:“stock.usd.nyse” 或 "book.uk.london" 或 "a.b.c",这些可以是任何你喜欢的单词,但通常是一些消息的属性。主题字符串限制最多255个字符。

要发布一个带主题的消息,可以简单地调用带主题参数的Publish重载方法"

bus.Publish(message,"X.A");

 

订阅者能通过指定一个主题来过滤消息。这些可以包含通配符。

  • *(星号)只能匹配一个词。

  • # (井号)能匹配0到多个词。

举个栗子:

假如发布一个带有“X.A.2”主题的消息,订阅者可以用“#”、 “X.#”、 ".A."来匹配,但是“X.B”或“A”肯定不能匹配上的。

订阅一个主题,要调用带配置的SubScribe重载方法。

bus.Subscribe("my_id", handler,   //handler是一个委托,即处理消息的回调方法
    x=>x.WithTopic("X.*"));       //这里要提供配置,指定主题

 

警告:两个独立订阅者使用同一个subscriber_Id和不同的主题字符串,可能不会有你预期的效果。(你可能希望两个订阅者消费不同主题的消息,实际上你办不到)。因为主题topic其实是为RabbitMQ的topic交换器设置绑定(路由规则),而不是在EasyNetQ客户端做的过滤。

一个subscriber_Id识别一个独立的AMQP队列,那么带有相同subscriber_Id的两个订阅者将连接到同一个队列,而他们自己的主题会一同添加到topic交换器的绑定Binding里。例如你这样做:

bus.Subscribe("my_id",handlerOfXDotStar,   
    x=>x.WithTopic("X.*"));

bus.Subscribe("my_id",handlerOfStarDotB,
    x=>x.WithTopic(*.B));

 

实际上,所有匹配“X.”或  “.B”的消息都将发送到“XXX_My_id”队列上。然后RabbitMQ轮流在两个消费者之间投递消息(你一下我一下)。handlerOfXDotStar和handlerOfStarDotB会依次轮流得到消息(并不是前者只收到X.*后者只收到*.B这样,而是两种都有)。

现在,如果你想匹配多个主题("X."或者“.B”)你可以使用另外一个带多个主题参数的Subscribe重载方法,像下面这样:

bus.Subscribe("my_id",handler, 
    x=>x.WithTopic("X.*").WithTopic("*.B"));

这些主题重载也适用于SubscribeAsync方法。

关于主题的更多警告,请看这篇博客Topic Confusion,不过要注意,示例代码使用了老版本的API,在你调用Publish方法之前,必须要打开publish管道。

英文地址:https://github.com/EasyNetQ/EasyNetQ/wiki/Topic-Based-Routing

posted on 2017-12-05 15:11  困兽斗  阅读(323)  评论(0编辑  收藏  举报

导航