最近,我开始使用Spring Cloud Stream和RabbitMQ binder。
如果我在两个服务要传递消息时正确理解了所有内容,则应配置 source 以发送消息,而其他服务应配置 sink 以接收消息 - 两者都应使用相同的频道。
我的频道名为testchannel
。不过,我注意到 source 创建了RabbitMQ绑定:
testchannel
,testchannel
,testchannel.default
(持久),当 sink 创建RabbitMQ绑定时:
testchannel
,#
,testchannel.anonymous.RANDOM_ID
(excusive)。为简洁起见,我跳过了前缀。
现在我运行两个应用程序。第一个向testchannel
交换发送消息,然后路由到两个队列(我假设路由密钥是testchannel
)。第二个应用程序使用来自随机队列的消息,但永远不会消耗来自默认队列的消息。
我的另一个问题是 - 第二个应用程序仅使用 sink ,但它也为输出通道创建了绑定,默认情况下为output
,因为我没有指定任何内容。 / p>
我使用相同的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
Fisrt app源代码:
@EnableBinding(Processor.class)
...
@ServiceActivator(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
public byte[] handleIncomingMessage(byte[] payload) {}
第二个应用属性:
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(Sink.class)
...
@ServiceActivator(inputChannel = Sink.INPUT)
public void handleIncomingMessage(byte[] payload) {}
所以我的问题是。
答案 0 :(得分:2)
默认情况下;消费者各自得到自己的队列;它是一个发布/订阅场景。
有一个消费者group
的概念,因此您可以让多个实例竞争来自同一队列的消息。
绑定生产者时,绑定默认队列。
如果您想订阅default
组;你必须设置组:
spring.cloud.stream.bindings.input.group=default
如果您没有提供群组,则会获得一个独占的自动删除队列。
修改强>
由于默认队列是持久的,您还应该设置
spring.cloud.stream.bindings.input.durableSubscription=true
在消费者绑定时避免发出警告,如果消费者先绑定并且队列尚未存在,则确保队列是持久的。