进程内消息机制的价值

进程内消息机制的价值

一,前言

首先声明一点,这篇文章不会去深入阐述什么叫消息机制,消息机制实现的原理。因为这些东西,网上一大把的资料,区别只是内容是否精炼,概括是否准确等。

这篇文章只讨论在JVM进程内使用消息机制,有怎样的价值,优劣势在哪里?

二,什么是消息机制

通常,人们都会将观察者模式,事件驱动,消息机制三个词语放在同一位置。

这里我简单谈一下我的认识:
消息机制中消息分发方式分为push与pull,而push往往采用的是订阅模式,而订阅模式一般是基于观察者模式实现的。
消息机制往往作为事件驱动的主要信息交互方式,此模式下,消息作为事件驱动模型中的事件信号。

三,进程内消息机制的实现

进程内,表示在同一JVM进程中。实现的方式很多:

  • 自主依据observer模式,进行设计与编码。可以按照业务需求进行并发,消息堆积等扩展
  • 依赖于开发框架,如Spring的ApplicationEvent机制,通过对应注解,及属性(如condition等)进行应用
  • 引入第三方工具包,如Guava的EventBus机制,实现消息注册及使用

四,疑问事件的由来

前不久,门店域下有一个模块需要进行大的迭代,这个部分由我负责。
我发现代码中出现一些地方,采用了Spring的ApplicationEvent机制。我当然是理解这个使用,但是这次我有了一个疑问,为什么要使用这个东东。毕竟使用了这个,会降低代码可读性(毕竟你需要去寻找消息的发布者,从而找到调用链的上游)等。

五,进程内消息机制的好处

在一段时间思考后,并与师兄进行了交流,总结出以下三点好处:

  • 消息内部二次分发:系统从外部获取的消息,大多是通过topic获取的,粒度过大。所以在进程内可以通过内部消息机制,按照需要进行消息拆分,从而消息的消费更加明确,侧面降低系统复杂度。
  • 重复消费:进程内消息机制,往往都是简单地基于observer模式实现,所以可以多个消费者同时消费同一消息。这在业务上是很有必要的,如门店域的缺货出信号,往往会触发包括盘点,库调等多个业务动作。
  • 调用解耦:解耦的好处数不胜数,如有利于事件驱动等设计,有利于调用方代码调整等。

这里再扩展说明一下第一点好处

为什么不利用消息中间件的Tag功能

首先不是所有的MQ都支持Tag功能。
其次在实际业务开发中,往往不会对tag提出规范要求,因为过细的粒度要求,反而会带来协调开发的复杂度提升。这就涉及到对多人协同开发中协同效率(如交流效率)的考虑。举个例子,协同开发时,如果提出一个新的tag,则需要与消息生产者的开发者进行沟通,确定新的tag是否可用,多久上线,还有联调等。所以,除了部分稳定,且有着严格规范的应用,很多系统并不会提出tag的要求。

内部消息机制如何实现拆分

首先,如果采用了spring的ApplicationEvent机制,则可以利用其消费的condition字段(这需要了解Spring EL)。
其次,如果采用了Guava这样的第三方工具,则首先了解其是否具有类似功能。如果没有,则可以在第三方工具外包一层消息分发器,根据具体消息模型进行分发(如根据消息内某字段,进行分发)。
最后,如果是自定义实现进程内消息机制,则更简单了。第二条的两个实现思路,按照需求,挑一个就行了。

六,进程内消息机制的缺点

就如同外部消息中间件的使用,由于消息生产者与消息消费者的解耦,难以根据其中一方,来寻找到另外一方。

这里给两个思路,来解决这个问题。这同时也是所有消息机制的解决方案,也就是包括消息中间件:

  • 规范开发:站在工程角度,从源头解决。良好的开发规范,将帮助所有的相关开发者,迅速定位到对应位置。如在项目下建立一个listener的包,所有的消费者都在此,另外内部消息机制的生产者也可以统一在该listener包的特定包(如dispatcher)下。当然,如果当前应用较为复杂,接入的消息也很多,也可以按照最小原则,只在对应层次的包下建立相关包。这取决于你们应用的开发规范风格(这里推荐一下,可以参照《阿里Java开发手册》)。
  • 根据特定接口或模型进行定位:这需要对所使用的进程内消息机制实现有一定的了解。如项目采用Spring的ApplicationEvent机制实现内部消息机制,则可以通过MessageListernerConcurrently等接口来定位消息生产者,通过@EventListener来定位消息消费者。另外,还可以根据某类消息所采用的消息模型,进行搜索定位。

7,总结

我相信没人会问,为什么不借助消息中间件来实现进程内消息机制吧。毕竟那样做太重了,无论是增加了调用链节点,还是降低稳定性等。

平日里,我们需要多多想想为什么,并保持这种好奇心。有些问题以前认为没问题,往往是因为以前的认知不足,看得比较片面。《论语》中的”吾日三省吾身“,是我非常喜欢的一句名言。

愿与诸君共进步。

你可能感兴趣的:(实现,java)