日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

SaaS多租戶架構數據源動態切換解決方案

來源: 責編: 時間:2024-03-28 17:51:58 182觀看
導讀概述隨著云計算和SaaS(Software as a Service)模型的興起,多租戶系統成為了構建靈活、高效應用的重要架構。在構建多租戶SaaS平臺時,數據庫方案的選擇直接關系到數據隔離、性能和可擴展性。在SaaS平臺項目中,根據前端不同

概述

隨著云計算和SaaS(Software as a Service)模型的興起,多租戶系統成為了構建靈活、高效應用的重要架構。在構建多租戶SaaS平臺時,數據庫方案的選擇直接關系到數據隔離、性能和可擴展性。L6K28資訊網——每日最新資訊28at.com

在SaaS平臺項目中,根據前端不同的域名查詢不同的數據庫,通常涉及到多租戶架構的實現。在這種架構中,一個應用實例可以服務多個客戶(租戶)【數據庫】,每個租戶的數據需要隔離存儲。實現這一目標的關鍵技術之一就是動態切換數據庫連接。L6K28資訊網——每日最新資訊28at.com

設計多租戶數據模型

在數據庫設計階段,你需要決定數據隔離的級別。通常有以下幾種隔離級別:L6K28資訊網——每日最新資訊28at.com

  • 獨立數據庫:每個租戶擁有一個獨立的數據庫實例。
  • 共享數據庫,獨立Schema:所有租戶共享同一個數據庫,但每個租戶有獨立的Schema。
  • 共享數據庫,共享Schema,共享數據表:所有租戶共享數據庫、Schema和數據表,但通過租戶ID字段進行數據隔離。

共享數據庫,獨立Schema

"共享數據庫,獨立Schema" 是一種在SaaS平臺中實現多租戶架構的策略,它在數據庫層面上提供了一種折中的數據隔離方法。L6K28資訊網——每日最新資訊28at.com

Oracle數據庫:在Oracle中一個數據庫可以具有多個用戶,那么一個用戶一般對應一個Schema,表都是建立在Schema中的,(可以簡單的理解:在Oracle中一個用戶一套數據庫表)L6K28資訊網——每日最新資訊28at.com

圖片圖片L6K28資訊網——每日最新資訊28at.com

在 MySQL 中,Schema 和 Database 可以認為是相同的概念。在 SQL 語句中,CREATE DATABASE 和 CREATE SCHEMA 基本上是等效的。所以,當你創建一個數據庫時,你也在事實上創建了一個模式。模式是一個邏輯上的容器,用于組織和管理數據庫對象,如表、視圖、存儲過程等。在 MySQL 中,模式和數據庫可以互換使用。L6K28資訊網——每日最新資訊28at.com

共享數據庫

在這種模式下,所有的租戶(即SaaS平臺的客戶)共享同一個物理數據庫服務器或數據庫實例。這意味著,盡管每個租戶都有自己的數據,但這些數據都存儲在同一個數據庫文件或數據庫集群中。這樣做的好處是可以減少硬件資源和維護成本,因為不需要為每個租戶單獨設置和維護數據庫實例。L6K28資訊網——每日最新資訊28at.com

獨立Schema

盡管數據庫是共享的,但每個租戶都有自己獨立的Schema。Schema是數據庫中的一種邏輯分組,它包含了一系列的數據庫對象,如表、視圖、索引、存儲過程等。在這個模式下,每個租戶的數據都存儲在自己的Schema中,這樣可以保證租戶之間的數據邏輯上是隔離的。L6K28資訊網——每日最新資訊28at.com

例如,假設有兩個租戶A和B,他們共享同一個數據庫"SaaSDB"。在"SaaSDB"中,可以分別為租戶A和租戶B創建兩個Schema(數據庫),分別是"SchemaA"和"SchemaB"。租戶A的所有數據都存儲在"SchemaA"中,而租戶B的數據存儲在"SchemaB"中。L6K28資訊網——每日最新資訊28at.com

優缺點

優點
  1. 資源利用率高:由于所有租戶共享同一個數據庫,硬件資源和數據庫維護成本較低。
  2. 易于管理:數據庫管理員只需要管理一個數據庫實例,簡化了維護和升級的工作。
  3. 隔離性:每個租戶的數據存儲在獨立的Schema中,邏輯上實現了數據隔離,減少了數據交叉污染的風險。
