微内核架构在大型前端系统中的应用

微内核架构在大型前端系统中的应用

时间:2020-03-23 14:59 作者:admin 点击:
阅读模式

由一群尽可能将数量最小化的软件程序组成,他们负责提供、实现一个操作系统所需要的各种机制和功能。这些最基础的机制,包括了底层地址空间管理,线程管理,与进程间通讯。微内核架构在使用时主要考虑两个方面『核心系统』和『插件模块』。应用逻辑被划分为独立的『核心系统』和『插件模块』,这样就提供了良好的可扩展性与灵活性,应用的新特性和基础业务逻辑也会被隔离。

一、核心系统

核心系统通常是一个可以独立运行的最小化模块,操作系统(Windows NT、Mac OS X)就是这么实现的。从商业应用的角度来看,核心系统为那些特定的场景、规则、复杂的条件判断提供了通用的业务逻辑,而插件模块则提供了更为具体的业务逻辑。可以增加或扩展核心系统以达到产生附加的业务逻辑的能力。

二、插件模块

插件模块通常是一个专业处理额外特性的独立组件。通常,插件模块之间是没有依赖的,当然你也可以创建一个依赖其他插件模块的插件,但不管怎么样,让插件模块之间可以彼此通讯又不产生依赖是一个很重要的问题。

三、获取插件模块并判断可用性

核心系统需要知道每个插件的可用性并且知道如何获取它们,一个通常的实现方式是使用一组注册表。注册表包括了每个插件的基本信息,包括名称、数据规范、远程访问协议(取决于插件模块如何和核心系统进行连接)以及其他自定义数据。比如百度网盘中用于上传文件的上传插件提供了插件名称、数据规范(输入、输出数据)、数据格式(json、xml),如果这个插件是通过异步进行加载的,那么还会有一个具体远程HTTP访问协议地址。

四、连接到核心系统

插件模块可以通过多种方式连接到核心系统,包括OSGI(open service gateway initiative)、消息机制、web服务以及点对点的绑定(对象实例化,既依赖注入)。使用何种方式主要取决于具体的应用场景和特殊需求(单机部署、分布式部署),微内核架构默认没有要求具体的实现方式,但是必须保证插件模块之间不能产生任何依赖。

五、通信规范

插件模块和核心系统之间的通信规范分为标准规范和自定义规范,自定义规范通常是指某个插件模块是由第三方服务开发的。这种情况下,就需要在自定义规范和标准规范之间提供一个Adapter,这样核心系统就不需要关心每个插件模块的具体实现。在设计标准规范之前制定一个版本策略很重要。

六、事件模式

核心系统提供了多种事件模式,主要包括常用的点对点模式、发布订阅模式。同时,事件的类型分为全局(系统级)事件、系统内部事件以及插件模块内部事件。由于点对点模式中发送者和接收者之间没有依赖关系并且一条消息只对应一个接收者,所以可以用作广播全局(系统级)事件,比如调起某个插件模块。而发布订阅模式中订阅者和发布者之间存在时间上的依赖性,可以用于系统内部事件和插件模块的内部事件。此外,核心模块也可以通过发布订阅模式向外发布某些属于业务基本操作规则的事件。

七、接口设计

当插件模块注册到核心系统之后,通过系统级事件可以调起具体的某插件模块。此时就需要核心模块提供属于基本操作规则的接口供插件模块使用,同样的,插件模块也必须按照通信规范提供运行入口(类似于java的Main方法)和数据规范(参数格式,返回的数据格式),以此保障插件模块可以在核心系统上正确运行。插件模块是独立于核心系统之外的,但是根据具体的需求(提供单纯的数据服务、处理系统数据和信息)可能会需要操作核心模块的系统服务做一些定制化功能,此时核心系统需要提供一个上下文对象(Context),且插件模块与外部进行交互只能通过此上下文对象。上下文对象提供了基础操作(调起其他插件模块、调起系统服务、获取系统信息)的API和事件。

远程访问协议核心系统调起插件模块时,可以通过插件声明的远程访问协议的HTTP地址,进行异步加载。

方案一:Manifest签名文件

在Manifest签名信息中放置插件模块的远程访问协议,比如上传插件模块的签名示例:

方案二:异步化接口 + import()

该方案是系统插件模块的远程访问协议不放置在插件模块的Manifest中,而是额外通过异步化接口请求得到远程访问协议。然后通过webpack提供的require.ensure()或esm的import()加载插件资源。