在有些架构中,我们经常看到组件或服务会发送一个消息到一个其它的组件(可能是一个注册有回调函数的响应器或一个不断接收信息的循环处理程序或一个消息中间件),这种交互形式称之为基于事件的通信模式。发送消息的一方称为发送者或生产者,接收消息的一方称为接收者或消费者。
同步和异步
-
同步事件:发送者发送一个事件后等待一个立即响应,比如常见的rpc调用或rest调用
-
异步事件:发送者抛出一个事件后,不需要任何等待,事件的处理结果(如果有的话)可能会从不同于发送事件的路径返回。因为发送者不会等待,因此这些事件往往会通过中间件(消息队列)来投递,而且可能会被多次投递(多次处理)。
异步事件通常通过中间件来进行事件的投递(大多数情况下生产者应该信任消息中间件的可靠性,即投递给消息中间件意味着接收者在后面的某一时间肯定会获取到事件),通过消息中间件投递解耦了发送者和接收者,使得接收者行为更加灵活。
异步事件流通常是单向的,因为异步事件通常通过消息中间件来投递事件,这意味着发送者只能立即获取到消息中间件的响应(事件发送到消息中间件是否成功)。发送者对于事件处理结果和异常需要通过单独的通道来获取,这也使得事件和事件的处理结果的对应关系更加的灵活(一个事件可以对应多个处理结果)。
异步事件通信模式
-
事件处理任务耗时长
如果消费者处理每个事件需要太长时间,同步事件就不是很合适。因为太慢的消费者会阻塞生产者,同时造成维护连接和上下文的成本增大,此时就需要采用异步事件来解耦生产者和消费者。此外就是在消费者需要保证每个事件仅处理一次的语义时,采用异步事件会带来便捷。 消费者处理事件的结果写入消息队列来投递给生产者,对于处理失败的事件将其移到一个特殊队列以方便追踪。通过采用异步事件提升了系统的鲁棒性。
-
负载均衡和动态伸缩
当生产者和消费者性能不匹配时,异步事件能够允许消费者按照自己的速率来消费事件而不必担心过载造成的一系列问题。因为异步事件通过消息队列对消息进行暂存和传递,消费者通过pull传递的方式能够完全控制事件的消费节奏。 同时消费者可以订阅消息队列的事件积压信息,在事件积压超过一定阈值的情况下,启动更多的消费者来并行消费来加速事件消费速度。
-
发布订阅
发布-订阅是一种异步事件通信模型,发送者将事件直接发布到某个主题。然后,任何感兴趣的一方都可以通过自身端点订阅该主题,并开始接收这些消息。在发布订阅模型中,消息代理充当一个重要的角色,通常发布者发布消息到消息代理,然后订阅者向该消息代理注册订阅,由消息代理来进行过滤。消息代理通常执行存储转发的功能将消息从发布者发送到订阅者。
-
事件分区
发送者在发送事件的时候,可以对事件进行指定分区,将不同部分的消息存储在不同消息代理的实例上,通过分区提升可靠性,并允许多个消费者并行消费而不担心重复消费。