SpringCloudStream+RabbitMQ使用中遇到的問(wèn)題及解決
問(wèn)題一
一個(gè)交換機(jī),多個(gè)隊(duì)列,每個(gè)隊(duì)列路由不同,向其中一個(gè)隊(duì)列發(fā)送消息后,所有隊(duì)列都能接收到消息
原因
沒(méi)有綁定確定的路由
解決
添加生產(chǎn)者路由綁定
#配置方式一:A工程作為生產(chǎn)者生產(chǎn)消息,B工程作為消費(fèi)者訂閱消息
#生產(chǎn)者:A工程
spring:
cloud:
stream:
default-binder: rabbit
bindings:
A_stream:
binder: rabbit
destination: A-exchange-dev-4
group: group_A
rabbit:
bindings:
A_stream:
consumer:
exchangeType: topic
autoBindDlq: true
republishToDlq: true
bindingRoutingKey: group_A
producer:
bindingRoutingKey: group_A
routingKeyExpression: '''group_A'''
#消費(fèi)者:B工程
spring:
cloud:
stream:
default-binder: rabbit
bindings:
A_stream:
binder: rabbit
destination: A-exchange-dev-4
group: group_A
rabbit:
bindings:
A_stream:
consumer:
exchangeType: topic
autoBindDlq: true
republishToDlq: true
bindingRoutingKey: group_A
producer:
bindingRoutingKey: group_A
routingKeyExpression: '''group_A'''問(wèn)題二
兩個(gè)不同交換機(jī)對(duì)應(yīng)不同隊(duì)列,隊(duì)列組名稱(chēng)相同,生產(chǎn)者消費(fèi)者綁定路由key相同,發(fā)送消息,目的交換機(jī)路由未收到消息,另一個(gè)卻收到消息
原因
隊(duì)列組相同
解決
修改隊(duì)列組,使交換機(jī)路由組生產(chǎn)者消費(fèi)者路由key不同,否則,不能使消息發(fā)送到目的路由
問(wèn)題三
一個(gè)隊(duì)列既是消費(fèi)者又是生產(chǎn)者,如果生產(chǎn)者和消費(fèi)者使用同一配置,容易出現(xiàn)查不到消費(fèi)者的情況
解決
生產(chǎn)者和消費(fèi)者使用不同通道
#配置方式二:同一工程中既是消費(fèi)者又是生產(chǎn)者,生產(chǎn)者消費(fèi)者分開(kāi)配置
spring:
cloud:
stream:
default-binder: rabbit
bindings:
A_output_stream:
binder: rabbit
destination: A-exchange-dev-4
group: group_A
A_input_stream:
binder: rabbit
destination: A-exchange-dev-4
group: group_A
rabbit:
bindings:
A_output_stream:
producer:
bindingRoutingKey: group_A
routingKeyExpression: '''group_A'''
A_input_stream:
consumer:
exchangeType: topic
autoBindDlq: true
republishToDlq: true
bindingRoutingKey: group_A問(wèn)題四
啟動(dòng)報(bào)錯(cuò)
如下:
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange' for queue 'exchange-dev-4-test001.product_sync' in vhost '/': received none but current is the value 'DLX' of type 'longstr', class-id=50, method-id=10)
......
org.springframework.cloud.stream.binder.BinderException: Exception thrown while starting consumer: ......
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'exchange-dev-4-test001.product_sync.errors.recoverer' defined in null: Cannot register bean definition [Root bean: class [org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] for bean 'exchange-dev-4-test001.product_sync.errors.recoverer': There is already [Root bean: class [org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null] bound.
原因
bean 定義無(wú)效,已經(jīng)有 bean 綁定。本次報(bào)錯(cuò)的原因是 bean 中對(duì)輸入通道[@Input(ProductSyncQueueComponent .INPUT)]重復(fù)定義
在同一個(gè)工程中,[exchange-dev-4-test001.product_sync]既是消費(fèi)者又是生產(chǎn)者,啟動(dòng)程序時(shí)報(bào)錯(cuò),在 mq 隊(duì)列查看 routingKey 時(shí)發(fā)現(xiàn)有兩個(gè),一個(gè)是自定義的[product_sync],一個(gè)是默認(rèn)的[#],導(dǎo)致了生產(chǎn)者發(fā)送的消息消費(fèi)者接收不到。
根據(jù)報(bào)錯(cuò)提示 bean 定義無(wú)效,檢查自定義stream bean 時(shí)發(fā)現(xiàn)下列代碼中生產(chǎn)者和消費(fèi)者都定義成了輸入通道,輸入輸出通道定義不正確。
@Component
public interface ProductSyncQueueComponent {
/**
* Input channel name.
*/
String INPUT = "product_sync_input_stream";
@Input(ProductSyncQueueComponent.INPUT)
SubscribableChannel input();
/**
* Output channel name.
*/
String OUTPUT = "product_sync_output_stream";
@Output(ProductSyncQueueComponent.OUTPUT)
SubscribableChannel output();
}解決
正確定義輸入輸出通道。(該解決方法僅使用于上述情況)
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Springboot整合MongoDB進(jìn)行CRUD操作的兩種方式(實(shí)例代碼詳解)
這篇文章主要介紹了Springboot整合MongoDB進(jìn)行CRUD操作的兩種方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04
Java 基于tcp協(xié)議實(shí)現(xiàn)文件上傳
這篇文章主要介紹了Java 基于tcp協(xié)議實(shí)現(xiàn)文件上傳,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-11-11
springboot的maven多模塊混淆jar包的實(shí)現(xiàn)方法
springboot可以使用proguard-maven-plugin 這個(gè)插件 在 pom.xml 中自定義proguard 的指令,本文基于 springboot + maven + proguard 的maven多模塊架構(gòu)進(jìn)行代碼混淆,需要的朋友可以參考下2024-03-03
Mybatis?mysql模糊查詢(xún)方式(CONCAT多個(gè)字段)及bug
這篇文章主要介紹了Mybatis?mysql模糊查詢(xún)方式(CONCAT多個(gè)字段)及bug,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01
java在hashmap初始化時(shí)賦初值過(guò)程解析
這篇文章主要介紹了java在hashmap初始化時(shí)賦初值過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Springcloud seata nacos環(huán)境搭建過(guò)程圖解
這篇文章主要介紹了Springcloud seata nacos環(huán)境搭建過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03

