我们都知道,Spring是提供了Event机制的,可以在发送一个事件,然后再基于这个事件做监听处理,这个流程好像和MQ有点像。都是典型的生产者-消费者的模式。
有很多事情,我们用这两者都能实现,主要是因为他们有很多共同点:
生产者消费者模式,这个就不用说了,通过这种方式可以实现解耦,即生产者只负责发送事件,消费者负责监听处理,二者之间的耦合相比于直接调用是比较弱的,中间的联系只是一个事件的定义而已。
一对多的模式,无论是Spring的事件还是MQ,都支持一发多收,一个发送者发送消息,其他的多个消费者一起监听这个消息做自己的业务逻辑。
异步处理,MQ是异步的这个没啥好说的了,大家都很容易理解。Spring Event默认是同步的,但是他也支持异步,能基于线程池实现一个异步的事件消费。
但是,他们之间还有很多不同:
事件/消息的持久化,MQ的事件是可以在磁盘上进行持久化存储的。但是Spring的事件机制的话,是没有持久化的,它是基于JVM内存的,一旦应用重启或者崩溃,未处理完的事件也会随时消失
削峰填谷,MQ天然提供了削峰填谷的能力,因为MQ自己会通过队列做存储,这个队列可以起到一个很好的缓冲作用。而Spring Event的事件没有一个缓冲。
失败重试,基于MQ,可以做失败重试,MQ自己会针对失败的消息进行重新投递,但是Spring的Event失败了没办法重试,需要自己进行异常的处理。
特殊功能,MQ针对消息提供了很多特殊的功能,比如延迟消息、顺序消息、事务消息等等,而Spring Event就是玩出花来,也就是自定义个线程池进行处理
但是Spring Event相比MQ也有好处,那就是简单,非常简单。
所以,在实际的业务中,如果是在自己的业务中需要做一些解耦或者一发多收的操作,比如订单创建后,异步创建一条订单流水。这种就可以基于Spring Event来做,并且利用线程池来进行异步并提升执行效率。
但是,需要考虑失败的问题,一旦处理失败了,需要有补偿机制,比如通过定时任务进行补偿处理。
而在多个系统之间交互的时候,就不能用Spring Event了,因为他没办法跨JVM进程,只能用MQ,并且如果要用到一些延迟消息、顺序消息、事务消息等就必须要用MQ,以及如果并发量比较大,也需要借助MQ进行削峰填谷。