缺點
  1. 隔離性不如獨立數據庫:雖然Schema提供了一定程度的隔離,但如果Schema之間存在依賴關系或需要進行復雜的數據操作,隔離性可能不如完全獨立的數據庫。
  2. 性能問題:如果租戶數量增多,可能會導致數據庫性能問題,因為所有租戶都在競爭同一個數據庫資源。

總體來說,"共享數據庫,獨立Schema" 的模式在SaaS平臺中是一種常見的多租戶數據隔離策略,它在資源利用率和數據隔離性之間取得了平衡。開發者需要根據具體的業務需求和預期的租戶規模來決定是否采用這種模式。L6K28資訊網——每日最新資訊28at.com

SaaS多租戶架構數據庫設計

重點:在 SQL 語句中,CREATE DATABASE 和 CREATE SCHEMA 基本上是等效的。所以,當你創建一個SCHEMA時,就是在一個RDS實例下創建一個數據庫DATABASE。L6K28資訊網——每日最新資訊28at.com

圖片圖片L6K28資訊網——每日最新資訊28at.com

以newtrain.tinywan.com、hz_newtrain.tinywan.com、bj_newtrain.tinywan.com三個域名為例,每個域名對應一個租戶平臺站點,分別對應各自的數據源數據庫newtrain.tinywan.com、hangzhou.tinywan.com、beijing.tinywan.com。L6K28資訊網——每日最新資訊28at.com

實施方案

域名解析與路由

  • 在DNS系統中為每個域名配置A記錄,指向SaaS平臺的服務器
  • 在服務器上部署Web應用,并根據請求的Host頭部信息,確定租戶身份。

數據源配置

  • 在應用程序的配置文件中,定義每個租戶的數據源配置,包括數據庫URL、用戶名和密碼
  • 可以使用環境變量或配置中心來動態加載這些配置。

動態數據源切換

根據請求的域名或其他標識符,動態確定使用哪個數據庫連接。這通常通過中間件、攔截器或全局函數來實現。L6K28資訊網——每日最新資訊28at.com

示例:使用PHP實現域名路由中間件L6K28資訊網——每日最新資訊28at.com

<?php/** * @desc 域名路由中間件 * @author Tinywan(ShaoBo Wan) * @date 2024/11/20 18:14 */declare(strict_types=1);namespace app/middleware;use app/common/model/SaasModel;use Webman/Http/Request;use Webman/Http/Response;use Webman/MiddlewareInterface;class ConnectionMiddleware implements MiddlewareInterface{    /**     * @param Request $request     * @param callable $handler     * @return Response     */    public function process(Request $request, callable $handler): Response    {        $domain = $request->header()['x-site-domain']?? 'https://newtrain.tinywan.com';        $platform = SaasModel::where('domain', $domain)->field('id, domain, website')->findOrEmpty();        if (!$platform->isEmpty()) {            $request->website = $platform['website'];        }        return $handler($request);    }}

以上根據前端請求的域名標識符x-site-domain,動態確定使用哪個數據庫連接,通過中間件動態賦予全局請求對象$request->website,后續就可以使用。L6K28資訊網——每日最新資訊28at.com

項目應用

項目架構

項目使用超高性能可擴展PHP框架webman。webman是一款基于workerman開發的高性能HTTP服務框架。webman用于替代傳統的php-fpm架構,提供超高性能可擴展的HTTP服務。你可以用webman開發網站,也可以開發HTTP接口或者微服務。L6K28資訊網——每日最新資訊28at.com

數據庫連接使用ThinkORM。ThinkORM是一個基于PHP和PDO的數據庫中間層和ORM類庫,之前一直作為ThinkPHP5.*系列的內置ORM類,以優異的功能和突出的性能著稱,現已經支持獨立使用,并作了升級改進,提供了更優秀的性能和開發體驗,最新版本要求PHP7.1+。L6K28資訊網——每日最新資訊28at.com

數據庫連接中間

示例:域名路由中間件L6K28資訊網——每日最新資訊28at.com

<?php/** * @desc 域名路由中間件 * @author Tinywan(ShaoBo Wan) * @date 2024/11/20 18:14 */declare(strict_types=1);namespace app/middleware;use app/common/model/SaasModel;use Webman/Http/Request;use Webman/Http/Response;use Webman/MiddlewareInterface;class ConnectionMiddleware implements MiddlewareInterface{    /**     * @param Request $request     * @param callable $handler     * @return Response     */    public function process(Request $request, callable $handler): Response    {        $domain = $request->header()['x-site-domain']?? 'https://newtrain.tinywan.com';        $platform = SaasModel::where('domain', $domain)->field('id, domain, website')->findOrEmpty();        if (!$platform->isEmpty()) {            $request->website = $platform['website'];        }        return $handler($request);    }}

