多租戶 Laravel

Laravel 框架的靈活性使我們還可以實現多租戶架構。

多租用戶是一種軟體架構,其中應用程式的單一實例為多個客戶應用程式提供服務。

在這篇文章中,我們將探討 Laravel 中的多租戶概念、它的好處以及如何實現它。我們還將了解必要的配置、實用的程式碼範例和步驟,以確保您的多租戶應用程式順利運行。

每個租戶都可以被視為一個單獨的客戶,其自己的資料與其他租戶隔離。

預計閱讀時間: 5 minuti

什麼是多租戶?

多租戶是一種允許單一應用程式託管多個租戶(客戶)及其資料和配置的體系結構。每個租戶的資料彼此隔離,確保資料機密性和安全性。多租戶可以透過多種方式實施,包括:

  1. 數據庫, Schema 共享:全部 tenant condividono lo stesso 數據庫 e le stesse tabelle.
  2. 數據庫 singolo, Schemi 分開:我 tenant condividono lo stesso 數據庫 ma hanno il proprio schema.
  3. 數據庫 multipli: ogni tenant ha il proprio 數據庫.

該模型的優點

  1. 可擴展性: 更容易擴展新應用程式 tenant 沒有重大變化。
  2. 成本效益: 透過共享資源來降低基礎設施和維護成本 tenant.
  3. 集中維護: 由於只有一個應用程式實例,因此簡化了更新和維護。
  4. 使用者體驗 改進:針對不同的環境可客製化 tenant.

實施多租戶 Laravel

Laravel 開發了多種工具來幫助實現多租戶架構,例如:

  • hyn/multi-tenant- 允許您管理一個軟體架構,其中應用程式的單一執行個體為多個租用戶(或使用者帳戶)提供服務,從而確保每組使用者的資料安全和隱私。此工具通常用於提供SaaS(軟體即服務)服務。
  • tenancy/tenancy:靈活的解決方案 多租戶 拉拉維爾。讓我們看看下面的一些功能:
    • 自動租賃: Invece di modificare la configurazione del tuo progetto, il pacchetto avvia automaticamente il multi-tenancy in background. Cambia le connessioni al 數據庫, separa le cache, aggiunge prefissi ai filesystem e altro ancora;
    • 自動資料分離: Il pacchetto rende automaticamente tenant-aware: 數據庫, cache, filesystem, code e store Redis. Non devi modificare nulla se hai già scritto il tuo progetto;
    • 與其他包集成: Poiché la modalità automatica cambia la connessione al 數據庫 predefinita, molti altri pacchetti utilizzeranno questa connessione. Ad esempio, puoi utilizzare 拉拉維爾·諾瓦 在租戶應用程式中管理租戶資源;
    • 事件驅動架構:多租戶啟動邏輯、後租戶建立邏輯等操作都是透過事件發生的。您可以定制各個方面;
    • 多資料庫租賃:如果您不想使用每個租戶資料庫的方法,該軟體包提供了模板來將模板限制為當前租戶,即使是與租戶不直接相關的模板;

在本文中我們將使用該工具 tenancy/tenancy,這為 Laravel 中的多租戶提供了堅實的基礎。那麼讓我們一步步看看如何在 Laravel 實現多租戶。

第 1 步:安裝軟體包

首先,我們來安裝這個套件 tenancy/tenancy 與作曲家:

作曲家需要租賃/租賃

第 2 步:發布您的配置

現在讓我們繼續發布套件設定檔:

php artisan 供應商:發布 --tag=tenancy

第 3 步:設定 Tenancy

現在讓我們繼續設定文件 tenancy.php,它位於目錄中 config以滿足應用需求。

因此以下是一些參數:

  • 存儲驅動程序,存儲: puoi configurare il driver per lo storage dei tenant. Ad esempio, puoi scegliere tra Redis o un 數據庫. Leggi di più sulla pagina dei 儲存驅動程式.
  • 租用戶路由命名空間:設定用於路由的控制器命名空間 routes/tenant.php.
  • 豁免域:如果存取此數組中存在的主機名,則路由 tenant.php 它們不會被記錄,從而允許您使用該檔案中存在的相同路由。
  • 數據庫: Imposta la connessione al 數據庫 per i dati del tenant.
  • Redis的:為您的租戶資料配置 Redis 連線。
  • 高速緩存:替換實例 CacheManager 支援多租戶。
  • 文件系統:配置租戶的文件儲存位置。

