如何检查RabbitMQ消息队列是否存在?

发布于 2024-09-14 05:06:14 字数 440 浏览 11 评论 0原文

如何检查消息队列是否已存在?

我有两个不同的应用程序,一个创建队列,另一个从该队列读取。

因此,如果我运行首先从队列中读取的客户端,它就会崩溃。
因此,为了避免这种情况,我想首先检查队列是否存在。

这是我如何读取队列的代码片段:

QueueingBasicConsumer <ConsumerName> = new QueueingBasicConsumer(<ChannelName>); 
<ChannelName>.BasicConsume("<queuename>", null, <ConsumerName>); 
BasicDeliverEventArgs e = (BasicDeliverEventArgs)<ConsumerName>.Queue.Dequeue();

How can I check whether a message Queue already exists or not?

I have 2 different applications, one creating a queue and the other reading from that queue.

So if I run the Client which reads from the queue first, than it crashes.
So to avoid that i would like to check first whether the queue exists or not.

here is the code snippet of how I read the queue:

QueueingBasicConsumer <ConsumerName> = new QueueingBasicConsumer(<ChannelName>); 
<ChannelName>.BasicConsume("<queuename>", null, <ConsumerName>); 
BasicDeliverEventArgs e = (BasicDeliverEventArgs)<ConsumerName>.Queue.Dequeue();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

霓裳挽歌倾城醉 2024-09-21 05:06:14

不用费心检查。

queue.declare 是一个幂等操作。所以,如果你运行一次、两次、N次,结果仍然是一样的。

如果要确保队列存在,只需在使用前声明即可。确保每次都以相同的持久性、排他性、自动删除性来声明它,否则您将得到例外。

如果您确实需要检查队列是否存在(通常不需要),请对队列进行被动声明。如果队列存在,则该操作成功;如果不存在,则操作失败并出现错误。

Don't bother checking.

queue.declare is an idempotent operation. So, if you run it once, twice, N times, the result will still be the same.

If you want to ensure that the queue exists, just declare it before using it. Make sure you declare it with the same durability, exclusivity, auto-deleted-ness every time, otherwise you'll get an exception.

