Spring и RabbitMQ, как объявлять и использовать очереди? - PullRequest
0 голосов
/ 25 января 2012

Я работаю над веб-проектом, который использует Spring и RabbitMQ.Это базовая система с главным узлом, отправляющим задачи на подчиненные узлы (используя прямой обмен) и подчиненные узлы, отвечающие на ведущий с помощью простой очереди.

Новые подчиненные могут приходить и уходить в любое время, поэтому они используютанонимные очереди.Также может быть несколько главных узлов, и в этом случае каждый из них будет иметь свою очередь ответов.Когда мастер отправляет задачу подчиненным, задача содержит имя очереди ответов мастера, который ее отправил.Отправка сообщений осуществляется с помощью AmqpTemplate.

Я настраиваю все это с помощью XML, вот что у меня получилось:

Для подчиненного:

<!-- Message listener -->
<bean id="taskListener" class="tgi.docgen.amqp.TypedListener" />
  <bean id="slave" class="tgi.docgen.node.Slave" />
    <bean id="handler" class="tgi.docgen.task.TaskHandler" />

<!-- Rabbit infrastructure -->
<!-- Slave reading queue, bound to the exchange -->
<rabbit:queue id="receiveQueue" auto-delete="true" durable="false" />

<!-- Master -> Slave exchange -->
<rabbit:direct-exchange name="docgenExchange" auto-delete="true" durable="false">   
    <rabbit:bindings>
        <rabbit:binding queue="receiveQueue" />
    </rabbit:bindings>
</rabbit:direct-exchange>

<!-- taskListener bean listens to the queue -->
<rabbit:listener-container connection-factory="rabbitFactory">
    <rabbit:listener queues="receiveQueue" ref="taskListener" />
</rabbit:listener-container>

Для мастера:

<!-- Message listener -->
<bean id="taskListener" class="tgi.docgen.amqp.TypedListener" />
  <bean id="master" class="tgi.docgen.node.Master">
      <property name="docgenExchange" value="???" />
      <property name="receiveQueue" value="???" />
  </bean>

<!-- Rabbit infrastructure -->
<!-- Anonymous reception queue -->
<rabbit:queue id="receiveQueue" auto-delete="true" durable="false" />

<!-- Master -> Slave exchange -->
<rabbit:direct-exchange name="docgenExchange" auto-delete="true" durable="false" />

<!-- taskListener listens to reception queue -->
<rabbit:listener-container connection-factory="rabbitFactory">
    <rabbit:listener queues="receiveQueue" ref="taskListener" />
</rabbit:listener-container>

Вот что я хочу знать

1) как избежать повторения имени обмена в обоих XML-файлах конфигурации?Мастер-проект зависит от подчиненного проекта, поэтому я могу легко обмениваться конфигурацией между ними, но я не понимаю, как можно извлечь имя для обмена и использовать его в обоих файлах.

2) Как я уже сказалМастер отправит задачи на биржу и должен записать имя своей очереди ответа в задачах.Как я могу ввести имя очереди и обмен в главном компоненте?То есть: как я могу заменить два ??? на соответственно «docgenExchange» и сгенерированное имя очереди анонимных ответов в моем конфигурационном файле выше?

1 Ответ

0 голосов
/ 19 сентября 2012

Это не Spring Integration 2?

В любом случае, я несколько дней назад сделал для себя «доказательство концепции», занимаясь тем, что вы хотите архивировать.См. https://github.com/knalli/task-worker

Относительно вашего первого вопроса: Ну, это зависит.Это зависит от того, что именно вы хотите.Не вижу проблем с настройкой в ​​обоих проектах - хозяина проекта и ведомого проекта - имени центральной очереди.Конечно, это не должно быть жестко закодировано, а вариант конфигурации.И вы можете предоставить обеим запущенным программам одни и те же внешние свойства, которые будут использоваться в качестве компонента-заполнителя свойства в контексте конфигурации Spring.

Второй вариант немного странный: возможно, у вас был старый пример, или это Spring Ingegration1.х .. я не знаюВ любом случае: вам не нужно указывать имя ответа.Потому что это будет автоматически обрабатываться Spring Integration для вас, если вы используете AMPQ Gateway Beans.

Я процитирую порт конфигурации Inbound AMQP Gateway для конфигурации моего демона (это ваш «ведомый»):

<int-amqp:inbound-gateway 
    connection-factory="connectionFactory" 
    request-channel="requestChannel"
    reply-channel="replyChannel" 
    error-channel="errorChannel"
    queue-names="${rabbitmq.queue}"/>

Каждый из упомянутых каналов - requestChannel, replyChannel, errorChannel - регистрируется только в контексте интеграции Spring через простой

 <int:channel id="requestChannel"/>

Для AMQP - имеется в виду Message Brokerконфигурация - больше нет необходимости в дополнительных частях конфигурации, кроме элемента <rabbit:queue>.

Кроме того, я бы использовал аннотации Java для связи сообщений с интерфейсами служб (@Gateway) и классами служб (@ServiceActivator),Это значительно уменьшает конфигурацию.

...