數據庫配置

ThinkORM配置文件:config/thinkorm.phpL6K28資訊網——每日最新資訊28at.com

<?php/** * @desc ThinkORM配置文件 * @author Tinywan(ShaoBo Wan) * @date 2024/11/14 15:14 */declare(strict_types=1);return [    'default' => 'train',    'connections' => [        'train' => [            'type' => 'mysql',            'hostname' => '127.0.0.1',            'database' => 'newtrain.tinywan.com',            'username' => 'root',            'password' => '123456'        ],        'hangzhou' => [            'type' => 'mysql',            'hostname' => '127.0.0.1',            'database' => 'hangzhou.tinywan.com',            'username' => 'root',            'password' => '123456'        ],        'beijing' => [            'type' => 'mysql',            'hostname' => '127.0.0.1',            'database' => 'beijing.tinywan.com',            'username' => 'root',            'password' => '123456'        ]    ],];

Model模型使用

BaseModel.php 基礎模型L6K28資訊網——每日最新資訊28at.com

<?php/** * @desc 基礎模型 * @author Tinywan(ShaoBo Wan) * @date 2024/11/2 15:09 */declare(strict_types=1);namespace app/common/model;use think/Model;class BaseModel extends Model{    /**     * 設置當前模型的數據庫連接     * @var string     */    protected $connection;    /**     * BaseModel constructor.     * @param array $data     */    public function __construct(array $data = [])    {        $this->connection = /request()->website ?? 'train';        parent::__construct($data);    }}

CityModel.php 公共模型,對應數據庫表名common_city。L6K28資訊網——每日最新資訊28at.com

<?php/** * @desc 市模型 * @author Tinywan(ShaoBo Wan) * @date 2024/12/13 14:59 */declare(strict_types=1);namespace app/common/model;use think/Model;class CityModel extends Model{    /** 數據庫配置 */    protected $connection = 'train';    /** 設置當前模型對應的完整數據表名稱 */    protected $table = 'common_city';}

公共模型CityModel類里面定義了connection屬性,則該模型操作的時候會自動按照給定的數據庫配置進行連接,而不是配置文件中設置的默認連接信息.L6K28資訊網——每日最新資訊28at.com

業務 MeetingModel.php 會議模型類。對應數據庫表名resty_meetingL6K28資訊網——每日最新資訊28at.com

<?php/** * @desc 會議模型類 * @author Tinywan(ShaoBo Wan) * @date 2024/11/17 11:55 */declare(strict_types=1);namespace app/common/model;class MeetingModel extends BaseModel{    /** 設置當前模型對應的完整數據表名稱 */    protected $table = 'resty_meeting';}

業務控制器或者服務使用L6K28資訊網——每日最新資訊28at.com

<?php/** * @desc 會議 * @author Tinywan(ShaoBo Wan) * @date 2023/11/9 16:57 */declare(strict_types=1);public function meetingList(/support/Request $request, int $organizationId) : /support/Response{    $meetingList = /app/common/model/MeetingModel::where([        'organization_id' => $organizationId,        'create_user_id' => $this->userId    ])->select();    return json($meetingList->toArray());}

Db類使用

可以調用Db::connect方法動態配置數據庫連接信息L6K28資訊網——每日最新資訊28at.com

<?php/** * @desc 會議 * @author Tinywan(ShaoBo Wan) * @date 2023/11/9 16:57 */declare(strict_types=1);public function datasetList(/support/Request $request) : /support/Response{    $res = /think/facade/Db::connect(/request()->website)        ->table('resty_meeting')        ->field('id,name')        ->select();    return json($res->toArray());}

connect方法必須在查詢的最開始調用,而且必須緊跟著調用查詢方法,否則可能會導致部分查詢失效或者依然使用默認的數據庫連接。動態連接數據庫的connect方法僅對當次查詢有效。這種方式的動態連接和切換數據庫比較方便,經常用于多數據庫連接的應用需求。L6K28資訊網——每日最新資訊28at.com

動態連接到目標數據庫

