跳到主要内容

规则设备范围、业务绑定与数量口径

同一条设备筛选条件可能服务于任务推送、Launcher 广告或其他业务。规则库通过 business_type + business_id 表达目标,而不是为每个业务新建一套设备筛选表。设备范围则分为直接 MAC、可复用 MAC 资源、渠道和地区,便于运营批量维护而无需改写每一条 EL。

设备范围表怎样协作​

表使用方式为什么单独存储
rule_mac_item某条规则直接绑定 MAC适合本规则专用名单,携带独立的待审批 valid 状态
rule_mac_resource命名 MAC 资源集维护资源名和说明,减少同一批名单重复导入
rule_mac_resource_item资源集内的 MAC 项支持批量导入/移除、审批状态和分区查询
rule_chain_mac_resource_item规则引用哪个资源集将资源复用关系与资源内容分开;资源被规则引用时删除受业务校验约束
rule_channel_item某规则覆盖的设备渠道编号通过 device 渠道归属动态圈选,不复制全部设备档案
rule_region_item某规则允许的地区编号候选规则形成后按设备地区进一步筛选
rule_business规则与目标业务的对应关系同一业务可通过多条规则获得设备覆盖,业务主数据仍在业务服务

Mermaid Diagram Code:

erDiagram
  rule_liteflow_chain ||--o{ rule_mac_item : liteflow_chain_id
  rule_liteflow_chain ||--o{ rule_channel_item : liteflow_chain_id
  rule_liteflow_chain ||--o{ rule_region_item : liteflow_chain_id
  rule_liteflow_chain ||--o{ rule_business : liteflow_chain_id
  rule_liteflow_chain ||--o{ rule_chain_mac_resource_item : liteflow_chain_id
  rule_mac_resource ||--o{ rule_chain_mac_resource_item : mac_resource_id
  rule_mac_resource ||--o{ rule_mac_resource_item : mac_resource_id

以上均为逻辑关系,实测没有物理 FK。直接 MAC 与资源 MAC 都保存 MAC 文本,不按 device_id 建关联,也没有存 CPU,因此规则名单的设备粒度不能照搬设备档案的 (mac,cpu) 唯一身份。MacListUnionDO 联合显示两种来源及规则/资源名,是查询投影,不是一张新表。

has_mac=0 表示无设备范围限制的候选规则;它仍需与本次业务类型的规则集合取交集,之后还要做地区、EL、启用和有效性判断。创建绑定业务的规则且没有渠道时,当前代码会放入占位 MAC AA:BB:CC:DD:EE:FF,防止空名单立即变成无限定范围;这个记录的业务意图不能从普通 MAC 字段字典中读出。

当前候选集合逻辑为 (MAC 关联规则 ∪ 无设备范围规则 ∪ 渠道规则) ∩ 业务类型规则。地区关联不参与这一步并集,而在执行前单独过滤;设备导出类型跳过 MAC 专属规则查询。关联数据查询多处使用 valid!=0,是为了保留待修改/待删除但尚未完成审批的已生效内容,不应将这些状态直接当作失效记录。

分区与去重​

MAC 明细当前分区编号由父 ID 和 MAC 两部分计算:(abs(parentId.hashCode()%10)+10)*100 + (abs(mac.hashCode()%30)+10)。父 ID 对直接名单是规则 ID,对资源名单是资源 ID。查询可按父 ID 枚举其 30 个低位桶,或按 MAC 枚举 10 个高位桶;旧 PARTITION_NUM=150 对应已弃用单参数方法,不能写成当前全部名单采用 150 分区。

实测两张 MAC 明细表主键均为 (id,partition_index);唯一键分别为 (liteflow_chain_id,mac,partition_index) 和 (mac_resource_id,mac,partition_index)。批量导入使用重复键更新维护 valid:已标记删除的项可恢复为已生效,其余状态按是否需要审批区别处理。数据库唯一键保证的是带分区号的组合,不是 MAC 在整个规则系统唯一。补采确认两表各有 300 个 LIST(partition_index) 分区,具体边界见实测字典;查询需要保留父对象 ID、MAC 及对应分区号,不能仅凭表已分区推断全表过滤很快。

businessId 到底指向哪里​

类型当前业务含义及目标编号审批默认要求
0 TASK_PUSHtask 的 nebula_ids.base_task_device.id,匹配后转为 TaskDO 推送;不是遗留 base_task.id是
1 LAUNCHER_PUSHlauncher 的 launcher_index.id,即广告位,不是 launcher_base_info.id是
2 BLACK_LISTblacklist 的 app_blacklisted.id,再读取对应黑名单配置是
3 UOTA_UPDATE枚举保留的 UOTA 升级类型;本次限定调用核对未确认其独立在线匹配入口否
4 DOMAIN_DISPATCHtask 独立库的 task_domain.id否
5 DOMAIN_DISPATCH_UOTAtask 独立库的 task_domain_uota_app.id否
6 DEVICE_RULE_EXPORTdevice 独立库的 device_rule_export_config.id,导出匹配结果分文件保存否

相同数字 business_id 在不同类型中可以指向不同记录,必须与 business_type 一起使用。规则绑定 Service 会检查重复三元组 (liteflow_chain_id,business_type,business_id);对需要审批的类型,还限制该规则已有其他业务绑定时不能继续绑定。数据库自身没有这些复合唯一约束,业务限制依赖入口校验。

外部业务删除后通过规则 API 解绑,数据库不会跨库级联。特别是 task 的域名 UOTA 删除代码当前调用类型 4,而查询使用类型 5,已列入差异页;不能据此认定两种业务 ID 可混用。

覆盖数量与数量限制是两类数据​

rule_device_count 保存用于管理展示的覆盖数量缓存:type=0 时按规则 ID,type=1 时按业务类型和业务 ID。RuleDeviceCountServiceImpl 汇总 MAC、资源和渠道设备并去重,类说明明确不计算地区与 EL 过滤。因此这个数字不是最终运行命中量,更不是任务推送成功量。它有独立创建/更新时间和逻辑删除字段,但没有业务组合唯一键,重新计算的幂等性由服务处理。

rule_business_limit 保存业务限额 limit_count 和当前计数 current_count。Kafka 消费者按业务键加锁维护:明确传入 currentCount 时覆盖,否则按 addCount 增量更新;limitCount=-1 表示不限制。缓存用于查询或运行匹配读取。

运行工具实际存在数量检查分支,但只有 BusinessTypeEnum.hasCountLimit=true 才会执行,而当前所有枚举值均为 false。所以不能把该表描述为“所有任务已经实施硬性配额”,也不能因为入口旧注释“暂不实现”就否认后续数量判断代码存在。这是保留能力与当前业务开关不一致的演进状态,未通过运行验证。

源码证据​

证据位置
MAC 分区算法B/util/MacPartitionUtil.java:17,36,52,66,77
名单导入状态与唯一键更新R/mapper/chain/RuleMacItemMapper.xml:5,20;R/mapper/macresource/RuleMacResourceItemMapper.xml:5,20
绑定校验与占位 MACB/service/chain/RuleLiteflowChainServiceImpl.java:158,408,423
候选集合与范围检查A/util/RuleRunUtil.java:528,573;B/service/business/RuleBusinessApiServiceImpl.java:982,997,1009
业务类型和审批/限额标识F/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/BusinessTypeEnum.java:18
数量覆盖口径B/service/chain/RuleDeviceCountServiceImpl.java:28,81,178
限额消息消费及匹配B/kafka/consumer/RuleBusinessLimitConsumer.java:68,173;A/util/RuleRunUtil.java:664

跨服务精确证据均位于 ik_project/yudao-cloud/:task-biz 的 service/task/TaskServiceImpl.java:479 与 dal/dataobject/task/TaskDO.java:20;service/domain/DomainServiceImpl.java:131 与 dal/dataobject/domain/DomainDO.java:15、DomainUotaAppDO.java:14;launcher-biz 的 service/push/LauncherBaseInfoServiceImpl.java:651 与 dal/dataobject/push/LauncherIndexDO.java:16;blacklist-biz 的 service/blacklisted/AppBlacklistedServiceImpl.java:1255 与 dal/dataobject/blacklisted/AppBlacklistedDO.java:18。各位置省略对应模块标准 src/main/java/cn/iocoder/yudao/module/{模块}/ 前缀。

业务表解释见 task、launcher、blacklist 和 device 规则导出。

用户文档
AI 助手
Agent 列表
请选择一个 Agent 开始对话
AI 问答