Files
notes/work/移动杭研/开发记录/7.16.0/域名备案查询方案.md
T
2026-03-01 01:43:46 +08:00

3.3 KiB

XinAnApiService 中 getDomainsIcp 逻辑非常糟糕,递归多次查询,没必要。帮我实现新的查询功能,保持原来的所有代码不要动,在类最后新写一个方法。但是保持入参、返回值和 原getDomainsIcp 一致。

域名备案查询方案

目标

对一批域名进行备案查询。由于信安接口单次最多支持 100 个域名,因此需要对域名进行拆解、去重、分批查询,并最终为每个域名选出“最接近原始域名但有备案”的结果。

整体流程

① 域名拆解(从左向右逐级截断)

对每个输入域名,按 . 分段,并从每个位置向右拼接成子域名列表。 最低拆到这种 baidu.com 程度作为最后一级,也就是主域名的上一级,不要拆到顶级域名 com,com 这种去查备案号没什么用。

主域名以 List<String> mainDomainCollections =mainDomainDao.findAll().stream().map(MainDomainPO::getDomain).collect(Collectors.toList()); 为优先,如果没在表中的默认拆到两级。

main_domain 的数据是这种:

or.id
org.pg
tw
tel
信息
广东

注意表中可能出现 xj.cn 和 cn,要先main_domain排序后去匹配域名。

例如:

  • a.b.c.baidu.com
    a.b.c.baidu.com, b.c.baidu.com, c.baidu.com, baidu.com

  • a.b.c.d.baidu.com
    a.b.c.d.baidu.com, b.c.d.baidu.com, c.d.baidu.com, d.baidu.com, baidu.com

  • a.b.c.d.org.pg
    a.b.c.d.org.pg, b.c.d.org.pg, c.d.org.pg, d.org.pg

② 全局去重

所有要查询的域名放入一个 Set,去掉重复项,例如 baidu.com 只会出现一次。

③ 分批调用信安接口

规则:

  • 按 100 个域名一批切分
  • 每批调用一次信安接口
  • 将所有批次的结果合并成:
    recordMap:域名 → 备案信息

④ 为每个原始域名选择“最佳备案”

对于一个域名的候选列表(从长到短):

例如:

[a.b.c.baidu.com, b.c.baidu.com, c.baidu.com, baidu.com]

选择第一个在 recordMap 中“有备案”的域名,作为最终结果。

例:

  • a.b.c.baidu.com → 无备案
  • b.c.baidu.com → 有备案(选它)

最终输出:

原始域名 → 最匹配备案号

底层查询使用 private Map<String, String> queryDomainsIcpByGroup(List<String> domains),已实现分组、重试直接用就行。代码要易读健壮优雅。

函数说明:

    /**
     * 批量查询域名备案号
     * @param domains 域名集合
     * @return Map value: false:未备案;具体备案号:说明备案;"":信安未返回
     */
    private Map<String, String> queryDomainsIcpByGroup(List<String> domains) {
        Map<String, String> result = Maps.newHashMap();
        //list分组
        List<List<String>> lists = Lists.partition(domains, XINAN_DOMAIN_QUERY_SIZE);
        lists.parallelStream().forEach((temp -> {
            try {
                Map<String, String> domainsIcpMap = queryDomainsIcp(temp);
                if (MapUtils.isNotEmpty(domainsIcpMap)) {
                    result.putAll(domainsIcpMap);
                }
            } catch (Exception e) {
                log.error("queryDomainsIcpByGroup() -> 批量分组查询icp异常, domains:{}", JacksonUtils.toJSONString(domains), e);
            }
        }));
        return result;
    }