找回密码
 立即注册
首页 业界区 业界 VonaJS多租户同时支持共享模式和独立模式 ...

VonaJS多租户同时支持共享模式和独立模式

寇油 7 天前
多实例/多租户

VonaJS 通过多实例的概念来支持多租户 SAAS 系统的开发。只需启动一个后端服务,即可支持多个实例同时运行
VonaJS 支持以下几种多实例/多租户模式:

  • 共享模式:多个实例共享同一个数据库,通过实例Id字段隔离多实例之间的数据
  • 独立模式:每个实例都使用独立的数据库,从而满足大数据量的业务需求
  • 混合模式:在一个系统中同时支持共享模式和独立模式,从而可以精确指定某个实例使用共享数据库还是独立数据库
实例配置

1. 测试环境、开发环境

在测试环境和开发环境中,系统默认提供了一个缺省实例。同时提供了两个测试实例,用于演示如何使用共享模式和独立模式:
src/backend/config/config/config.test.ts
src/backend/config/config/config.dev.ts
  1. // instances
  2. config.instances = [
  3.   { name: '', password: '', title: '', config: {} },
  4.   { name: 'shareTest', password: '', title: '' },
  5.   { name: 'isolateTest', password: '', title: '', id: 1000, isolate: true, isolateClient: 'isolateTest' },
  6. ];
复制代码

  • 实例清单
名称说明empty缺省实例shareTest用于演示共享模式,具体而言,shareTest与empty共享同一个数据库isolateTest用于演示独立模式,具体而言,isolateTest使用独立的数据库

  • 实例属性
名称说明name实例名password实例中用户admin的初始密码,默认是123456title网站标题config实例的配置信息id当使用独立模式时,必须明确指定唯一的实例Idisolate是否使用独立模式,默认为共享模式isolateClient当使用独立模式时,必须明确指定数据源2. 生产环境

在生产环境,需要自行配置实例信息
src/backend/config/config/config.prod.ts
  1. config.instances = [
  2.   { name: '', password: '', title: '', config: {} },
  3.   { name: 'vona', password: '', title: '', config: {} },
  4. ];
复制代码
如何添加新实例

下面以实例shareTest为例,演示如何添加新实例:
1. 添加类型定义

src/backend/config/config/config.ts
  1. declare module 'vona' {
  2.   export interface IInstanceRecord {
  3.     shareTest: never;
  4.   }
  5. }
复制代码

  • 采用接口合并机制添加新实例的类型定义
2. 增加实例配置

在需要的 config 文件中添加实例配置,比如在测试环境配置新实例:
src/backend/config/config/config.test.ts
  1. // instances
  2. config.instances = [
  3.   { name: 'shareTest', password: '', title: '' },
  4. ];
复制代码

  • 对于独立模式,还需要配置数据源,此处从略
获取当前实例名的规则

当用户访问后端 Api 时,后端会自动根据规则获取当前实例名,然后根据实例名获取实例信息
1. 模块配置

多实例是由模块 a-instance 提供的核心能力,可以在 App config 中修改模块的配置:
src/backend/config/config/config.prod.ts
  1. // modules
  2. config.modules = {
  3.   'a-instance': {
  4.     getInstanceName: undefined,
  5.     headerField: 'x-vona-instance-name',
  6.     queryField: 'x-vona-instance-name',
  7.   },
  8. };
复制代码
名称说明getInstanceName提供自定义函数,用于获取当前实例名headerField从request header中获取当前实例名,header key默认为x-vona-instance-namequeryField从request query中获取当前实例名,query key默认为x-vona-instance-name2. 规则次序

系统按以下次序,依次判断当前实例名,当获取到实例名时则停止判断流程

  • 如果提供了getInstanceName,则调用此函数
  • 如果queryField不为空,则从 request query 中获取
  • 如果headerField不为空,则从 request header 中获取
  • 从域名中解析实例名
3. 如何从域名中解析实例名

比如,域名为https://cabloy.com,那么对应的实例名是cabloy。可以通过配置SERVER_SUBDOMAINOFFSET来修改计算规则
env/.env
  1. # server
  2. SERVER_SUBDOMAINOFFSET = 1
复制代码

  • 当SERVER_SUBDOMAINOFFSET = 1时,域名与实例名对应关系如下:
域名实例名cabloy.comcabloystore.cabloy.comcabloy.store

  • 当SERVER_SUBDOMAINOFFSET = 2时,域名与实例名对应关系如下:
域名实例名cabloy.com空字符串store.cabloy.comstore使用多实例

1. 访问当前实例信息
  1. // 当前实例名
  2. const name = this.ctx.instanceName;
  3. // 当前实例对象
  4. const instance = this.ctx.instance;
  5. // 当前实例Id
  6. const iid = this.ctx.instance.id;
复制代码
2. 使用Model操作数据库

由于多实例的数据是相互隔离的,因此在操作数据库时,需要指定实例Id。VonaJS 提供了非常强大的Model对象,从而可以透明的处理多实例
  1. // create
  2. await this.scope.model.student.insert({ name: 'Tom' });
  3. // select
  4. await this.scope.model.student.select();
  5. // get
  6. await this.scope.model.student.get({ id: 1 });
  7. // update
  8. await this.scope.model.student.update({ id: 1, name: 'Jimmy' });
  9. // delete
  10. await this.scope.model.student.delete({ id: 1 });
复制代码
当我们使用 Model student操作数据时,系统会自动设置实例Id
3. 使用Query Builder操作数据库

如果使用builder()方法操作数据库,就需要自行添加实例Id
  1. await this.scope.model.student.builder().where({
  2.   iid: this.ctx.instance.id,
  3.   name: 'Tom',
  4. });
复制代码
如果使用builderSelect()方法操作数据库,系统会自动添加实例Id
  1. await this.scope.model.student.builderSelect().where({
  2.   name: 'Tom',
  3. });
复制代码
4. 使用原生Sql操作数据库

如果使用原生Sql操作数据库,就需要自行添加实例Id
  1. await this.scope.model.student.query(
  2.   'select * from demoStudent where iid=?',
  3.   [this.ctx.instance.id],
  4. );
  5. await this.scope.model.student.queryOne(
  6.   'select * from demoStudent where iid=? and id=?',
  7.   [this.ctx.instance.id, 1],
  8. );
复制代码
Vona ORM已开源:https://github.com/vonajs/vona

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册