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

news/2025/9/26 11:24:47/文章来源:https://www.cnblogs.com/zhennann/p/19113145

多实例/多租户

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

VonaJS 支持以下几种多实例/多租户模式:

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

实例配置

1. 测试环境、开发环境

在测试环境和开发环境中,系统默认提供了一个缺省实例。同时提供了两个测试实例,用于演示如何使用共享模式独立模式

src/backend/config/config/config.test.ts

src/backend/config/config/config.dev.ts

// instances
config.instances = [{ name: '', password: '', title: '', config: {} },{ name: 'shareTest', password: '', title: '' },{ name: 'isolateTest', password: '', title: '', id: 1000, isolate: true, isolateClient: 'isolateTest' },
];
  • 实例清单
名称 说明
empty 缺省实例
shareTest 用于演示共享模式,具体而言,shareTestempty共享同一个数据库
isolateTest 用于演示独立模式,具体而言,isolateTest使用独立的数据库
  • 实例属性
名称 说明
name 实例名
password 实例中用户admin的初始密码,默认是123456
title 网站标题
config 实例的配置信息
id 当使用独立模式时,必须明确指定唯一的实例Id
isolate 是否使用独立模式,默认为共享模式
isolateClient 当使用独立模式时,必须明确指定数据源

2. 生产环境

在生产环境,需要自行配置实例信息

src/backend/config/config/config.prod.ts

config.instances = [{ name: '', password: '', title: '', config: {} },{ name: 'vona', password: '', title: '', config: {} },
];

如何添加新实例

下面以实例shareTest为例,演示如何添加新实例:

1. 添加类型定义

src/backend/config/config/config.ts

declare module 'vona' {export interface IInstanceRecord {shareTest: never;}
}
  • 采用接口合并机制添加新实例的类型定义

2. 增加实例配置

在需要的 config 文件中添加实例配置,比如在测试环境配置新实例:

src/backend/config/config/config.test.ts

// instances
config.instances = [{ name: 'shareTest', password: '', title: '' },
];
  • 对于独立模式,还需要配置数据源,此处从略

获取当前实例名的规则

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

1. 模块配置

多实例是由模块 a-instance 提供的核心能力,可以在 App config 中修改模块的配置:

src/backend/config/config/config.prod.ts

// modules
config.modules = {'a-instance': {getInstanceName: undefined,headerField: 'x-vona-instance-name',queryField: 'x-vona-instance-name',},
};
名称 说明
getInstanceName 提供自定义函数,用于获取当前实例名
headerField 从request header中获取当前实例名,header key默认为x-vona-instance-name
queryField 从request query中获取当前实例名,query key默认为x-vona-instance-name

2. 规则次序

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

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

3. 如何从域名中解析实例名

比如,域名为https://cabloy.com,那么对应的实例名是cabloy。可以通过配置SERVER_SUBDOMAINOFFSET来修改计算规则

env/.env

# server
SERVER_SUBDOMAINOFFSET = 1
  • SERVER_SUBDOMAINOFFSET = 1时,域名与实例名对应关系如下:
域名 实例名
cabloy.com cabloy
store.cabloy.com cabloy.store
  • SERVER_SUBDOMAINOFFSET = 2时,域名与实例名对应关系如下:
域名 实例名
cabloy.com 空字符串
store.cabloy.com store

使用多实例

1. 访问当前实例信息

// 当前实例名
const name = this.ctx.instanceName;
// 当前实例对象
const instance = this.ctx.instance;
// 当前实例Id
const iid = this.ctx.instance.id;

2. 使用Model操作数据库

由于多实例的数据是相互隔离的,因此在操作数据库时,需要指定实例Id。VonaJS 提供了非常强大的Model对象,从而可以透明的处理多实例

// create
await this.scope.model.student.insert({ name: 'Tom' });
// select
await this.scope.model.student.select();
// get
await this.scope.model.student.get({ id: 1 });
// update
await this.scope.model.student.update({ id: 1, name: 'Jimmy' });
// delete
await this.scope.model.student.delete({ id: 1 });

当我们使用 Model student操作数据时,系统会自动设置实例Id

3. 使用Query Builder操作数据库

如果使用builder()方法操作数据库,就需要自行添加实例Id

await this.scope.model.student.builder().where({iid: this.ctx.instance.id,name: 'Tom',
});

如果使用builderSelect()方法操作数据库,系统会自动添加实例Id

await this.scope.model.student.builderSelect().where({name: 'Tom',
});

4. 使用原生Sql操作数据库

如果使用原生Sql操作数据库,就需要自行添加实例Id

await this.scope.model.student.query('select * from demoStudent where iid=?',[this.ctx.instance.id],
);
await this.scope.model.student.queryOne('select * from demoStudent where iid=? and id=?',[this.ctx.instance.id, 1],
);

Vona ORM已开源:https://github.com/vonajs/vona

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/918178.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录一下第一次为Dify贡献插件的经历

最近Dify上线了一个新功能——知识管道(Knowledge Pipeline)。知识管道可以像乐高一样编排你的信息,以数据源(Data Source)作为起始节点,以知识库节点作为结束节点。其一般步骤为:从数据源导入文档 -> 使用抽…

