使用 Spring Cloud Stream,我应该为每种事件类型配置通道吗?
With Spring Cloud Stream, should I config channels for every event type?
我正在开发一个项目,使用 springboot、spring cloud netflix 等构建微服务。
对于一些异步通信,我使用 Spring Cloud Stream 来生成和使用事件。例如在合同服务中起草业务合同后,该服务会发布一个合同创建事件,该事件将由审计服务使用,以启动审计过程。而且,用户服务将使用该事件为相关方创建通知。
场景是我有很多事件,消费者会根据事件类型订阅感兴趣的事件。
我遇到的问题是,我有很多事件类型,很快,我的配置文件就充满了通道配置。例如
spring.cloud.stream.bindings.creation.destination=contract-creation
spring.cloud.stream.bindings.revocation.destination=contract-revocation
spring.cloud.stream.bindings.termination.destination=contract-termination
...
我做错了什么?我正在考虑这些替代方案:
- David Turanski!有一个示例,它将按类型选择性地使用事件。这是一个很好的解决方案,但我在想,Spring Cloud Stream 是否有原生解决方案?
- 我应该使用 Apache Camel 还是 Spring 集成?我没有复杂的路由规则,这些框架看起来有点矫枉过正。
我是消息传递方面的新手,希望这里的人能给我指明正确的方向。
David 的博客 post 中提到的 condition
表达式 属性 被烘焙到 @StreamListener
注释中,因此您可以将不同的事件类型从同一目的地路由到不同的目的地听众。
这真的取决于,我很抱歉开始回答这个问题。
拥有一个带选择器的通道是最简单的选择,但需要注意的是每个消费者都将消费来自该目的地的所有消息。如果这是您的用例,那就去做吧。
另一个用例是事件源类型,其中大多数消费者只对事件的一个子集感兴趣,您可能会更好地在每个目的地放置事件(或更好的聚合根)。这将使您能够更好地扩展,并避免从经纪人到消费者的不必要的喋喋不休。
在您的示例中,您可以使用类似这样的内容:
public interface Contracts {
@Output("contract-creation") MessageChannel creation();
@Output("contract-revogation") MessageChannel revogation();
@Output("contract-termination") MessageChannel termination();
}
这会为每个事件类型创建一个主题,也许有点矫枉过正
也许您应该创建一个带有 Type
的接口 Event
并让您的事件从它继承,然后改为:
public interface Events {
@Output MessageChannel user();
@Output MessageChannel contract();
}
现在,所有合同事件(创建、撤销、终止)都将转到同一个目的地。在接收端,您可以创建选择器来选择要应用的选择器:
@StreamListener(target = "contract", condition = "payload.type=='created'")
public void contractCreated(@Payload ContractCreatedEvent){
}
@StreamListener(target = "contract", condition = "payload.type=='terminated'")
public void contractTerminated(@Payload ContractTerminatedEvent){
}
我正在开发一个项目,使用 springboot、spring cloud netflix 等构建微服务。
对于一些异步通信,我使用 Spring Cloud Stream 来生成和使用事件。例如在合同服务中起草业务合同后,该服务会发布一个合同创建事件,该事件将由审计服务使用,以启动审计过程。而且,用户服务将使用该事件为相关方创建通知。
场景是我有很多事件,消费者会根据事件类型订阅感兴趣的事件。 我遇到的问题是,我有很多事件类型,很快,我的配置文件就充满了通道配置。例如
spring.cloud.stream.bindings.creation.destination=contract-creation
spring.cloud.stream.bindings.revocation.destination=contract-revocation
spring.cloud.stream.bindings.termination.destination=contract-termination
...
我做错了什么?我正在考虑这些替代方案:
- David Turanski!有一个示例,它将按类型选择性地使用事件。这是一个很好的解决方案,但我在想,Spring Cloud Stream 是否有原生解决方案?
- 我应该使用 Apache Camel 还是 Spring 集成?我没有复杂的路由规则,这些框架看起来有点矫枉过正。
我是消息传递方面的新手,希望这里的人能给我指明正确的方向。
David 的博客 post 中提到的 condition
表达式 属性 被烘焙到 @StreamListener
注释中,因此您可以将不同的事件类型从同一目的地路由到不同的目的地听众。
这真的取决于,我很抱歉开始回答这个问题。
拥有一个带选择器的通道是最简单的选择,但需要注意的是每个消费者都将消费来自该目的地的所有消息。如果这是您的用例,那就去做吧。
另一个用例是事件源类型,其中大多数消费者只对事件的一个子集感兴趣,您可能会更好地在每个目的地放置事件(或更好的聚合根)。这将使您能够更好地扩展,并避免从经纪人到消费者的不必要的喋喋不休。
在您的示例中,您可以使用类似这样的内容:
public interface Contracts {
@Output("contract-creation") MessageChannel creation();
@Output("contract-revogation") MessageChannel revogation();
@Output("contract-termination") MessageChannel termination();
}
这会为每个事件类型创建一个主题,也许有点矫枉过正
也许您应该创建一个带有 Type
的接口 Event
并让您的事件从它继承,然后改为:
public interface Events {
@Output MessageChannel user();
@Output MessageChannel contract();
}
现在,所有合同事件(创建、撤销、终止)都将转到同一个目的地。在接收端,您可以创建选择器来选择要应用的选择器:
@StreamListener(target = "contract", condition = "payload.type=='created'")
public void contractCreated(@Payload ContractCreatedEvent){
}
@StreamListener(target = "contract", condition = "payload.type=='terminated'")
public void contractTerminated(@Payload ContractTerminatedEvent){
}