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

RabbitMQ——有选择地从队列检索消息,rabbitmq,Rabbitmq,我是RabbitMQ的新手,想知道一个解决这个问题的好方法。我想创建一个服务,订阅一个队列,只提取满足特定条件的消息;例如,如果消息中有特定的主题标头 我仍在学习RabbitMQ,并在寻找如何实现这一点的技巧。我的问题包括:消费者如何仅从队列中提取特定消息?生产者如何在消息中设置主题标题(如果这是正确的术语?RabbitMQ非常适合这种情况。你有很多选择去做你想做的事。我建议阅读文档以便更好地理解。我建议您使用主题或直接交流。话题比较灵活。事情是这样的 生产者代码连接到RabbitMQ代理,并使

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


我仍在学习RabbitMQ,并在寻找如何实现这一点的技巧。我的问题包括:消费者如何仅从队列中提取特定消息?生产者如何在消息中设置主题标题(如果这是正确的术语?

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

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

制作人出版以交换。发布的每封邮件都将使用路由密钥发布

使用者连接到RabbitMQ代理

消费者创建队列

使用者将队列绑定到交换,与生产者中定义的交换相同。绑定还包括该特定使用者所需的每条消息的路由密钥

假设您正在发布日志消息。路由密钥可能类似于“log.info”、“log.warn”、“log.error”。制作人发布的每封邮件都会附上相关的路由密钥。然后,您将有一个消费者发送和发送所有错误消息的电子邮件,另一个消费者将所有错误消息写入一个文件。因此,emailer将使用路由键“log.error”定义从其队列到exchange的绑定。这样,尽管exchange接收所有消息,但为电子邮件发送程序定义的队列将只包含错误消息。filelogger将定义绑定到同一exchange的新单独队列,并设置不同的路由密钥。您可以为所需的三个不同路由键执行三个单独的绑定,或者只使用通配符“log.*”从exchange请求以log开头的所有消息

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


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

要从RabbitMQ检索消息,我们需要首先连接RabbitMQ服务器

公共WebClient GetRabbitMqConnection(字符串用户名、字符串密码) { var client=new WebClient(); client.Credentials=新的网络凭据(用户名、密码); 返回客户; } 现在使用以下代码从RabbitMQ检索消息

公共字符串GetRabbitMQMessages(字符串域名、字符串端口、,
string queueName、string virtualHost、WebClient客户端、string methodType)
{
string messageResult=string.Empty;
string strUri=“http://”+domainName+:“+port+
“/api/queues/”+virtualHost+“/”;
var data=client.DownloadString(strUri+queueName+“/”);
var queueInfo=JsonConvert.DeserializeObject(数据);
if(queueInfo==null | | queueInfo.messages==0)
返回字符串。空;
if(methodType==“POST”)
{
字符串postbody=”
{\'ackmode\':\'ack\'U requeue\'U 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);
}
返回消息结果;
} 

我认为这将帮助您实现RabbitMQ。

如果您希望一次检索单个消息,请在检索代码中添加以下属性

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

通过添加RabbitMQ的此属性,您可以从队列中逐个检索消息。与FIFO标准相同,建议充分利用RabbitMQ的交换/路由。如果您确实想根据消息内容进行检查,下面的代码是一个可行的解决方案

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

拉一条消息

GetResponse resp = channel.basicGet(QUEUE_NAME, false);
channel.basicAck(resp.getEnvelope().getDeliveryTag(), false);
确认一条消息

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'

您的意思是消费者可以在一个队列中检索具有特定路由密钥的消息吗?消费者似乎没有选择权,它只接收队列中的所有消息。@消费者接收队列中的所有消息。我想这就是定义。这里的要点是,它们是在exchange级别进行过滤的。通过主题交换,队列将只接收某些消息。这样一来,消费者就会继续阅读他们想要的消息,因为队列只接收消费者想要的消息。我认为这并不能回答问题。问题在于使用一个名为“log”的队列,消费者只能使用队列中的“info”日志。公平地说,作者希望做一些队列不是专门设计用来做的事情。我只是提出了一个可行的解决方案。如果您的消费者真的需要订阅(对订阅之前发布的消息不感兴趣),那么订阅(以及与选择规则绑定)不是到现有队列,而是到现有exchange(如下所述)。。然后,问题的措辞应该被编辑。你好,普尼特。欢迎来到StackOverflow。你的答案似乎没有回答这个问题。他问“消费者如何才能从队列中仅提取特定消息”和“生产者如何在消息中设置主题标题”。你的答案似乎是关于连接