If you actually do need to check if a queue exists (you shouldn't normally need to), do a passive declare of the queue. That operation succeeds if the queue exists, or fails in an error if it doesn't.

游魂 2024-09-21 05:06:14

将以下代码放入 try catch 部分。如果队列或交换器不存在,则会抛出错误。如果存在它不会做任何事情。

  var channel = connection.CreateModel();


  channel.ExchangeDeclarePassive(sExchangeName);

  QueueDeclareOk ok = channel.QueueDeclarePassive(sQueueName);

   if (ok.MessageCount > 0)
    {
      // Bind the queue to the exchange

     channel.QueueBind(sQueueName, sExchangeName, string.Empty);
    }

Put below code inside try catch section. If queue or exchange doesn't exist then it will throw error. if exists it will not do anything.

  var channel = connection.CreateModel();


  channel.ExchangeDeclarePassive(sExchangeName);

  QueueDeclareOk ok = channel.QueueDeclarePassive(sQueueName);

   if (ok.MessageCount > 0)
    {
      // Bind the queue to the exchange

     channel.QueueBind(sQueueName, sExchangeName, string.Empty);
    }
冷月断魂刀 2024-09-21 05:06:14

当有其他人(其他应用程序)负责 q 声明时,这将不起作用。我根本不知道 q 的所有参数,只知道名称。

我宁愿使用 PassiveDeclare 并检查 q 不存在的 IOException

This won't work in situations when there is someone else (other application) responsible for q declaration. And I simply could not know all the parameters of the q, just the name.

I would rather use passiveDeclare and check for the IOException that the q does not exists

2024-09-21 05:06:14

目前,您可以通过 RabbitMQ 管理 HTTP API

例如,要了解此时是否有一个队列已启动,可以调用 API 的 GET /api/queues/vhost/name 接口。

Currently you can know that info and much more throught RabbitMQ Management HTTP API.

For example, to know if one queue is up at this moment, you can invoke to GET /api/queues/vhost/name interface of the API.

梦在深巷 2024-09-21 05:06:14

spring-amqp中有一个meta api(java实现)

@Autowired
public RabbitAdmin rabbitAdmin;

//###############get you queue details##############
Properties properties = rabbitAdmin.getQueueProperties(queueName);

//do your custom logic
if( properties == null)
{
    createQueue(queueName);
}

There is a meta api in spring-amqp(java implementation)

@Autowired
public RabbitAdmin rabbitAdmin;

//###############get you queue details##############
Properties properties = rabbitAdmin.getQueueProperties(queueName);

//do your custom logic
if( properties == null)
{
    createQueue(queueName);
}
随遇而安 2024-09-21 05:06:14

正如其他答案中提到的,channel.QueueDeclarePassive(QueueName) 将允许您检查队列是否存在,而无需尝试重​​新声明(例如,如果您更改了队列设置,否则会导致异常)。

但是QueueDeclarePassive()似乎只检查根虚拟主机。如果您的目标队列实际上位于自定义虚拟主机中,您可能(尚未测试)得到漏报。如果根虚拟主机中存在同名队列,您将(经过测试)得到误报。

也许将 QueueDeclare() 包装在 try-catch 中可能是一个更好的方法,尽管在我看来,您将得到的 RabbitMQ.Client.Exceptions.OperationInterruptedException 太包罗万象了使其成为一种安全的方法。

As mentioned in other answers, channel.QueueDeclarePassive(QueueName) will allow you to check queue's existence without attempting to redeclare (e.g. if you changed the queue settings and would otherwise cause an exception).

However, QueueDeclarePassive() seems to only check the root vhost. You may (haven't tested) get a false negative if your target queue is actually in a custom vhost. You will (tested) get a false positive, if a queue with the same name exists in root vhost.

Maybe wrapping QueueDeclare() in try-catch could be a better way to go, though IMO the RabbitMQ.Client.Exceptions.OperationInterruptedException you'll get is too catch-all for it to be a safe approach.

谁与争疯 2024-09-21 05:06:14

按照建议使用 QueueDeclare() 执行此操作。此外,我们一直所做的就是让队列的使用者成为队列的所有者,并始终发布到由发布者创建和拥有的 Exchange。然后,消费者将他们的队列绑定到他们希望从中接收流量的交换机,并为他们想要的流量使用适当的路由键过滤器。通过这种方式,发布者不会被非持久队列的消费者静音,并且消费者可以自由地使用与适当的路由键映射的持久或非持久队列来来去去。

这会形成一个易于管理的系统,并允许使用 Web 管理来创建持久队列并将其绑定到交换器,获取一些流量,解除绑定,然后检查队列内容以了解通过交换器的流量和负载。

Use QueueDeclare() to perform this as suggested. Also, what we have always done, is make the consumer of the queue be the owner of the queue, and always publish to Exchanges which are created and owned by publishers. Consumers then bind their queues to the exchanges that they wish to receive traffic from and use an appropriate route key filter for the traffic they want. In this way, publishers are muted by no consumers for non-durable queues, and consumers are free to come and go with durable or non-durable queues mapped with the appropriate route keys.

This results in an easily administered system and allows web administration to be used to create a durable queue and bind it to an exchange, get some traffic, unbind it, and then inspect the queue contents to understand what traffic and load is coming through the exchange.

电影里的梦 2024-09-21 05:06:14

以我的愚见,最好的方法是覆盖rabbitmq的默认配置。

主类应该禁用默认的rabbit配置:

    @SpringBootApplication
    @EnableAutoConfiguration(exclude 
  {org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration.class})
  public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

我的rabbitmq属性位于rabbitmq.properties文件中:

...
    rabbitmq.queue=my-queue
...

然后只需创建自己的配置rabbitmq组件:

@Component
@EnableRabbit
@PropertySource("classpath:rabbitmq.properties")
public class RabbitMQConfiguration
{
...
    @Value("${rabbitmq.queue}")
    private String queueName;

...

    @Bean
    public Queue queue() {
        return new Queue(queueName, false);
    }
...

还应该设置消费者:

@Component
@PropertySource("classpath:rabbitmq.properties")
public class MyConsumer
{
    private static Logger LOG = LogManager.getLogger(MyConsumer.class.toString());

    @RabbitListener(queues = {"${rabbitmq.queue}"})
    public void receive(@Payload Object data) {
        LOG.info("Message: " + data) ;
    }

现在,当客户端启动时,它会自动创建队列,如果它不存在。如果队列存在,则不执行任何操作。

In my humble opinion, best way is to override rabbitmq default configuration.

Main class should disable default rabbit configuration:

    @SpringBootApplication
    @EnableAutoConfiguration(exclude 
  {org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration.class})
  public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }

}

my rabbitmq properties are in rabbitmq.properties file:

...
    rabbitmq.queue=my-queue
...

Then just create own configuration rabbitmq component:

@Component
@EnableRabbit
@PropertySource("classpath:rabbitmq.properties")
public class RabbitMQConfiguration
{
...
    @Value("${rabbitmq.queue}")
    private String queueName;

...

    @Bean
    public Queue queue() {
        return new Queue(queueName, false);
    }
...

Also consumer should be setuped:

@Component
@PropertySource("classpath:rabbitmq.properties")
public class MyConsumer
{
    private static Logger LOG = LogManager.getLogger(MyConsumer.class.toString());

    @RabbitListener(queues = {"${rabbitmq.queue}"})
    public void receive(@Payload Object data) {
        LOG.info("Message: " + data) ;
    }

Now when client starts it would automatically create queue if it does not exists. If queue exists it do nothing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文