malk 012df8fbd6 feat(mjava-pro): DynamicDDService / DynamicYDService 多租户凭据中转 недель назад: 2
..
src 012df8fbd6 feat(mjava-pro): DynamicDDService / DynamicYDService 多租户凭据中转 недель назад: 2
README.md 012df8fbd6 feat(mjava-pro): DynamicDDService / DynamicYDService 多租户凭据中转 недель назад: 2
pom.xml 660b557f82 feat(mjava-pro): 多客户单部署子模块最小脚手架(add-mjava-pro) месяцев назад: 2

README.md

mjava-pro

多客户单部署运行时(A 档公共托管)。一个 jar 通过 X-Tenant-Id 路由到不同租户配置,按租户隔离凭据/缓存/日志/数据。

客户分档:见 openspec/changes/define-customer-tiering/specs/customer-tiering/spec.md R1。当前 mjava-pro = A 档容器。

端口与上下文

  • 端口:9010
  • context-path:/api/pro

调用范式

请求必须带 X-Tenant-Id Header(TenantInterceptor 识别,未带返 401 TENANT_REQUIRED,无对应配置返 403 TENANT_NOT_FOUND)。

业务代码示例:

@RestController
@RequestMapping("/example")
public class ExampleController {

    @Autowired DynamicYDService ydService;
    @Autowired YDClient_Form ydForm;

    @GetMapping("/forms")
    public McR listForms() {
        // ydService.buildAuth() 自动从当前租户拿凭据 + 钉钉 token
        Object data = ydForm.searchForm(ydService.buildAuth(), "FORM-XXX", null, null);
        return McR.success(data);
    }
}

钉钉直调:

@Autowired DynamicDDService ddService;
...
String token = ddService.getAccessToken();   // {tenantId}:dingtalk:{appKey} namespace cache
String corpId = ddService.currentCorpId();

新增租户(A 档入驻 SOP)

标准入驻清单见 define-customer-tiering spec R4。

  1. 校验:确认客户不命中 A→B 任一硬指标(无自定义 Controller / 无私有 schema / 无独立部署要求)
  2. 宜搭应用表加一行(formUuid 配在 application.ymltenant.registry.formUuid):
字段 必填 说明
tenantId 业务唯一标识,禁中文/特殊字符
tenantName 中文展示名(日志/监控可读性)
vendor dingtalk / aliwork / ...
appKey 产品方 appKey
appSecret 产品方 appSecret(宜搭加密字段)
corpId 钉钉系必填
extraJson 可选 vendor 特定参数 JSON 字符串(如宜搭的 appType / systemToken / userId
enabled false 拒绝该 tenant 请求
  1. 热加载:调 POST /_admin/reloadTenant(dev profile)或等下次 @Scheduled 刷新(默认 TTL 配在 application.yml
  2. 凭据热验证GET /api/pro/_diag/tenant/{tenantId} 探活(接口归后续 task 实现)
  3. 上线通告:邮件抄送运维 + 客户对接人

隔离边界

维度 隔离方式
DB 共享 schema,业务表必须含 tenant_id 列;JPA Interceptor 自动注入 WHERE 条件(待 task 实现)
缓存 UtilToken key 命名空间扩为 {tenantId}:{vendor}:{appKey}DynamicDDService 已实现)
日志 MDC 自动注入 tenantId;logback pattern 含 [%X{tenantId:-}](已落)
异步线程 TaskDecorator 传播 ThreadLocal(待生产启用时评估)

配置文件

文件 说明
application.yml 通用配置(端口、context-path、scheduling 等)
application-dev.yml.example dev profile 占位
application-prod.yml.example prod profile 占位
application-{profile}.yml 实际配置(不入 git

tenant.registry.* 配置块:

tenant:
  registry:
    appType: ${TENANT_REG_APP_TYPE}
    systemToken: ${TENANT_REG_SYSTEM_TOKEN}
    formUuid: ${TENANT_REG_FORM_UUID}
    userId: ${TENANT_REG_USER_ID}
    ttlSeconds: 600
    failFast: true

关联文档

  • 客户分档 spec:openspec/changes/define-customer-tiering/specs/customer-tiering/spec.md
  • 多租户 capability:openspec/changes/add-mjava-pro/specs/multi-tenant-runtime/ + specs/tenant-registry/
  • 基座 Client/Service 分层:openspec/specs/client-service-layering/spec.md R1~R7
  • 后端开发主规范:/Users/malk/Desktop/Tech/claude/后端/CLAUDE.md