# 任务 # 日志 域名的理解: 冲突域名:在 self_service_domain_config 表中有 domain 和 cpDomain。例如冲突域名 baidu.com.01.houzhui.com 那么对应的 cpDomain 就是 baidu.com,我们叫 baidu.com.01.houzhui.com 冲突域名,其真实域名 baidu.com。 普通域名:在 self_service_domain_config 表中只有 domain。例如 yidong.com。 这里有一个小设计在显示的时候,一个企业下,可能他只有一个冲突域名。那么他看到的就是 cpDomain 字段。 但有两种特殊场景: 场景一:当他有两个冲突域名对应一个 cpDomain 的时候例如: 域名一:baidu.com.01.houzhui.com baidu.com 域名二:baidu.com.02.houzhui.com baidu.com 那么客户看到的是冲突域名的 domain 字段也就是:baidu.com.01.houzhui.com、baidu.com.02.houzhui.com。 场景二:普通域名 和 冲突域名的 cpDomain 一样,两个域名在一个企业下。 域名一:baidu.com.01.houzhui.com baidu.com 域名二:baidu.com 那么客户看到的是冲突域名的 domain 字段也就是:baidu.com.01.houzhui.com、baidu.com。 也就是客户可能知道的是冲突域名或者看到的是冲突域名的真实域名。 1. urlHostList:url 去重重新封装的 url 2. urlHostMap:key url,value 是 host 3. hostSet:host 集合 4. domainCacheMap:key 是域名,valude是域名配置信息(缓存) 缓存 key: IBS_6_domain_cpId;(domain 是客户传的值) 值:domain、domainPlain、enterpriseCpId、domainState、tenantId 需求: 现在需要处理这个客户调用的任务下发接口。在拿到客户请求后,能正确分析出客户是用冲突域名还是冲突域名对应的真实域名。然后下发任务给配管时,把客户穿的路径中的域名都转换成我们库中的 domain 字段和三方交互。 现在缓存貌似也有一些问题,比如: 当客户有两个域名,真实;和真实对应的冲突时,客户应该传真实域名和冲突域名。 此时把客户的 host 作为 key 去缓存。就可能是 baidu.com baidu.com.01.houzhui.com 但是如果缓存期间 客户把真实域名删除了,那么他会用 冲突域名对应的真实域名来刷新,从缓存获取就获取错了。 是不是只能通过进缓存前处理 url 呢?帮我看看怎么完成要求,现有的缓存和 冲突域名的处理应该是有问题。 --- 请仔细分析这里的场景,然后帮我优化代码,要求不要在 for 中 查库,性能太差了,但是要保持原逻辑语义。 ``` // 2. 处理未缓存的精准域名 if (!CollectionUtils.isEmpty(absentDomain)) { for (String domain : absentDomain) { Long count = selfServiceDomainConfigDao.countByTenantIdAndDomainOrCpDomain(enterpriseId, domain); if (count == 0) { String msg = String.format("该企业: %s 不存在此域名: %s", enterpriseId, domain); log.error(msg); throw new PlatformException(msg); } String configDomain = domain; // 不影响下边 DomainEnterpriseInfoRedisPO 的变量。 if (count == 1) { // 一个冲突或者一个真实 Optional tenantIdAndCpDomain = selfServiceDomainConfigDao.findByTenantIdAndCpDomain(enterpriseId, domain); if (tenantIdAndCpDomain.isPresent()) { configDomain = tenantIdAndCpDomain.get().getDomain(); // 是冲突域名,用 domain 找实际配置 } } Optional selfServiceDomainConfigPO = selfServiceDomainConfigDao.findByDomain(configDomain); // 如果 count 不是 1 也就是客户该传什么是什么。 if (!selfServiceDomainConfigPO.isPresent()) { String msg = String.format("该企业: %s 不存在此域名: %s", enterpriseId, domain); log.error(msg); throw new PlatformException(msg); } SelfServiceDomainConfigPO domainConfigPO = selfServiceDomainConfigPO.get(); DomainEnterpriseInfoRedisPO redisPO = DomainEnterpriseInfoRedisPO.builder() .domain(domain) .domainState(domainConfigPO.getState().ordinal()) .domainPlain(domainConfigPO.getDomainPlain().toString()) .enterpriseCpId(domainConfigPO.getTenantId()) .tenantId(domainConfigPO.getTenantId()) .build(); if (redisPO != null) { preciseDomainMap.put(domain, redisPO); redisUtil.setJSONString(RedisKeyUtils.contentDomainKey(domain, enterpriseId), redisPO, 1800L); } } } /** * 查询特定用户下,指定的 domain 或 cpDomain 匹配的记录数量。 * *

返回结果可能的场景如下: * *

* * @return 满足条件的记录数,返回结果可以是 0 条、1 条、2 条或 3 条等,表示不同配置的情况。 */ @Query("SELECT COUNT(s) FROM SelfServiceDomainConfigPO s WHERE s.tenantId = :tenantId AND (s.domain = :cpDomain OR s.cpDomain = :cpDomain)") Long countByTenantIdAndDomainOrCpDomain(@Param("tenantId") String tenantId, @Param("cpDomain") String cpDomain); Optional findByTenantIdAndCpDomain(String tenantId, String cpDomain); ``` 这些逻辑是为了实现冲突域名的转换,请问有什么方案能实现不在 for 循环中查库么? # 总结 写需求。