Chapter 35. 消息的转发(divert)与分流

在HornetQ中可以配置一些称为转发器(diverts)的对象。

转发器可以将路由到一个地址的消息透明地转发到其它的地址去,不需要客户端的参与。

转发器可以是唯一(exclusive)的,即消息只转发到新的地址,不发到原 来的地址;也可以是不唯一(non-exclusive)的,即消息在发往原有地址的 同时,它的一个拷贝被发往新的地址。不唯一的转发器可以在应用中将消息进行 分流(splitting)。比如在一个订单系统中它可以用于监视发往订单队列中 的每个订单消息。

转发器还可以带一个可选的消息选择器。只有被选择器选择的消息才会被转发。

转发器还可以带有一个转换器(Transformer)。它可以将消息进行转换。

转发器只在同一个服务器中的地址间进行转发。如果要向另外服务器中的地址进行转发,可以采用转发器与桥配合 来实现。先将消息通过转发器转发到一个存储与转发的队列中,再由一个桥将这个队列的消息转发到远程服务器的目的 地址中。

由转发器与桥进行配合可以组成复杂的路由系统。在服务器中由一组转发器可以形成一个消息路由表。如果加上桥,就 可以进一步形成一个分布式的可靠的消息路由网。

转发器的配置在hornetq-configuration.xml中定义。可以配置零个或多个转发器。

参见转发器的例子Section 11.1.13, “转移(Divert)”,它展示了如何配置与使用转发器。

让我们看一些转发器的配置例子:

35.1. 唯一式转发器

下面是一个唯一式转发器的例子。它将所有符合条件的消息转发到新的地址,而旧的地址将不能得到这些消息。

以下配置来自于divert例子:

<divert name="prices-divert">                  
    <address>jms.topic.priceUpdates</address>
    <forwarding-address>jms.queue.priceForwarding</forwarding-address>    
    <filter string="office='New York'"/>
    <transformer-class-name>
        org.hornetq.jms.example.AddForwardingTimeTransformer
    </transformer-class-name>     
    <exclusive>true</exclusive>
</divert>                        
        

在这里我们定义了一相名为“prices-divert”的转发器,它将发往 “jms.topic.priceUpdates”(对应JMS话题priceUpdates)的消息转向另一个本地地址“jms.queue.priceForwarding”(对应JMS队列 priceForwarding)。

我们还配置了一相消息过滤器。只有office属性值为New York 的消息才被转发到新地址,其它消息则继续发往原地址。如果没有定义过滤器,所有消息将被转发。

本例中还配置了一个转换器的类。当每转发一个消息时,该转换器就被执行一次。转换器可以对消息在转发前进行 更改。这里的转换器只是在消息中加入了一个记录转发时间的消息头。

本例中消息被转发到一个’存贮与转发是‘队列,然后通过一个桥将消息转发到另一个HornetQ服务器中。

35.2. 不唯一转发器

下面我们来看一个不唯一的转发器。不唯一转发器将消息的拷贝转发到新的地址中, 原消息则继续发往原有地址。

因此不唯一转发器可以将消息进行分流(splitting)。

不唯一转发器的配置与唯一转发器的配置中一样的,也可以带一个可选的过滤器和转换器。下面的配置也是出自 divert例子:

<divert name="order-divert">                 
    <address>jms.queue.orders</address>
    <forwarding-address>jms.topic.spyTopic</forwarding-address>         
    <exclusive>false</exclusive>
</divert>                       
        

The above divert example takes a copy of every message sent to the address 'jms.queue.orders' (Which corresponds to a JMS Queue called 'orders') and sends it to a local address called 'jms.topic.SpyTopic' (which corresponds to a JMS Topic called 'SpyTopic').