Stancl Tenancy v3 多租户 Laravel
将以下提示词粘贴到你的 AI 对话框中:
请根据 https://skillhub.cn/install/skillhub.md,安装 @user_3c6cb52e/tenancy-development 技能。
技能介绍
多租户到底难在哪
在 Laravel 里做 SaaS,租户隔离听起来只是"给查询加个 WHERE"。实际落地时,问题分散在请求生命周期的各个角落:
- 租户上下文初始化:域名、子域名、路径、请求数据四种识别方式,失败时如何优雅降级而不是白屏;
- 数据隔离:是每租户独立库,还是单库靠
BelongsToTenanttrait 和复合唯一索引兜底?withoutTenancy()又该在什么时候用; - 基础设施切换:切换租户时要重连数据库、缓存、文件系统、队列和 Redis,顺序错了就是脏数据;
- 异步任务:队列里的 job 恢复租户上下文、长驻进程(Horizon、Octane)里的前缀累积,都是文档里一句带过、线上才会炸的坑。
这个技能如何工作
它围绕 stancl/tenancy v3(^3.9)的完整 API 展开,按真实项目的组织方式提供指导:
- 梳理中心上下文 vs 租户上下文两种模式,帮你选定自动/手动租户切换策略;
- 给出
InitializeTenancyByDomain等中间件与自定义$onFail的处理范式; - 覆盖 Bootstrappers 全家桶(database、cache、filesystem、queue、Redis)以及如何写自定义 bootstrapper;
- 串讲租户级配置
TenantConfig、用户模拟、事件生命周期与JobPipeline; - 生产层面包含队列隔离(租户专属队列、优先级队列、独立 worker)、幂等 provisioning、Horizon 任务标签、Meilisearch 索引隔离等。
测试部分会直接改变你的迭代速度:基于事务的租户测试比常规方案快约 25 倍,同时提醒 Event::fake() 在隔离场景下的失效风险。
适用边界与注意点
三个坑被单独列为"Critical Gotchas",值得在写代码前先读一遍:
- 队列事件里绝不传租户作用域模型——
SerializesModels序列化时全局 scope 会在上下文恢复前触发,应传tenantId等标量,在handle()里tenancy()->initialize(); - 跨租户批处理前
DB::purge('tenant')会清空 PDO 连接,批量 job 需要专门处理; - 长驻进程中 Cache/Redis/filesystem 的 key 前缀会逐次累积,多轮切换后必须验证。
这套技能适合正在用 stancl/tenancy v3 构建或维护多租户系统的工程师;如果你只是偶尔加一个"组织切换"字段,或者用的是旧版 v2 的包结构,那么部分 API 和中间件说明并不适用。
使用场景
- 在 Laravel SaaS 中按域名或子域名识别租户,并配置 `$onFail` 处理初始化失败
- 为多租户系统选择单库或多库方案,并用 `BelongsToTenant` 与复合唯一索引隔离数据
- 在 Horizon/Octane 长驻进程里处理缓存与 Redis key 前缀累积问题
- 用事务型租户测试覆盖跨租户迁移与队列任务隔离
适合人员
- Laravel 后端工程师,正在用 stancl/tenancy v3 搭建多租户 SaaS 并需要选型数据隔离方案
- SaaS 平台技术负责人,需要在生产环境处理租户队列隔离与迁移发布
- 测试工程师,希望用事务型测试加速多租户场景验证并避免常见陷阱
- 维护遗留 Laravel 项目的开发者,准备引入租户上下文与 bootstrapper 机制