This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
主要对象及相关关系
在oak-general-business的对象中,有以下几个数据结构和应用本身相关联:
-
application
表示一个前端应用(其type属性表达了该应用是App/网站/公众号/小程序类型)
-
system
表示一个应用系统,一个系统可以有多个应用,共享系统逻辑和数据
-
platform
表示一个平台,一个平台可以部署多个应用系统。一般的互联网平台类应用可能会表达到平台层(同一个应用系统以不同的前端面向垂直领域客户)
-
domain
表示一个域名。一个域名只属于一个应用系统,同时一个应用可以显式指向所属应用系统的某个域名
应用启动过程
某个应用在初始化时,首先通过调用getApplication接口(src/aspects/application)去查询确定当前应用(Application)。其主要依据是type和domain,同时也传入应用的当前版本号。
应用的版本号
应用的版本号在打包发布时确定,编译器会自动将项目目录下package.json中的version号注入到打包后的文件中,以之作为应用的版本号。应用打包后,版本号就固定不会改变,除非用户升级。
如果在应用开发中需要取当前应用的版本号,可以编写一个oakGetPackageJsonVersion函数,直接返回任意字符串。oak在前端打包时,会自动将package.json中的version注入返回(参见src/utils/appVersion.ts)。
版本号命名规则
Oak框架的前后端代码不分开,因此可以很优雅的保持前后端版本的一致性。在开发过程中应遵循node的规定,以a.b.c(-extra)的格式来命名package.json中的version属性。其中:
- a表示大版本更新,数据结构和上一个版本必然不兼容
- b表示功能性更新,数据结构和上一个版本不保证兼容
- c表示bug修正,数据结构和上一个版本必须兼容
- extra一般用于一些特殊情况(比如线上紧急的临时版本)
线上应用升级策略
在实际线上应用的生命周期中,有以下两种情况需要处理:
- 尽管最新版本号中的a或者b已经变更过了,但应用(客户端)的历史版本仍然需要支持,不能强制客户升级;
- 某一个版本的应用(客户端)代码存在致命缺陷,需要强制客户升级。
第一种情况非常常见,由于Oak框架中绝大多数的前后端通信都是通过select/operate这样的接口来实现,因此要在数据结构已经升级了的情况下,仍然保证之前旧版本的应用可以使用。解决方案就是:在新的开发过程中,数据结构只增加属性,同时将(在新版本中)已经废除的属性通过trigger保持其数据的有效性(这类trigger应当加以特别的标识);同理,已经废弃的对象,也一样通过trigger保持其数据的有效性。
但很显然,这种做法随着版本的增多,会留存大量的垃圾数据(和少量的垃圾代码)。因此对于历史版本的支持也不能是无限期的。随着时间的流逝,历史最低支持的版本号被提升,此时比该版本号更低的版本所残留的数据结构(以及相应的trigger)就可以删除了。
这种策略较好的在历史版本的支持和代码的可维护性之间达到一个平衡。可以理解为,支持的历史版本有一个缓冲期,缓冲期结束后,系统可以发现并提示用户升级应用。
实现
在Application对象中,有三个属性:
- dangerousVersions:表示此Application强制升级的版本号
- warningVersions:表示此Application建议升级的版本号
- soaVersion:此应用的最新版本号
在component/application/upsert组件中,可以对之进行编辑。
在System/Platform对象中,有一个属性:
- oldestVersion:表示此System/Platform所支持的最低版本号
同样,在components/system/upsert组件中,也可以对之进行编辑

系统当前策略
- 当应用初始化时,后台会检查应用的当前版本号是否:
- 低于该System/Platform所支持的最低版本号
- 位于该Application的dangerousVersions中
如果满足其中之一,则会向应用抛出OakApplicationHasToUpgrade异常,此时框架根据自身的情况加以处理如下:
- Web/公众号直接刷新(不太可能出现)
- 小程序自动更新
- App提示用户去应用市场升级
- 如果当前版本号位于Application的warningVersions中,在初始化时,会返回此属性,暂时还未作进一步处理。
应用初始化后的情况
如果系统在应用使用的过程中产生了升级,则此时应用可能会处于一个“不安全”的状态中(逃脱了初始化过程中的安全检查)。为了性能考虑,目前并没有在每次网络请求的时候都对应用版本加以检查,而是用了另一种策略:当应用产生了不可识别的异常时,系统会去检查应用的当前version和该Application的soaVersion是否一致,若不一致,也会抛出OakApplicationHasToUpgrade异常使用户升级。
最新版本号
前面说过,由于Oak是前后台代码一体化的开发框架,因此后台(System/Platform)和前台(Application)可以共用开发线上的package.json中的version作为其最新版本号,但各版本之间可能会有细微的差别,这体现在版本号(a.b.c)的最后一位c上。因为如果系统更新了a或者b,其应用必然要重新编译发布。但是更新c也即修正bug,可能只需要发布某一个应用,或者只更新部署后台,导致不同的Application会有不同的最新版本号。因此,各Application的最新版本号soaVersion需要程序员在后台进行维护。

