2015-02-14 25 views
8

Mam trzech klientów z własnymi instancjami RabbitMQ i mam aplikację (nazwijmy ją appA), która ma własną instancję RabbitMQ, trzy aplikacje klienckie (app1, app2, app3) chcą korzystać z usługi na appA.RPC RPC w wielu instancjach rabbitMQ

Usługa na appA wymaga komunikacji RPC, app1, app2 i app3, każda ma kolejkę booking.request i booking.response.

enter image description here

Dzięki wtyczce łopaty, mogę przekazać wszystkie booking.request wiadomości z app1-3 do 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. 

Teraz Appa odpowie na żądanie w kolejce booking.response, Potrzebuję komunikatu o odpowiedzi na rezerwację w rabbitMQ-appA, aby powrócić do prawidłowej kolejki booking.response na app1, app2 lub app3, ale nie do wszystkich z nich - jak skonfigurować kolejkę szufli/stowarzyszoną w rabbitMQ-appA, która będzie przesyła odpowiedź z powrotem do poprawnego rabbitMQ (app1, app2, app3), który oczekuje odpowiedzi we własnej rezerwacji. ueue?

Wszystkie te aplikacje używają spring-amqp (w razie potrzeby). Alternatywnie, mógłbym ustawić szablon rabbitMQ na wiosnę, który słuchałby wielu kolejek rabbitMQ i konsumował od każdego z nich.

Od docs, to co to typowy konsument wygląda następująco:

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

Czy można określić wiele fabryk połączeń w tym celu nawet jeśli Fabryki połączeń są do tej samej instancji RabbitMQ, ale tylko różne vhostów:

enter image description here

Aktualizacja:

podstawie odpowiedzi Josha, musiałbym wiele fabryk połączeń:

<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" /> 

Wtedy używam SimpleRoutingConnectionFactory zawijać zarówno connection-fabryki:

<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> 

Teraz kiedy oświadczam mój szablon RabbitMQ, Chciałbym zwrócić go do SimpleRoutingConnectionFactory zamiast poszczególnych fabryk połączeń:

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

... a następnie użyć temp późno jak bym normalnie używać go ...

<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> 

// i komunikaty są spożywane z obu przypadkach RabbitMQ

... i ...

@Autowired 
    private AmqpTemplate template; 

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

// i publikuje wiadomość do obu kolejek:

Czy mam rację?

Odpowiedz

5

Zobacz org.springframework.amqp.rabbit.connection.AbstractRoutingConnectionFactory. Pozwoli ci to utworzyć wiele fabryk połączeń z różnymi vhostami lub różnymi instancjami rabbitmq. Używamy go do aplikacji multi-najem rabbitmq.

+0

AbstractRoutingConnectionFactory wygląda obiecująco, czy masz przykład tego, jak go używasz? Do czego służy funkcja determineCurrentLookupKey? –

+1

Oto dokument źródłowy na ten temat. [http://docs.spring.io/spring-amqp/docs/1.3.0.M1/reference/html/amqp.html#routing-connection-factory](http://docs.spring.io/spring- amqp/docs/1.3.0.M1/reference/html/amqp.html # routing-connection-factory). Daj mi znać, jeśli masz jakieś pytania po przeczytaniu tego dokumentu. –

+0

Na podstawie doktora, zaktualizowałem moje pytanie ... w skrócie, SimpleRoutingConnectionFactory opakowuje wiele fabryk połączeń i może być używany w taki sam sposób, jak pojedyncza fabryka połączeń, czy to prawda? –

1

Minęło trochę czasu, ale jeśli używasz Spring możesz utworzyć tyle fabryk połączeń, ile chcesz, z ich własnymi konfiguracjami (host, user/pass, vhost itp.), Tak jak zrobiłeś:

@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; 
} 

a administrator królik/szablon jest jak idziesz:

@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; 
} 

Pamiętaj, że musisz podać tag @Primary włączyć jeden główny fasolkę po Wiosna nie wie, który z nich wybrać, gdy don "Nie informuj wyraźnie o name.

Mając to na rękach, po prostu wstrzyknąć je zazwyczaj ze sobą elementów:

@Autowired 
private RabbitTemplate template; 

// ... 

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

Nadzieję, że to pomaga! :)