Vantiq EDA开发规范

使用事件驱动架构进行开发,我们需要在事件的第一公民这个原则下,实现:

将事件作为一等数据保存。
定义事件驱动的范围,在整个系统内都使用事件驱动,还是在服务间使用事件驱动。
用事件定义服务间的接口。
定义事件的职责,确保每个事件的单一职责。
管理事件的订阅,实现对订阅者的授权和管理。
控制事件数据结构的更新,确保事件更新时订阅者的正常功能。
在上述原则当中,有一些是属于业务范围的定义,如定义事件驱动的范围,定义服务间的事件接口,定义事件的职责,控制事件数据结构的更新等。

而对于对事件的保存,事件的查看、搜索,事件订阅者的管理和授权,这些在Vantiq平台中都能够非常容易就实现。这在之前的文档中已经详细说明。

下面,我们就来看一下在Vantiq平台下,进行事件驱动架构下的系统的开发规范,通过这些规范,我们就能更好的遵守上述的事件驱动架构的原则,尽可能的实现整个系统的长期可维护性、扩展性。

Event Catalog与namespace的组织规范
在Vantiq中,权限是以namespace(命名空间)为基础进行的,不同的namespace之间想要相互访问,就需要通过access token授权。

为了实现事件的集中管理,我们需要在一个namespace中启用Catalog,并在其中定义所有的事件。

每个服务都对应一个namespace,该服务所在的namespace又通过access token授权,才能够访问Catalog中的事件,并且是通过本地队列访问的。不同的namespace之间的本地队列是完全隔离的,一个服务不能范围其他namespace的队列。

他们之间的关系如下图:

pronto-event-pub-sub-spec

通过这种结构,我们就能实现:

事件在Event Catalog所在的namespace中统一管理、查找。
在Event Catalog中统一授权和管理所有事件的所有订阅者、发布者队列。
每个服务都通过自己的namespace内的本地队列使用事件,不同的服务通过不同的namespace隔离自己的本地事件队列。
在Vantiq Pronto平台,事件是一个事件类型的定义,不是具体的事件消息。服务也不是直接使用事件,而是通过在这个事件上创建订阅者、发布者来访问事件。一般来说,这些订阅者、发布者都是本地队列(Topic),服务通过这个本地队列来发送、获取事件消息。

事件的定义规范
对于事件的定义,我们应该从发布者的角度来分析,确定一个事件是从哪个领域对象产生的。在Vantiq中,我们对事件名称的定义,是使用/domainFoo/eventAbc这样的命名规范来进行的,也是体现了这一原则。也就是使用层级的路径方式的名称,来反映这个事件是从哪个领域对象产生,并且产生的具体事件是什么。

这一命名原则,也体现了我们事件驱动架构的原则,也就是先进行业务领域的分析,在确定事件驱动的适用范围以后,再定义事件的接口。而且需要注意的是,事件是跟具体的服务无关的,我们不应该在事件中包含该领域所在的服务的信息。因为事件是领域对象产生的,是进行领域分析和业务抽象后,确定的业务规范,而服务是实现该领域时确定的,是在定义好领域之后进行的。所以,我们应该让我们的事件定义不依赖具体的服务,而只是体现我们的业务。

事件的单一职责规范
在EDA的规范中,我们要求事件的单一职责,这更多的是从业务上的定义。具体到实践中来说,我们需要从发布者的角度来分析,一个领域对象有哪些业务操作,其中又有哪些操作会对其他系统产生影响。

然后,我们对每个领域对象产生的每种业务,定义一个事件,也就是/domainFoo/eventAbc, /domainFoo/eventEfg等。

事件-发布者队列-服务关系规范
根据上面的事件的规范,事件的定义是根据领域对象产生的一个个操作来定义。该事件的发布,是通过发布队列来进行,而这个发布队列是由服务来使用,由服务中的某个领域对象类,其中的某个方法发布事件消息到这个发布队列。

根据事件的单一职责原则,发布队列也应该与事件一一对应,进而服务内领域内的方法也要与发布队列对应。所以,我们需要在开发服务实现领域对象的过程中,也遵守面向对象的单一职责原则,并结合对应的事件的单一职责,以保证他们之间的相互关系是清晰、明确的。

根据事件驱动架构的规范,事件是由某个领域对象产生的,而一个领域对象,不应该在多个服务内。如果一个领域对象的一部分功能在一个服务内,另一个部分功能在另一个服务内,那就说明该领域对象实际上应该是2个领域。所以,事件的发布者,应该只有一个,而不是多个。

而发布者队列的命名,应该包含发布该事件的服务,以及领域等信息,就像上面图中的/serviceA/domainAbc/eventAA。

事件-订阅者队列-服务关系规范
事件的订阅,是由于系统中的其他服务需要对这个事件作出响应,以完成一定的业务操作,或进行数据分析。所以,事件的订阅者,很可能会有多个。所以事件的订阅者队列的名字,需要体现订阅者所在的服务和领域等信息,这样就能从订阅者队列直观的提现该事件的使用者。

所以,对订阅者队列的命名,就是/service1/DomainFoo/eventAA,/service2/DomainBar/eventAA这样。也就是该订阅者队列是用于某个服务(service1)中的某个领域(DomainFoo),最后再加上事件的名。加上事件名后,我们在订阅者的服务中就能够通过队列名来区分事件。

猜你喜欢

转载自blog.csdn.net/weixin_44264245/article/details/86080381
今日推荐