← ClaudeAtlas

multi-tenant-golisted

Go 多租户模式专家 - 租户上下文传播(HTTP Header/gRPC Metadata)、Context 注入与提取、HTTP中间件/gRPC拦截器自动传播、数据隔离(共享数据库+租户分区键)、租户感知缓存(键隔离/空值防穿透/随机TTL防雪崩)、消息队列租户隔离(Kafka分区/Pulsar属性)、跨服务传播(HTTP InjectToRequest/gRPC InjectToOutgoingContext)、租户生命周期管理。适用:SaaS多租户系统、B2B平台、微服务租户隔离、多租户数据安全。不适用:单租户系统、租户无数据隔离需求的内部工具、纯前端多租户(应在BFF层处理)。触发词:multi-tenant, 多租户, tenant, 租户隔离, tenant isolation, tenant context, 租户上下文, SaaS, B2B, 数据隔离
omeyang/Thoth · ★ 0 · AI & Automation · score 73
Install: claude install-skill omeyang/Thoth
# Go 多租户模式专家 使用 Go 实现多租户模式:$ARGUMENTS --- ## 1. 租户上下文定义 ### Context Key 与基础操作 ```go // 使用 typed key 防止冲突 type contextKey string const ( keyTenantID = contextKey("tenant_id") keyTenantName = contextKey("tenant_name") ) // TenantInfo 租户信息(请求级) type TenantInfo struct { TenantID string TenantName string } func (t TenantInfo) IsEmpty() bool { return t.TenantID == "" && t.TenantName == "" } func (t TenantInfo) Validate() error { if t.TenantID == "" { return ErrEmptyTenantID } if t.TenantName == "" { return ErrEmptyTenantName } return nil } var ( ErrEmptyTenantID = errors.New("empty tenant_id") ErrEmptyTenantName = errors.New("empty tenant_name") ) ``` ### Context 注入与提取 ```go // 注入 func WithTenantID(ctx context.Context, id string) context.Context { return context.WithValue(ctx, keyTenantID, id) } func WithTenantInfo(ctx context.Context, info TenantInfo) context.Context { if info.TenantID != "" { ctx = context.WithValue(ctx, keyTenantID, info.TenantID) } if info.TenantName != "" { ctx = context.WithValue(ctx, keyTenantName, info.TenantName) } return ctx } // 提取(零值安全) func TenantID(ctx context.Context) string { if v, ok := ctx.Value(keyTenantID).(string); ok { return v } return "" } // 强制提取(业务必需场景) func RequireTenantID(ctx context.Context) (string, error) { v := TenantID(ctx) if v == "" { return "", ErrEmptyTenantID } return v, nil } ``` > 完整 Context 操作和 Identity 结构体见 [references/examples.md