在SaaS平臺中,如果需要根據前端傳遞的配置信息動態連接到目標數據庫并將數據拉取到本地數據庫,可以采用以下步驟實現L6K28資訊網——每日最新資訊28at.com

  • 前端傳遞配置信息。前端在用戶操作時,將目標數據庫的連接信息作為請求參數發送到后端。這些配置信息通常包括數據庫類型、主機地址、端口、數據庫名、用戶名和密碼等。
  • 驗證和解析配置信息。后端接收到配置信息后,首先進行驗證,確保其合法性和安全性。解析配置信息,并準備用于數據庫連接的參數。
  • 動態數據源管理。創建一個動態數據源管理器,它可以根據傳入的配置信息動態創建數據庫連接。
  • 數據同步。根據目標數據庫的連接信息,建立連接并執行數據查詢操作。然后將查詢結果同步到本地數據庫。這可能涉及到以下步驟:

建立連接:使用動態數據源管理器創建的目標數據庫連接。L6K28資訊網——每日最新資訊28at.com

執行查詢:在目標數據庫上執行SQL查詢,獲取所需數據。L6K28資訊網——每日最新資訊28at.com

映射數據:將查詢結果映射到本地數據庫的表結構中。L6K28資訊網——每日最新資訊28at.com

寫入本地數據庫:將映射后的數據插入到本地數據庫中。L6K28資訊網——每日最新資訊28at.com

  • 異常處理和日志記錄。在整個數據同步過程中,需要妥善處理可能出現的異常情況,并記錄相關操作日志,以便于問題追蹤和系統維護。
  • 安全性考慮
  • 加密敏感信息:確保所有的數據庫憑證信息在存儲和傳輸過程中都是加密的。L6K28資訊網——每日最新資訊28at.com

  • 權限控制:確保只有授權的用戶或服務才能訪問數據同步功能。L6K28資訊網——每日最新資訊28at.com

  • SQL注入防護:對動態執行的SQL進行嚴格的安全檢查,避免SQL注入攻擊。L6K28資訊網——每日最新資訊28at.com

自定義函數

函數配置文件app/functions.php新增函數dynamic_connect_db()L6K28資訊網——每日最新資訊28at.com

/** * @desc: 動態切換數據庫 * @param string $name * @param array $connection * @return /think/db/ConnectionInterface * @author Tinywan(ShaoBo Wan) */function dynamic_connect_db(string $name, array $connection): /think/db/ConnectionInterface{    try {        $connect = /think/facade/Db::connect($name);    } catch (/Throwable $e) {        // 獲取配置參數        $config  = /think/facade/Db::getConfig();        // 配置具體的數據庫連接信息        $config['connections'][$name] = $connection;        // 初始化配置參數        /think/facade/Db::setConfig($config);        // 創建/切換數據庫連接查詢        $connect = /think/facade/Db::connect($name);    }    return $connect;}

動態使用

調用自定義函數dynamic_connect_db()方法動態數據庫連接查詢,這里查詢一個不存在的配置數據庫zhejiang 浙江站點。L6K28資訊網——每日最新資訊28at.com

/** * @desc: 動態切換數據庫 * @param Request $request * @return Response * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException * @author Tinywan(ShaoBo Wan) */public function dynamicConnectDb(Request $request): Response{    $connection = [        'type' => 'mysql',        'hostname' => '127.0.0.1',        'database' => 'zhejiang.tinywan.com',        'username' => 'root',        'password' => '123456'    ];    $connect = dynamic_connect_db('zhejiang', $connection);    $result = $connect->table('resty_meeting')->where('id', 1)->find();    var_dump($result);    return json($result->toArray());}

在實際應用中,數據同步操作可能涉及到復雜的數據映射和處理邏輯,需要根據具體的業務需求進行設計和實現。同時,為了保障系統的穩定性和性能,可能還需要考慮引入事務管理、批量處理和異步處理等機制。L6K28資訊網——每日最新資訊28at.com

L6K28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-80200-0.htmlSaaS多租戶架構數據源動態切換解決方案

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 使用 HexFormat 來格式化和解析十六進制字符串

下一篇: 功能問題:如何用Docker部署一個后端項目?

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 石景山区| 漳州市| 德令哈市| 石棉县| 吉林市| 汶上县| 夏邑县| 山丹县| 洞口县| 禹州市| 天气| 太康县| 海口市| 金寨县| 宣化县| 镇沅| 姜堰市| 甘谷县| 枞阳县| 合江县| 承德市| 海盐县| 绵竹市| 舞阳县| 德安县| 崇仁县| 奉新县| 青冈县| 望江县| 克拉玛依市| 南皮县| 武鸣县| 新安县| 北安市| 台中市| 吉安县| 洱源县| 尖扎县| 修武县| 稻城县| 高青县|