2016-03-18 3 views
1

У меня есть несколько вопросов по кодированию в RabbitMQ ... Я не новичок в этом мир и получил вопросы на основе дизайна предоставленного мне для реализации ...RabbitMQ - Знающий Потребитель до

  • Если я отправлю BasicAck или BasicAack из Потребителя, он удалит только соответствующее сообщение из очереди или он будет доставлять Ack до издателя?
  • Как обеспечить, чтобы издатель отправил сообщение на Сервер только тогда, когда Потребитель готов к обработке?

Дизайн говорит, что издателю необходимо подождать и узнать, когда обработка Потребителя завершена, чтобы выполнить определенную задачу на стороне клиента (в зависимости от успеха/отказа).

Я пробовал под кодом, но удаляю сразу же удаленное сообщение из очереди без отправки каких-либо Ack или Nack. Я запутался код

издателя:

using (var connection = factory.CreateConnection()) 
      { 
       using (var channel = connection.CreateModel()) 
       { 
        channel.QueueDeclare("test", durable, false, false, null); 
        channel.TxSelect(); 
        var properties = channel.CreateBasicProperties(); 
        properties.SetPersistent(true); 

        string message = "Hello World!"; 
        var body = Encoding.UTF8.GetBytes(message); 



        channel.BasicPublish("", "test", properties, body); 
        channel.TxCommit(); 
        Console.WriteLine(" [x] Sent {0}", message); 
       } 
      } 

Потребительского код

using (var connection = factory.CreateConnection()) 
     { 
      using (var channel = connection.CreateModel()) 
      { 
       channel.QueueDeclare("test", durable, false, false, null); 

       var consumer = new QueueingBasicConsumer(channel); 
       channel.BasicConsume("test", true, consumer); 

       Console.WriteLine(" [*] Waiting for messages." + 
             "To exit press CTRL+C"); 
       while (true) 
       { 
        var ea = (BasicDeliverEventArgs)consumer.Queue.Dequeue(); 

        var body = ea.Body; 
        var message = Encoding.UTF8.GetString(body); 
        Console.WriteLine(" [x] Received {0}", message); 
       } 
      } 
     } 

Примечания: Я понял, что channel.BasicConsume("test", true, consumer); имеет Noack к истине. Я изменил это на channel.BasicConsume("test", false, consumer);

Я вижу сообщение удалено из очереди, когда я использовал channel.BasicAck(deliveryTag: ea.DeliveryTag, multiple: false); Но как издатель знает, что потребитель успешно обработал его?

ответ

1

Как обеспечить, чтобы издатель отправил сообщение на Сервер только тогда, когда Потребитель готов к обработке?

Вы не можете. И что более важно, вы не должны. Цель использования архитектуры обмена сообщениями - забыть о таких проблемах. Проверьте this.

Кроме того, RabbitMQ будет хранить эти сообщения для вас, пока кто-то не будет готов их обработать, если очередь долговечна.

Но как издатель знает, что потребитель успешно обработал его?

Нет, не будет. Ack только между RabbitMQ и вашим потребителем, или между RabbitMQ и вашим продюсером. Проверьте this за некоторые подробности о ack/nack.

Что вы хотите достичь здесь, если я могу вас правильно понять, это своего рода «частая» архитектура, где потребитель также является производителем «ответных сообщений» для издателя, таких как «эй, я», m сделано с сообщением XX, все в порядке ».

Простой способ сделать это - установить, чтобы ваш потребитель был также производителем, а ваш производитель также был потребителем.Вам просто нужно добавить в сообщение подсказку или уникальный идентификатор, а когда вы закончите с ним, вы отправите сообщение в другую очередь с этим идентификатором в качестве контента, чтобы сообщить об этом оригинальному издателю (который является потребителем этой очереди «ответа»), что работа выполнена успешно.

Надеюсь, это поможет :)

+0

thanks; Я знаю, что вы предоставили решение моей проблемы; который является стандартным или традиционным способом реализации? Надеюсь, первая, но не «болтливая» архитектура! – techspider

+0

Если вам нужно сообщить производителю, что пользователь «выполнил» задание, требуется ответ на канал; ответ может быть в одной очереди или в другой очереди, но это другое сообщение для отправки. В противном случае вы можете проверить саги, проверьте этот http://docs.masstransit-project.com/en/latest/overview/saga.html, но немного сложнее (и вам нужен masstransit). Возможно, вы можете переосмыслить свою архитектуру, пытаясь удалить необходимость в ответном сообщении :) –

+0

Я полностью согласен с вашим ответом; Это зависит от того, как хочет наш Архитектор;) спасибо за вашу помощь – techspider