RabbitMQ--有选择地从队列中检索消息

时间:2012-06-21 15:58:01

标签: rabbitmq

我是RabbitMQ的新手,并且想知道我正在考虑解决这个问题的好方法。我想创建一个订阅队列的服务,只提取符合特定条件的消息;例如,如果消息中有特定的主题标题。

我还在学习RabbitMQ,并且正在寻找如何解决这个问题的技巧。我的问题包括:消费者如何仅从队列中提取特定消息?生产者如何在消息中设置主题标题(如果这甚至是正确的术语?)

4 个答案:

答案 0 :(得分:24)

RabbitMQ非常适合这种情况。你有很多选择可以做你想做的事。我建议阅读文档以便更好地理解。我建议您使用主题或直接交换。主题更灵活。它是这样的。

生产者代码连接到RabbitMQ Broker并使用特定名称创建和交换。

制片人发布以进行交流。发布的每条消息都将使用路由密钥发布。

Consumer连接到RabbitMQ代理。

消费者创建队列

Consumer将Queue绑定到交换机,即生产者中定义的相同交换。绑定还包括此特定使用者所需的每条消息的路由键。

让我们说你发布了日志消息。路由键可能类似于“log.info”,“log.warn”,“log.error”。生产者发布的每条消息都附有相关的路由密钥。然后,您将拥有一个发送和发送电子邮件以获取所有错误消息的消费者,以及另一个将所有错误消息写入文件的消费者。因此,电子邮件程序将使用路由键“log.error”定义从其队列到交换的绑定。这样,虽然交换机接收所有消息,但为电子邮件发送者定义的队列将只包含错误消息。 filelogger将定义绑定到同一交换机的新单独队列,并设置不同的路由密钥。您可以为三个不同的路由键要求执行三个单独的绑定,或者只使用通配符“log。*”从log开始请求来自交换的所有消息。

这是一个简单的例子,展示了如何实现你想要做的事情。

查看here代码示例,具体编号为5号教程。

答案 1 :(得分:1)

  1. To Retrive Message from RabbitMQ we need to first connect with RabbitMQ server 

    public WebClient GetRabbitMqConnection(string userName, string password)
    {
        var client = new WebClient(); 
        client.Credentials = new NetworkCredential(userName, password);
        return client;
    }

 2. Now retrieve message from RabbitMQ using below code.

      public string GetRabbitMQMessages(string domainName, string port, string 
                    queueName, string virtualHost, WebClient client, string 
                    methodType)
      {
                  string messageResult = string.Empty;
                  string strUri = "http://" + domainName + ":" + port + 
                                  "/api/queues/" + virtualHost + "/";
                  var data = client.DownloadString(strUri + queueName + "/");
                  var queueInfo = JsonConvert.DeserializeObject<QueueInfo>(data);
                  if (queueInfo == null || queueInfo.messages == 0)
                             return string.Empty;
                  if (methodType == "POST")
                  {
                      string postbody = "  
                      {\"ackmode\":\"ack_requeue_true\",\"count\":
                       \"$totalMessageCount\",\"name\":\"${DomainName}\",
                       \"requeue\":\"false\",\"encoding\":\"auto\",\"vhost\" :
                       \"${QueueName}\"}";
                       postbody = postbody.Replace("$totalMessageCount", 
                       queueInfo.messages.ToString()).Replace("${DomainName}", 
                       domainName).Replace("${QueueName}", queueName);
                       messageResult = client.UploadString(strUri + queueName + 
                       "/get", "POST", postbody);
                }
                return messageResult;
    } 


   I think this will help you to implement RabbitMQ.

答案 2 :(得分:1)

建议充分利用Rabbitmq进行交换/路由。如果确实要根据消息内容进行检查,则以下代码是一种解决方案。

从队列中检索邮件并检查,有选择地确认您感兴趣的邮件。

发送一封邮件

GetResponse resp = channel.basicGet(QUEUE_NAME, false);

确认一条消息

channel.basicAck(resp.getEnvelope().getDeliveryTag(), false);

示例

import com.rabbitmq.client.*;

public class ReceiveLogs {
    private final static String QUEUE_NAME = "hello";

    public static void main(String[] argv) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try(Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();){

            channel.queueDeclare(QUEUE_NAME, true, false, false, null);

            // pull one message and ack manually and exit
            GetResponse resp = channel.basicGet(QUEUE_NAME, false);
            if( resp != null ){
                String message = new String(resp.getBody(), "UTF-8");
                System.out.println(" [x] Received '" + message + "'");
                channel.basicAck(resp.getEnvelope().getDeliveryTag(), false);
            }
            System.out.println();
        }
    }
}

依赖性

compile group: 'com.rabbitmq', name: 'amqp-client', version: '5.8.0'

答案 3 :(得分:-1)

如果您想一次检索一条消息,请在“检索代码”中添加以下属性。

Boolean autoAck = false;
model.BasicConsume(Queuename, autoAck);
model.BasicGet("Queuename", false);
model.BasicGet("Queuename", false); 

通过添加RabbitMQ的此属性,您可以从队列中逐个检索消息。类似于FIFO条件