我正在尝试将 spring cloud stream functions
用于 spring boot
应用程序中的应用程序之间的消息传递。 (我已阅读此question)。
我使用 3.1.0-RC1 版本,因为他们在那里引入了我需要的 CloudEvent
消息生成器。我也使用 RabbitMQ
活页夹。我在本地运行 RabbitMQ
。
我有 Application A
,它需要将消息中的一些数据(CloudEvent
规范)传送到 Application B
。
所以 Application B
是接收者(或 spring cloud stream
术语中的消费者)。
@Bean
public Consumer<Message<MyMessageData>> onEventOneMessage(){
return msg -> {
// Get the contained message, log and return it
MyMessageData myMessageData = msg.getPayload();
log.debug("Received Cloud Event on event one: " +
myMessageData.toString());
// Some processing code ...
};
}
@Bean
public Consumer<Message<MyMessageData>> onEventTwoMessage(){
return msg -> {
// Get the contained message, log and return it
MyMessageData myMessageData = msg.getPayload();
log.debug("Received Cloud Event to event two: " +
myMessageData.toString());
// Some processing code ...
};
}
而application.yaml
相关配置的Application B
为:
spring:
cloud:
function:
definition: onEventOneMessage;onEventTwoMessage
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
那么 Application A
是供应商\来源。由于我找不到明确触发消息发送的方法,因此我按照我引用的问题的答案中的建议使用了 StreamBridge
。
它使用以下模式构建目标名称:on<EventName>-in-0
。
private ObjectMapper objectMapper = new ObjectMapper();
private final StreamBridge streamBridge;
/**
* Sends a message to the queue
*
* @param message The message to send
*/
@Override
public void sendDirectMessage(MyMessage message) {
if (message.getEvent() == null){
throw new MyMessagingException("Must contain an event specification");
}
try {
// Create the routing expression (function definition to look for)
String routingExpression = String.format("on%s-in-0", message.getEvent().toString());
// Wrap the message in CloudEvent spec message
Message<String> inputMessage = CloudEventMessageBuilder
.withData(objectMapper.writeValueAsString(message))
.setSource("https://spring.io/spring-event")
.setType("com.example.springevent")
.build();
this.streamBridge.send(routingExpression, inputMessage);
}
catch(Exception ex){
throw new MyMessagingException(String.format("Failed to send a message: %s", message.toString()), ex);
}
}
由于我动态创建目标,因此我不会在提供程序的 application.yaml
处注册源。
StreamBridge
有效但消费者方法被多次调用(重复消息),而不仅仅是一次。
知道这种行为的原因是什么吗?