使用Camel的spring-rabbitmq组件时如何自动声明交换?

问题描述 投票:0回答:2

我正在尝试从 Camel 3.x 迁移到 Camel 4.x 版本,因此我需要从

rabbitmq
组件迁移到替换组件
spring-rabbitmq
。对于
rabbitmq
组件,我使用
declare
选项让 Camel 自动创建和绑定队列和交换器,现在我正在
spring-rabbitmq
组件中寻找等效选项:

从文档看来这是可能的:自动声明交换、队列和绑定

在可以从RabbitMQ发送或接收消息,然后进行交换之前, 必须首先设置队列和绑定。

在开发模式下,可能需要让 Camel 自动执行 这。您可以通过设置 autoDeclare=true 来启用此功能 SpringRabbitMQComponent.

然后 Spring RabbitMQ 将自动声明必要的元素并 设置交换键、队列键和路由键之间的绑定。

因此,我已将

camel.component.spring-rabbitmq.auto-declare
属性配置为
true
中的
application.properties
,但这似乎只影响 RabbitMQ 消费者端点,而不影响生产者。

使用这个简单的路线:

<route id="receive-send-rabbitmq">
    <from uri="spring-rabbitmq:in-exchange?queues=queue-in"/>
    <log message="message received" />    
    <to uri="spring-rabbitmq:out-exchange"/>
</route>

in-exchange
queue-in
对象在启动路线时由Camel正确自动声明,消息被正确接收。但由于交换
out-exchange
不可用,发送部分失败。堆栈跟踪:

2023-07-10T11:54:12.094+02:00 DEBUG 3796 --- [pool-2-thread-5] o.s.amqp.rabbit.core.RabbitTemplate      : Publishing message [(Body:'[B@149e60f3(byte[3])' MessageProperties [headers={}, contentType=application/octet-stream, contentLength=3, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])] on exchange [out-exchange], routingKey = []
2023-07-10T11:54:12.099+02:00  INFO 3796 --- [ 127.0.0.1:5672] com.rabbitmq.client.impl.AMQConnection   : Received a frame on an unknown channel, ignoring it
2023-07-10T11:54:12.099+02:00 DEBUG 3796 --- [pool-2-thread-5] o.s.amqp.rabbit.connection.RabbitUtils   : Unexpected exception on closing RabbitMQ Channel

com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'out-exchange' in vhost '/', class-id=60, method-id=40)
    at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
    at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36)
    at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:502)

    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - no exchange 'out-exchange' in vhost '/', class-id=60, method-id=40)
    at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:517)
    at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:341)
    at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:182)
    at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:114)
    at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:743)
    at com.rabbitmq.client.impl.AMQConnection.access$300(AMQConnection.java:47)
    at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:670)
    ... 1 common frames omitted

我知道我可以使用

RabbitAdmin
声明这些交换,但我不想在我的应用程序代码中手动处理此问题,路由作为 XML 文件传递在专用文件夹中,由应用程序在启动时动态加载。

使用 Camel 4.0.0-rc1 和 Spring Boot 3.1.1。

rabbitmq apache-camel spring-rabbit
2个回答
1
投票

仅仅因为此组件选项仅适用于消费者端点,正如文档中明确指出的那样,我引用:

指定consumer在启动时是否应自动声明交换器、队列和路由键之间的绑定。启用此功能有利于开发,可以轻松地在代理上建立交换、队列和绑定。

对于生产者端点,您需要通过将您的

Queue
声明为常规bean来手动创建它,Spring将自动为您创建队列。

@Bean
public Queue myDurableQueue() {
    // This queue has the following properties:
    // name: my_durable
    // durable: true
    // exclusive: false
    // auto_delete: false
    return new Queue("my_durable", true, false, false);
}

请参阅此答案了解更多详细信息。


0
投票

里丘蒂,

请告诉我你是否已经解决了这个问题,我在骆驼升级后也面临着同样的情况。

提前致谢。

© www.soinside.com 2019 - 2024. All rights reserved.