如需完整指南 閱讀文件.

步驟 4:建立租戶模板

建立模板 Tenant 代表您的申請中的每位租戶:

php artisan make:模型租用戶-m

在遷移檔案中,定義表結構 tenants:

Schema::create('租戶', function (Blueprint $table) {
$表->id();
$表->字串('名稱');
$table->string('domain')->unique();
$表->時間戳();
});

第 5 步:確定您的租戶

按網域或子網域識別您的租用戶。然後我們更新模型 Tenant 包含租戶識別邏輯:

命名空間 App\Models;

使用 Illuminate\Database\Eloquent\Model;
使用 Tenancy\Identification\Contracts\Tenant 作為 TenantContract;
使用 Tenancy\Affects\Connections\Contracts\ProvidesDatabase;
類別 Tenant 擴充 Model 實作 TenantContract、ProvidesDatabase
{
protected $fillable = ['名稱', '域'];
公用函數 getTenantKey(): 字串
{
返回「域」;
}
公用函數 getConnectionName(): 字串
{
返回「租戶」;
}
公用函數configureDatabase($事件):無效
{
$event->useConnection('租戶', [
'資料庫' => '租戶_' 。 $這個->id,
]);
}
}

所以有以下三種方法: getTenantKey 識別域, getConnectionName 識別連接 e configureDatabase 設定與正確資料庫的連接。

第6步:配置中間件

我們創造了 中間件 che si occuperà di cambiate la connessione del 數據庫 in base al tenant:

php artisan make:中間件租戶中間件

Nel middleware, identifichiamo il tenant e impostiamo la connessione al 數據庫:

命名空間 App\Http\Middleware;使用閉包;使用租賃\身分\合約\租戶;類別 TenantMiddleware { 公用函數句柄($request, Closure $next) { $hostname = $request->getHost(); $tenant = Tenant::where('domain', $hostname)->first();如果($租戶){ 租戶($租戶);返回 $next($request); } }

那我們來記錄一下 middleware TenantMiddleware in app/Http/Kernel.php:

protected $middlewareGroups = [
    'web' => [
        // other middleware...
        \App\Http\Middleware\TenantMiddleware::class,
    ],
];

步驟7: Migration Tenant

透過指定租戶連線來建立特定於租戶的遷移:

php artisan make:migration create_posts_table --create=posts --path=database/migrations/tenant

在遷移檔案中,定義租戶表結構:

Schema::connection('tenant')->create('posts', function (Blueprint $table) {
$表->id();
$table->string('標題');
$table->text('內容');
$表->時間戳();
});

第 8 步:租戶遷移

建立命令來執行特定於租戶的遷移:

php artisan make:指令 MigrateTenants

在命令檔案中,為每個租戶執行遷移:

命名空間 App\Console\Commands;

使用 Illuminate\Console\Command;
使用App\Models\Tenant;
MigrateTenants 類別擴展了 Command
{
受保護的 $signature = '遷移:租戶';
protected $description = '為所有租用戶執行移轉';
公用函數句柄()
{
租戶::all()->each(function (租戶$tenant) {
租戶($租戶);
$this->call('遷移', [
'--資料庫' => '租戶',
'--path' => '資料庫/遷移/租戶',
'--force' => 真,
]);
});
$this->info('租戶遷移成功完成。');
}
}

步驟9: Seed 德爾 Tenant

建立一個播種器來播種特定於租戶的資料:

php artisan make:seeder TenantSeeder

在播種器中,定義要播種的資料:

命名空間Database\Seeders;

使用 Illuminate\Database\Seeder;
使用App\Models\Tenant;
TenantSeeder 類別擴展了 Seeder
{
公用函數run()
{
租戶::創建([
'姓名' => '租戶一',
'網域名稱' => 'tenant1.example.com',
]);
租戶::創建([
'姓名' => '租戶二',
'網域名稱' => 'tenant2.example.com',
]);
}
}

運行 sider:

php artisan db:seed --class=TenantSeeder

實際場景

SaaS 應用程式

多租戶非常適合 SaaS 應用程序,其中多個客戶(租戶)需要使用相同應用程序,同時保持數據獨立。

大型組織

擁有多個部門的組織可以使用多租戶在同一應用程式中單獨管理部門資料。

託管

託管提供者可以使用多租戶為具有隔離環境的多個客戶提供託管服務。

作者