2015-02-14 3 views
8

У меня есть три клиента, каждый со своими экземплярами RabbitMQ, и у меня есть приложение (назовем его appA), у которого есть свой собственный экземпляр RabbitMQ, три клиентских приложения (app1, app2, app3) хотят использовать службу на appA.RabbitMQ RPC через несколько экземпляров rabbitMQ

Служба на appA требует связи RPC, app1, app2 и app3, у каждого из которых есть резервирование. Очередь запросов и очередь резервирования.

enter image description here

С лопатой плагин, я могу направить все booking.request сообщения от app1-3 к APPA:

Shovel1 
virtualHost=appA, 
name=booking-request-shovel, 
sourceURI=amqp://userForApp1:[email protected]/vhostForApp1 
queue=booking.request 
destinationURI=amqp://userForAppA:[email protected]/vhostForAppA 
queue=booking.request 

setup another shovel to get booking requests from app2 and app3 to appA in the same way as above. 

Теперь Аппа ответит на запрос по очереди booking.response, Мне нужно сообщение ответа на бронирование на rabbitMQ-appA, чтобы вернуться к правильной очереди booking.response либо на app1, app2 или app3, но не на всех из них - как мне настроить очередь с лопатой/федерацией на rabbitMQ-appA, которая будет отправьте ответ обратно на правильный rabbitMQ (app1, app2, app3), который ожидает ответа в своем собственном заказе. ueue?

Все эти приложения используют Spring-amqp (в случае, если это релевантно) В качестве альтернативы, я могу настроить шаблон rabbitMQ весной, который прослушивает несколько очередей rabbitMQ и потребляет от каждого из них.

Из документов, это то, что типичный потребитель выглядит следующим образом:

<rabbit:listener-container connection-factory="rabbitConnectionFactory"> 
    <rabbit:listener queues="some.queue" ref="somePojo" method="handle"/> 
</rabbit:listener-container> 

Можно указать несколько фабрик соединений, чтобы сделать это, даже если фабрики соединений находятся в одном экземпляре RabbitMQ, но просто разные: виртуальные домены

enter image description here

Update:

На основании ответа Джоша, я бы несколько фабрик соединений:

<rabbit:connection-factory 
       id="connectionFactory1" 
       port="${rabbit.port1}" 
       virtual-host="${rabbit.virtual1}" 
       host="${rabbit.host1}" 
       username="${rabbit.username1}" 
       password="${rabbit.password1}" 
       connection-factory="nativeConnectionFactory" /> 

<rabbit:connection-factory 
       id="connectionFactory2" 
       port="${rabbit.port2}" 
       virtual-host="${rabbit.virtual2}" 
       host="${rabbit.host2}" 
       username="${rabbit.username2}" 
       password="${rabbit.password2}" 
       connection-factory="nativeConnectionFactory" /> 

Тогда я хотел бы использовать SimpleRoutingConnectionFactory обернуть оба соединения-заводы:

<bean id="connectionFactory" class="org.springframework.amqp.rabbit.connection.SimpleRoutingConnectionFactory"> 
    <property name="targetConnectionFactories"> 
     <map> 
      <entry key="#{connectionFactory1.virtualHost}" ref="connectionFactory1"/> 
      <entry key="#{connectionFactory2.virtualHost}" ref="connectionFactory2"/> 
     </map> 
    </property> 
</bean> 

Теперь, когда я декларировать свой шаблон RabbitMQ, Я хотел бы указать его на SimpleRoutingConnectionFactory вместо отдельной фабрики соединений:

<rabbit:template id="template" connection-factory="connectionFactory" /> 

... а затем использовать темп поздно, как я обычно использую его ...

<rabbit:listener-container 
     connection-factory="connectionFactory" 
     channel-transacted="true" 
     requeue-rejected="true" 
     concurrency="${rabbit.consumers}"> 
     <rabbit:listener queues="${queue.booking}" ref="TransactionMessageListener" method="handle" /> 
</rabbit:listener-container> 

// и сообщения, потребляемый от обоих RabbitMQ экземпляров

... и ...

@Autowired 
    private AmqpTemplate template; 

    template.send(getExchange(), getQueue(), new Message(gson.toJson(message).getBytes(), properties)); 

// и сообщение публикует в обе очереди

Правильно ли я?

ответ

5

Посмотрите на org.springframework.amqp.rabbit.connection.AbstractRoutingConnectionFactory. Это позволит вам создавать несколько фабрик соединений для разных vhosts или разных экземпляров rabbitmq. Мы используем его для приложения с несколькими арендаторами rabbitmq.

+0

AbstractRoutingConnectionFactory выглядит многообещающим, у вас есть пример того, как вы его используете? Для чего используется параметрCurrentLookupKey? –

+1

Вот весенний документ на нем. [http://docs.spring.io/spring-amqp/docs/1.3.0.M1/reference/html/amqp.html#routing-connection-factory](http://docs.spring.io/spring- AMQP/документы/1.3.0.M1/ссылка/HTML/amqp.html # маршрутизации-соединения-завод). Дайте мне знать, если у вас возникнут вопросы после прочтения этого документа. –

+0

Основываясь на документе, я обновил свой вопрос ... короче говоря, SimpleRoutingConnectionFactory обертывает несколько фабрик подключений и может затем использоваться так же, как и единая фабрика соединений, правильно ли это? –

1

Это было некоторое время, но если вы используете Spring вы можете создать столько фабрик соединений, как вы хотите, с их собственными конфигурациями (хост, пользователь/пасс, ВХост и т.д.), так же, как вы делали:

@Bean 
@Primary 
public ConnectionFactory amqpConnectionFactory1() { 
    final CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); 

    connectionFactory.setAddresses("..."); 
    connectionFactory.setUsername("..."); 
    connectionFactory.setPassword("..."); 
    connectionFactory.setVirtualHost("..."); 

    return connectionFactory; 
} 

@Bean 
public ConnectionFactory amqpConnectionFactory2() { 
    final CachingConnectionFactory connectionFactory = new CachingConnectionFactory(); 

    // ... 

    return connectionFactory; 
} 

И ваш кролик админ/шаблон, как вы идете:

@Bean 
@Primary 
public RabbitAdmin rabbitAdmin1() { 
    return new RabbitAdmin(amqpConnectionFactory1()); 
} 

@Bean 
public RabbitAdmin rabbitAdmin2() { 
    return new RabbitAdmin(amqpConnectionFactory2()); 
} 

// ... 

@Bean 
@Primary 
public RabbitTemplate rabbitTemplate1() { 
    RabbitTemplate rabbitTemplate = new RabbitTemplate(amqpConnectionFactory1()); 

    // ... 

    return rabbitTemplate; 
} 

@Bean 
public RabbitTemplate rabbitTemplate2() { 
    RabbitTemplate rabbitTemplate = new RabbitTemplate(amqpConnectionFactory2()); 

    // ... 

    return rabbitTemplate; 
} 

Обратите внимание, что вы должны предоставить @Primary тег, чтобы включить один основной компонент, когда весна не знает, какой из них выбрать, когда дон Не сообщайте name явно.

С этим в руках, просто вводить их обычно вместе компоненты:

@Autowired 
private RabbitTemplate template; 

// ... 

@Autowired 
@Qualifier("rabbitTemplate2") // Needed when want to use the non-primary bean 
private RabbitTemplate template; 

Надеется, что это помогает! :)

Смежные вопросы