更新 应用系统的设计与升级

Xu Chang 2025-02-05 18:10:49 +08:00
parent 699ed16724
commit 468c26f7cc
1 changed files with 77 additions and 0 deletions

@ -1,3 +1,5 @@
# 主要对象及相关关系
在oak-general-business的对象中有以下几个数据结构和应用本身相关联
* application
@ -11,3 +13,78 @@
* domain
表示一个域名。一个域名只属于一个应用系统,同时一个应用可以显式指向所属应用系统的某个域名
![对象关系](https://static-1252026042.cos.ap-shanghai.myqcloud.com/gitea.51mars.com/oak/general-entities1.png)
# 应用启动过程
某个应用在初始化时首先通过调用getApplication接口src/aspects/application去查询确定当前application。其主要依据是type和domain同时传入当前app的version。
## 应用的version如何确定
应用的Version在编译时确定编译器会自动将项目目录下package.json中的version号注入到编译文件中用之作为应用的版本号。
```tips
如果在应用开发中需要取当前应用的版本号可以编写一个oakGetPackageJsonVersion函数函数体直接返回任意字符串。oak在前端打包时会自动将package.json中的version注入返回参见src/utils/appVersion.ts
```
# 应用的版本号规定
Oak框架的前后端代码不分开因此可以很优雅的保持前后端版本的一致性。在应用开发中应遵循node的规定以a.b.c(-extra)的格式来命名package.json中的version。其中
* a表示大版本更新数据结构必然和上一个版本不兼容
* b表示版本更新数据结构和上一个版本不兼容
* c表示bug修正数据结构和上一个版本必须兼容
# 线上应用升级策略
在实际的线上应用中,有以下两种情况需要处理:
1. 尽管最新版本号中的a或者b已经变更过了但应用客户端的历史版本仍然需要支持不能强制客户升级
2. 某一个版本的应用(客户端)代码存在致命缺陷,需要强制客户升级。
第一种情况非常常见由于Oak框架中绝大多数的前后端通信都是通过select/operate这样的接口来实现因此要在数据结构已经升级了的情况下仍然保证之前旧版本的应用可以使用。解决方案就是在新的开发过程中数据结构只增加属性同时将在新版本中已经废除的属性通过trigger保持其数据的有效性这类trigger应当加以特别的标识同理已经废弃的对象也一样通过trigger保持其数据的有效性。
但很显然这种做法随着版本的增多会留存大量的垃圾数据和少量的垃圾代码。因此对于历史版本的支持也不能是无限期的。随着时间的流逝历史最低支持的版本号被提升此时比该版本号更低的版本所残留的数据结构以及相应的trigger就可以删除了。
这种策略较好的在历史版本的支持和代码的可维护性之间达到一个平衡。可以理解为,支持的历史版本有一个缓冲期,缓冲期结束后,系统可以发现并提示用户升级应用。
# 实现
在Application对象中有三个属性
* dangerousVersions表示此*application*强制升级的版本号
* warningVersions表示此*application*建议升级的版本号
* soaVersion此应用的最新版本
在*component/application/upsert*组件中,可以对之进行编辑。
![](https://static-1252026042.cos.ap-shanghai.myqcloud.com/gitea.51mars.com/oak/general-application-upsert1.png)
在System/Platform对象中有一个属性
* oldestVersion表示此*system/platform*所支持的最低版本号
同样,在*components/system/upsert*组件中,也可以对之进行编辑
![](https://static-1252026042.cos.ap-shanghai.myqcloud.com/gitea.51mars.com/oak/general-system-upsert1.png)
## 系统当前策略
1. 当应用初始化时,后台会检查应用的当前版本号是否:
* 低于该*system/platform*所支持的最低版本号
* 位于该*application*的*dangerousVersions*中
如果满足其中之一,则会向应用抛出*OakApplicationHasToUpgrade*异常,此时框架根据自身的情况加以处理如下:
* Web/公众号直接刷新(不太可能出现)
* 小程序自动更新
* App提示用户去应用市场升级
2. 如果当前版本号位于*application*的*warningVersions*中,在初始化时,会返回此属性,暂时还未作进一步处理。
## 应用初始化后的情况
如果系统在应用使用的过程中产生了升级则此时应用可能会处于一个“不安全”的状态中为了性能考虑目前没有在每次网络请求的时候都对版本加以检查如果因为版本不兼容的原因产生了异常系统会在异常出现后去检查应用的当前version和*application*的*soaVersion*是否一致,若不一致,也会抛出*OakApplicationHasToUpgrade*异常。
# 最新版本号
前面说过由于Oak是前后台代码一体化的开发框架因此后台System/Platform和前台Application可以共用开发线上的package.json中的version作为其最新版本号但各版本之间可能会有细微的差别这体现在版本号a.b.c的最后一位c上。因为如果系统更新了a或者b其应用必然要重新编译发布。但是更新c也即修正bug可能只需要发布某一个应用或者只更新部署后台因此*application*的最新版本号*soaVersion*需要程序员在后台进行维护。