免费自媒体网站有创意的设计公司名称

1. 使用 systemd 服务设置开机自启动 假设已经有一个可执行的python程序,然后用一个sh脚本去启动python程序,正常情况使用挂起的方式nohup启动,日志输出到指定文件: sudo touch run.sh sudo chmod 777 run.shsh文件内容如下&…

物联网字节校验常用方法

① 校验和(Checksum)原理:把所有字节加起来(可能取低 8 位 / 16 位),作为校验值。 优点:实现极其简单,计算快,资源消耗小。 缺点:检测能力有限(部分错误无法发现,例如两个字节互换位置)。 应用场景:早期…

实用指南:RabbitMQ 核心组件详解与持久化日志队列实现方案

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

实用指南:【C语言】统计二进制中1的个数:三种方法的比较与分析

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Visual Prompt Builder-AI 提示词可视化工具 - 详解

Visual Prompt Builder-AI 提示词可视化工具 - 详解2025-09-26 11:18 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; disp…

STM32H743-ARM例程2-UART命令控制LED - 实践

STM32H743-ARM例程2-UART命令控制LED - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &quo…

大连做网站哪家便宜深圳市龙华区房价

作者:激越王预估稿费:400RMB投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿你是否听说过xml注入攻击呢,或者对它只知其一不知其二呢?现在让我们从xml相关基础知识开始,一步步了解xml攻…

建设科技处网站wordpress wap

目录 说明批量zip2pdf批量zip2pdf下载SS号重命名源代码SS号重命名源代码下载附录,水文年鉴 说明 1、zip2pdf是一个开源软件,支持自动化解压压缩包成PDG,PDG合成PDF,笔者在其基础上做了部分修改,支持批量转换。 2、秒…

提供做网站公司wordpress开启多站点

我们组件中 会有很多通用的信息和方法 那么 首先 我们看通用事件 通用事件中 最常用的就是我们的点击事件 比如说 我们之前常写的 组件.onClick(()>{//事件逻辑 })但是 我们之前 都没有用它接参数 我们可以这样 Button("跳转").onClick((ewat: ClickEvent)>…

网站建设html代码邢台信息港二手房出售

1.简介 双指针技巧是一种常见的算法解题方法,通过使用两个指针在数据结构上同时移动,可以解决多种问题。这种技巧通常适用于数组、字符串和链表等数据结构,下面我将详细介绍双指针技巧的特点和应用场景: 特点: 快慢…

完整教程:Zookeeper与Kafka:分布式系统中的协调与消息队列

完整教程:Zookeeper与Kafka:分布式系统中的协调与消息队列pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Conso…

vite-vue3 项目优化首屏加载速度

A嵌入B,B加载速度太慢了,需要4s+,需优化: B系统技术栈: vue3 + vite 优化结果如下,上下对比还有有差距的:一、先处理: 首屏加载的文件——先优化文件大 step1: 安装可视化插件 rollup-plugin-visualizer; vi…

深入解析:小九源码-springboot050-基于spring boot的苏蔚家校互联管理系统

深入解析:小九源码-springboot050-基于spring boot的苏蔚家校互联管理系统pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-famil…

建设自己公司的网站公司网站本地如何弄

目录 前言 一、Mybatis-Plus 开启日志的方式 二、测试 三、日志分析 章末 前言 小伙伴们大家好,相信大家平时在处理问题时都有各自的方式,最常用以及最好用的感觉还是断点调试,但是涉及到操作数据库的执行时,默认的话在控制台…

12_TCP和UDP实现服务端和客户端的通信

一、TCP实现多进程通信 server_process.c 服务端代码: #define _XOPEN_SOURCE #include <stdio.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <stdlib.h…

各种软件的官方文档和安装包下载地址记录

各种软件的官方文档和安装包下载地址记录组件 官网文档 官方下载地址Elasticsearch https://www.elastic.co/guide/en/elasticsearch/reference/index.html https://www.elastic.co/downloads/past-releases?product=…

基于导频的OFDM系统的信道估计(使用LS估计算法)

在OFDM系统中,信道估计是关键的一步,因为它直接影响到信号的解调和系统性能。最小二乘(LS)估计算法是一种常用的信道估计方法,它通过已知的导频符号来估计信道响应。 基于MATLAB的OFDM系统信道估计的实现,使用LS…

Day22super详解

super是一个关键字,用于子类访问父类的属性方法与构造器,与this一样在调用构造器的时候两者由于java语法的强制要求,都需要放在第一行,所以当用this取调用子类的构造器是,无法在用super去调用父类的构造器,否则会…

台州网站搜索排名巴中建设网站

千视携NDI 6技术闪耀2024 CCBN展会&#xff0c;呈现轻量化媒体解决方案 2024年4月24日至26日&#xff0c;北京首钢会展中心将举办第三十届中国国际广播电视网络技术展览会&#xff08;CCBN2024&#xff09;。这是中国广播电视行业的一项重要盛会&#xff0c;将有国内外超600家…