业务流程与跨服务数据关系
当前系统的数据关系有三种:服务自有表之间的关系、单体拆分留下的直接访问、通过接口或消息形成的跨服务关联。它们不能都画成数据库外键。下面先按业务说明关系,再指出物理保障与核验边界。
独立库与遗留库怎样共存
nebula_ids 保留单体时期的设备、渠道、任务等对象。device 和 task 各自已有独立库,但当前代码仍保留默认数据源和部分显式跨库查询。它是尚未完成拆分的现状,不是将来所有数据都应共享的设计结论。本次不执行迁移。
一个明确的耦合是设备安装统计通 过 ik_app_install.app_install_count_package 关联遗留库 nebula_ids.sys_app_package_name。只迁移表而未检查 SQL 的限定库名,会遗漏这类依赖。另有 base_channel.task_id → base_task.id 的实测物理外键;其他按设备标识连接的关系不能类推为外键。
证据见 device 安装应用、device 设备档案、task 总览及遗留库物理字典。
从业务配置到审批生效
任务、桌面和黑名单把自身业务记录交给 BPM 审批,BPM 管理流程运行,业务服务管理“这份配置是否可以下发”。流程状态与业务有效状态属于不同字段体系,审批通过不能简单解释为替换某一个数据库外键。
| 业务 | 业务对象 / businessKey | 业务服务保存 | 审批结果怎样回来 |
|---|---|---|---|
| 任务投放审批 | base_task_device.id | 对应业务记录的流程实例 ID、审批及有效状态 | task 的 BPM 监听器转交业务服务按 businessKey 处理 |
| 桌面主配置审批 | launcher_base_info.id | 主配置流程实例 ID、审批状态、有效态及草稿 | launcher 的监听器回到主配置审批服务 |
| 黑名单审批 | app_blacklisted.id | 黑名单流程实例 ID、审批状态、有效态及草稿 | blacklist 的监听器回到黑名单业务服务 |
上述业务 ID 不是 BPM 的流程实例 ID,也不是审批任务 ID。不同业务域中的数值可以相同,解释关联时必须同时保留流程定义或业务类型上下文。共享 BpmBusinessValid 已表达待修改、待移除、启用/禁用标记等演进状态,旧字段注释不一定完整。
证据:task-biz 的 TaskBpmServiceImpl.java:86,105,123,429 及 listener/BpmTaskStatusListener.java:29(完整路径见 task 任务业务);launcher 的 service/push/LauncherBaseInfoBpmServiceImpl.java:152,171、listener/BpmLauncherStatusListener.java;其余具体入口见 BPM和黑名单。这些路径均相对对应服务的 Java 根,未将监听器存在写成线上回调已验证成功。
规则中心关联的是哪一个业务对象
规则中心保存匹配逻辑,各业务保存配置内容。关联需要业务类型与 businessId 一起解释,不能把一个裸 ID 当成全局业务主键。
| 业务类型 | businessId 的业务语义 | 使用场景 |
|---|---|---|
TASK_PUSH | 遗留库 nebula_ids.base_task_device.id | task 按设备条件匹配可下发任务,不是 base_task.id |
LAUNCHER_PUSH | launcher_index.id,即广告位 | 匹配可向设备返 回的广告位,不是主配置 ID 或素材 ID |
BLACK_LIST | app_blacklisted.id | 匹配对设备生效的黑名单配置 |
DOMAIN_DISPATCH | task_domain.id | task 的域名服务筛选分发项 |
DOMAIN_DISPATCH_UOTA | task_domain_uota_app.id | task 的 UOTA 域名服务筛选分发项 |
DEVICE_RULE_EXPORT | device_rule_export_config.id | device 按规则条件组织设备导出配置 |
设备属性提供匹配输入,规则结果指向业务配置。规则投放与旧渠道/MAC/地区分支在部分服务中并存,开关可受 infra 参数覆盖;本次没有读取参数业务记录,因此不宣称某条分支在线上已经启用或废弃。
证据:launcher 的 listener/RuleLauncherStatusListener.java:16,44;task 的 TaskServiceImpl.java:479,484、TaskBpmServiceImpl.java:112,113、TaskDO.java:20、DomainServiceImpl.java:131,132、DomainDO.java:15、DomainUotaAppDO.java:14;完整绑定、通知和持久化说明见 rule、launcher 配置、task 域名。
文件、素材、设备回执与报表历史
infra 的文件 ID 用来定位存储元数据;launcher 素材表通过 resource_id/app_id 引用文件并带入资源信息。设备回执里的 adResourceId 则指向 launcher_index_advert.id。虽然字段都带 resource,不能把回执 ID 直接当成 infra_file.id。
任务统计通过 push_task_id 与素材关系取得 launcher 反馈,再与 task 自己记录的成功 MAC 合并去重。这个统计视图由服务代码组合,不能仅查看一张流水表就解释全部成功设备数。证据:launcher 的 LauncherExecRecordServiceImpl.java:76,109;task 的 TaskDeviceServiceImpl.java:293,300。
task 的设备事件入口按事件类型分流:安装应用列表交 device,桌面播放反馈交 launcher,黑名单反馈交 blacklist,设备运行信息进入对应统计链。接收到事件不表示入口服务拥有最终落库表,消息发送也不等于消费成功。
report 的 APK 历史独立保留推送/卸载事实,用设备 MAC、CPU 标识、包名、版本与推送时间解释多次历史。MySQL 存储与 ES 检索不具备本次已证明的跨系统原子事务;同步、补同步和降级查询由实现处理。
已确认的卸载链路是:task 事件入口分发黑名单反馈,blacklist 保存卸载流水后发送 ApkUninstallUpdateEvent;report 的 ApkUninstallUpdateConsumer 监听配置项 kafka.topic.apk-uninstall-update 对应主题并调用 updateCpuidAndUninstallTime。这个消费者补充的是推送历史,不应写成已经更新 device 安装快照;当前链路传入的是 blacklist 服务端消费时间,不是设备发生时间。证据:task 的 DeviceEventServiceImpl.java:184–190,blacklist 的 BlackCallbackConsumer.java:57–64,report 的 kafka/consumer/ApkUninstallUpdateConsumer.java:47,71;发送与默认主题见黑名单业务页。真实消息投递及消费结果未运行验证。
相关说明:infra 文件生命周期、launcher 反馈统计、task 事件与导出。
身份、权限、日志与租户
system 定义用户、角色、组织及租户。report 项目 role_ids 逻辑引用 system 角色,读取时结合用户角色做访问控制;它是 JSON 列,不是角色关系表的物理外键。业务中的操作者、接收人和创建者还要结合 user_type 或调用上下文解释,不能只凭数值 ID 判断主体。
infra 保存跨服务 API 日志。日志记录的业务对象与日志附件属于不同职责:infra_api_access_log.file_ids 逻辑关联文件元数据,文件本体可能位于外部存储。这些日志不会因为由公共模块写入,就成为被记录服务的自有业务表。
租户字段由实体、框架拦截器、忽略表配置和运行上下文共同影响。实库有 tenant_id 而 DO 未声明时,应保留这一差异并核对框架,不直接删列或判定隔离失效。见公共映射说明。
一致性边界
物理外键只能保障数据库所定义的引用约束;业务状态、缓存、消息、ES 索引与时序统计具有各自的维护流程。此次仅核验代码与元数据,没有扫描孤立记录、检查消息积压或运行审批/下发链路,因此不对数据完整性或运行期一致性作额外结论。