spring-boot-starters/MULTI_TENANT_MODE_IMPROVEMENT.md
用户在 issue #3835 中提出了一个架构设计问题:
基础 Wx 实现类中已经有 configMap 了,可以用 configMap 来存储不同的小程序配置。不同的配置,都是复用同一个 http 客户端。为什么在各个 spring-boot-starter 中又单独创建类来存储不同的配置?从 spring 的配置来看,http 客户端只有一个,不同小程序配置可以实现多租户,所以似乎没必要单独再建新类存放?重复创建,增加了 http 客户端的成本?直接使用 Wx 实现类中已经有 configMap 不是更好吗?
从 4.8.0 版本开始,我们为多租户 Spring Boot Starter 提供了两种实现模式供用户选择:
实现方式:为每个租户创建独立的 WxService 实例,每个实例拥有独立的 HTTP 客户端。
优点:
缺点:
代码实现:WxMaMultiServicesImpl, WxMpMultiServicesImpl 等
实现方式:使用单个 WxService 实例管理所有租户配置,通过 ThreadLocal 切换租户,所有租户共享同一个 HTTP 客户端。
优点:
缺点:
代码实现:WxMaMultiServicesSharedImpl, WxMpMultiServicesSharedImpl 等
wx:
ma: # 或 mp, cp, channel
apps:
tenant1:
app-id: wxd898fcb01713c555
app-secret: 47a2422a5d04a27e2b3ed1f1f0b0dbad
tenant2:
app-id: wx1234567890abcdef
app-secret: 1234567890abcdef1234567890abcdef
config-storage:
type: memory
http-client-type: http_client
# 多租户模式配置(新增)
multi-tenant-mode: shared # isolated(默认)或 shared
@RestController
public class WxController {
@Autowired
private WxMaMultiServices wxMaMultiServices; // 或 WxMpMultiServices
@GetMapping("/api/{tenantId}")
public String handle(@PathVariable String tenantId) {
WxMaService wxService = wxMaMultiServices.getWxMaService(tenantId);
// 使用 wxService 调用微信 API
return wxService.getAccessToken();
}
}
以 100 个租户为例:
| 指标 | 隔离模式 | 共享模式 |
|---|---|---|
| HTTP 客户端数量 | 100 个 | 1 个 |
| 内存占用(估算) | ~500MB | ~50MB |
| 线程安全 | ✅ 完全安全 | ⚠️ 需注意异步场景 |
| 性能 | 略高(无 ThreadLocal 切换) | 略低(有 ThreadLocal 切换) |
| 适用场景 | 中小规模 | 大规模 |
目前已实现共享模式支持的模块:
wx-java-miniapp-multi-spring-boot-starterwx-java-mp-multi-spring-boot-starter后续版本将支持:
升级到 4.8.0+ 后:
multi-tenant-mode,将继续使用隔离模式(与旧版本行为一致)multi-tenant-mode: shared 启用共享模式使用隔离模式(ISOLATED)的场景:
使用共享模式(SHARED)的场景:
如果使用共享模式,在异步编程时需要注意 ThreadLocal 的传递:
// ❌ 错误:异步线程无法获取到正确的配置
CompletableFuture.runAsync(() -> {
wxService.getUserService().getUserInfo(...); // 可能使用错误的租户配置
});
// ✅ 正确:在主线程获取必要信息,传递给异步线程
String appId = wxService.getWxMaConfig().getAppid();
CompletableFuture.runAsync(() -> {
log.info("AppId: {}", appId); // 使用已获取的配置信息
});
感谢 issue 提出者对项目架构的深入思考和建议,这帮助我们提供了更灵活、更高效的多租户解决方案。