事件发布/接收流程
- new RemoteApplicationEvent() 创建事件
- applicationContext#publishEvent 本地发布事件
- BusAutoConfiguration#acceptLocal 监听、接收Remote事件
- serviceMatcher#isFromSelf 判断是否是自己发出的事件
- cloudBusOutboundChannel#send 如果是自己发出的,广播给MQ
- MQ收发(Rabbit/Kafka)
- BusAutoConfiguration#acceptRemote 接收MQ发来的事件
- serviceMatcher#isForSelf 判断是否是发给自己的
- applicationEventPublisher#publishEvent 本地广播事件
- 本地注册的ApplicationEventListener<?>调用
事件如何路由?判断是本地还是远程?
- ServiceMatcher#isFromSelf,ServiceMatcher#isForSelf来路由事件
- 判断的字段是RemoteApplicationEvent.originService和RemoteApplicationEvent.destinationService
- 判断方式是带:分号分割的Ant路径, BusAutoConfiguration#MatcherConfiguration
- BUS对originService的赋值来源于ApplicationContext#getId
- contextid在启动时确定,name + index
- ContextIdApplicationContextInitializer#getApplicationId
- NAME_PATTERN = "{vcap.application.name:${spring.config.name:application}}}";
- INDEX_PATTERN = "{spring.application.index:{PORT:null}}}}";
- 在集群部署下,每个实例可能在不同机器但是同一个端口。这时index会重复。导致EventBus判断错误。
- 这时可以定义一个随机值 spring.application.index=${random.uuid}
技术栈
- BUS背后是使用MQ(Rabbitmq/Kafka)来实现的,不过技术栈/概念非常多,这大致介绍下层级关系。以Rabbitmq为例
- spring-cloud-bus
- spring-cloud-stream
- spring-integration
- spring-messageing
- spring-amqp
- spring-rabbit
- http-client(RabbitMq)