Spring cloud Spring Cloud Stream with Rabbit Binder-源/接收器队列名称don';不匹配
最近,我开始玩SpringCloudStream和RabbitMQ活页夹 如果我在两个服务想要传递消息时都理解正确,那么一个应该配置发送消息的源,另一个应该配置接收消息的接收器——两者都应该使用相同的通道 我有一个名为Spring cloud Spring Cloud Stream with Rabbit Binder-源/接收器队列名称don';不匹配,spring-cloud,spring-rabbit,spring-cloud-stream,Spring Cloud,Spring Rabbit,Spring Cloud Stream,最近,我开始玩SpringCloudStream和RabbitMQ活页夹 如果我在两个服务想要传递消息时都理解正确,那么一个应该配置发送消息的源,另一个应该配置接收消息的接收器——两者都应该使用相同的通道 我有一个名为testchannel的频道。不过,我注意到源代码创建了RabbitMQ绑定: 交换testchannel 路由键testchannel 队列testchannel.default(持久) 接收器创建RabbitMQ绑定时: 交换testchannel 路由键# 队列test
testchannel
的频道。不过,我注意到源代码创建了RabbitMQ绑定:
- 交换
testchannel
- 路由键
testchannel
- 队列
(持久)testchannel.default
- 交换
testchannel
- 路由键
#
- 队列
(排除)testchannel.anonymous.RANDOM\u ID
testchannel
exchange,然后将其路由到两个队列(我假设路由键是testchannel
)。第二个应用程序使用来自随机队列的消息,但从不使用来自默认队列的消息
我的另一个问题是-2nd应用程序只使用接收器,但它也为输出通道创建绑定,默认情况下是output
,因为我没有指定任何内容
我使用相同的Gradle脚本构建两个应用程序:
buildscript {
ext {
springBootVersion = '1.3.2.RELEASE'
}
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'spring-boot'
repositories {
mavenCentral()
maven { url 'https://repo.spring.io/snapshot' }
maven { url 'https://repo.spring.io/milestone' }
}
dependencies {
compile(
'org.springframework.cloud:spring-cloud-starter-stream-rabbit',
)
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:Brixton.BUILD-SNAPSHOT"
}
}
第一个应用程序属性:
server.port=8010
spring.cloud.stream.binder.rabbit.default.prefix=z.
spring.cloud.stream.bindings.input=start
spring.cloud.stream.bindings.output=testchannel
spring.rabbitmq.addresses=host1:5672,host2:5672
spring.rabbitmq.username=user
spring.rabbitmq.password=psw
server.port=8011
spring.cloud.stream.binder.rabbit.default.prefix=z.
spring.cloud.stream.bindings.input=testchannel
spring.rabbitmq.addresses=host1:5672,host2:5672
spring.rabbitmq.username=user
spring.rabbitmq.password=psw
First应用程序源代码:
@EnableBinding(Processor.class)
...
@ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
public byte[] handleIncomingMessage(byte[] payload) {}
@EnableBinding(Sink.class)
...
@ServiceActivator(inputChannel = Sink.INPUT)
public void handleIncomingMessage(byte[] payload) {}
第二个应用程序属性:
server.port=8010
spring.cloud.stream.binder.rabbit.default.prefix=z.
spring.cloud.stream.bindings.input=start
spring.cloud.stream.bindings.output=testchannel
spring.rabbitmq.addresses=host1:5672,host2:5672
spring.rabbitmq.username=user
spring.rabbitmq.password=psw
server.port=8011
spring.cloud.stream.binder.rabbit.default.prefix=z.
spring.cloud.stream.bindings.input=testchannel
spring.rabbitmq.addresses=host1:5672,host2:5672
spring.rabbitmq.username=user
spring.rabbitmq.password=psw
第二个应用程序源代码:
@EnableBinding(Processor.class)
...
@ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
public byte[] handleIncomingMessage(byte[] payload) {}
@EnableBinding(Sink.class)
...
@ServiceActivator(inputChannel = Sink.INPUT)
public void handleIncomingMessage(byte[] payload) {}
所以我的问题是
- 源和接收器不应该使用相同的通道,从而导致相同的代理队列吗?实现这一目标的正确配置是什么?(我的目标是拥有多个接收器服务实例,但只有一个应该使用该消息。)
- 当我只使用接收器时,框架是否应该创建输出绑定?如果是,如何禁用它
默认情况下,
组的概念,因此您可以让多个实例竞争来自同一队列的消息
绑定生产者时,将绑定默认队列
如果您希望订阅默认组
;您必须设置组:
spring.cloud.stream.bindings.input.group=default
如果不提供组,则会得到一个独占的自动删除队列
编辑
由于默认队列是持久的,因此还应设置
spring.cloud.stream.bindings.input.durableSubscription=true
为了避免消费者绑定时出现警告,并确保如果消费者先绑定,而队列还不存在,则队列是持久的。您在默认情况下说过。是否有任何配置允许我将其更改为对等场景?直接频道似乎更适合我的需要。将组设置为default
可以做到这一点。我没有更改第一服务(A)。我将第二个服务(B)输入通道的组更改为默认值
。当我运行A时,B-B会抱怨队列的耐久性。异常:通道错误;协议方法:#方法(回复代码=406,回复文本=Premission_失败-vhost'/'中队列'z.test.default'的参数'dustable'不相等:收到'false',但当前为'true',类id=50,方法id=10)
更正:使用组默认设置确实可以作为对等设置。非常感谢。上述例外情况仅为警告。(不确定是否应该有任何警告,因为此设置是预期的用例之一。但这只是一个离题。)至于由输出队列产生的仅接收器用例-可能已修复,因为我现在没有看到它,今天的构建下载了新版本的Spring库。再次感谢您的帮助。啊,最后一个问题-是否可以更改输出默认组名?输出通道的相同属性似乎没有效果。输出队列始终以结束。默认值。