You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何管理多客户端部署的Laravel Web应用的功能更新与维护?

Laravel多租户定制项目优化方案

针对你这种核心功能一致、仅需租户级标识定制的场景,推荐以下几种低成本、易维护的方案,按维护成本从低到高排序:

1. 单数据库多租户(推荐首选)

实现思路

所有租户共享一套数据库表,给需要区分租户的业务表(如 invoices、customers)添加tenant_id字段,同时新增tenants表存储每个租户的定制信息(Logo、名称、域名等)。利用Laravel的全局作用域自动过滤当前租户的数据,避免每次查询都手动加条件。

关键代码示例

  • 创建Tenant模型及tenants表:
    Schema::create('tenants', function (Blueprint $table) {
        $table->id();
        $table->string('name'); // 租户名称
        $table->string('subdomain'); // 子域名(用于识别租户)
        $table->string('logo_url')->nullable(); // Logo地址
        $table->timestamps();
    });
    
  • 给业务表添加tenant_id:
    Schema::table('invoices', function (Blueprint $table) {
        $table->foreignId('tenant_id')->constrained();
    });
    
  • 全局作用域自动过滤租户数据:
    // 在Invoice模型中添加全局作用域
    protected static function booted()
    {
        static::addGlobalScope('tenant', function (Builder $builder) {
            $tenant = request()->tenant; // 从中间件获取当前租户
            if ($tenant) {
                $builder->where('tenant_id', $tenant->id);
            }
        });
    }
    
  • 子域名识别租户的中间件:
    public function handle(Request $request, Closure $next)
    {
        $subdomain = explode('.', $request->getHost())[0];
        $tenant = Tenant::where('subdomain', $subdomain)->firstOrFail();
        $request->merge(['tenant' => $tenant]);
        // 绑定到容器,方便全局调用
        app()->instance(Tenant::class, $tenant);
        return $next($request);
    }
    

优缺点

  • 优点:一套代码、一次部署,升级/修Bug只需操作一次;资源利用率最高,维护成本极低;定制信息集中管理,可通过后台批量修改。
  • 缺点:数据逻辑隔离,需确保代码无漏洞(如全局作用域失效导致数据越权);租户数据量极大时需优化索引。

2. 单数据库多Schema(PostgreSQL专属)

实现思路

基于PostgreSQL的Schema特性,每个租户对应一个独立的Schema(如tenant_client1),共享一套表结构但数据物理隔离。Laravel中通过动态切换数据库连接的Schema来实现租户隔离,定制信息存储在各自Schema的配置表中。

关键操作

  • 创建租户Schema的脚本:
    CREATE SCHEMA tenant_client1;
    
  • 中间件中动态切换Schema:
    public function handle(Request $request, Closure $next)
    {
        $tenant = $this->getCurrentTenant();
        config()->set('database.connections.pgsql.schema', "tenant_{$tenant->id}");
        \DB::purge('pgsql');
        \DB::reconnect('pgsql');
        return $next($request);
    }
    

优缺点

  • 优点:数据物理隔离,安全性更高;租户数据独立,备份恢复更灵活。
  • 缺点:依赖PostgreSQL,MySQL不支持;Schema数量过多会增加数据库维护复杂度。

3. 多数据库单租户

实现思路

每个租户对应一个独立的数据库,Laravel中动态切换数据库连接配置来访问对应租户的数据。定制信息存储在各自数据库的配置表中。

关键代码示例

  • 中间件中切换数据库:
    public function handle(Request $request, Closure $next)
    {
        $tenant = $this->getCurrentTenant();
        config()->set('database.connections.mysql.database', "db_{$tenant->id}");
        \DB::purge('mysql');
        \DB::reconnect('mysql');
        return $next($request);
    }
    
  • 批量执行数据库迁移脚本(用Shell或Laravel Envoy):
    # 遍历所有租户数据库执行迁移
    for tenant_id in $(mysql -u root -p -e "SELECT id FROM tenants" -sN); do
        php artisan migrate --database=mysql_$tenant_id
    done
    

优缺点

  • 优点:数据完全隔离,适合对数据安全要求极高的客户;租户间无资源竞争。
  • 缺点:维护成本较高,升级需遍历所有数据库;服务器资源消耗大。

通用优化要点

  • 定制内容集中管理:将Logo、名称等可配置项存储在租户配置表,前端渲染时动态读取,避免硬编码或修改代码。
  • 自动化部署升级:用Git管理代码,单库模式只需部署一次;多库模式编写脚本批量执行迁移和代码更新。
  • 租户识别机制:优先用子域名(client1.yourapp.com)或自定义域名绑定,也可通过登录用户关联租户ID。

内容的提问来源于stack exchange,提问作者Shubham Sharma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 23:44:55