
引入接口前先界定它能做什么、不能做什么很多開發(fā)者拿到一個 API 后的第一反應(yīng)是“它能查什么”而忽略了一個更基礎(chǔ)的問題這個接口在整體技術(shù)架構(gòu)中處于什么位置它的能力邊界在哪里。DNS 記錄查詢接口并非一臺完整的 DNS 服務(wù)器也不是權(quán)威解析服務(wù)的替身。它的工作方式是接收一個域名和記錄類型以請求方身份通過指定的多家國內(nèi) DoH 并發(fā)源獲取解析記錄再將多份結(jié)果合并、去重并做結(jié)構(gòu)化整理后返回。換句話說接口提供的是一次“增量查詢”而非“遞歸解析”的能力它更適合作為開發(fā)流程中的信息收集工具而不是作為線上 DNS 基礎(chǔ)設(shè)施的一部分。理解這條邊界后續(xù)的選型、限流設(shè)計、緩存策略和結(jié)果解讀才不會走偏。適用場景哪些業(yè)務(wù)會真正用到它域名資產(chǎn)記錄巡檢如果你維護了一批域名需要定期確認(rèn)它們的 A / AAAA / CNAME / MX / TXT / CAA / SOA 等記錄是否存在、是否被意外修改可以用該接口批量獲取并對比。多類型查詢讓一次請求覆蓋多種業(yè)務(wù)需求比如同時檢查 Web 服務(wù)的 A 記錄、郵件系統(tǒng)的 MX 記錄和證書簽發(fā)相關(guān)的 CAA 記錄。開發(fā)聯(lián)調(diào)與故障排查在沒有 dig 命令或網(wǎng)絡(luò)受限的臨時環(huán)境里通過 curl 向接口發(fā)一次請求就能確認(rèn)某個域名的解析結(jié)果。配合 X-API-Key 和 type 參數(shù)也能快速驗證 DNS 配置變更是否生效。上游數(shù)據(jù)源的交叉印證接口背后聚合了 AliDNS、DNSPod、360 三家 DoH 源并把命中同一記錄的來源寫入 sources 字段。當(dāng)本地解析結(jié)果與預(yù)期不一致時可以通過該字段判斷這是一條普遍生效的記錄還是個別 DNS 服務(wù)器的特殊結(jié)果。CAA、MX、SOA 等結(jié)構(gòu)化字段消費CAA、MX、SOA 這類記錄在純文本形式下難以直接處理。接口對它們做了拆分MX 拆成 priority 與 exchangeCAA 拆成 flags / tag / valueSOA 拆出 mname 等字段。這類解析結(jié)果特別適合直接寫入配置巡檢平臺或證書管理工具。不適合用這個接口的場景高 QPS 的全量域名掃描該接口的限速為 10 QPS。如果要對數(shù)十萬乃至百萬級域名做全量遍歷單個賬號直接循環(huán)請求會迅速打滿限額并造成超時。此類場景應(yīng)當(dāng)走自己的遞歸解析或批量任務(wù)隊列而不是把該接口當(dāng)成公共解析池。要求嚴(yán)格權(quán)威視角的場景由于接口對三個 DoH 源的數(shù)據(jù)做合并去重它反映的是“公共解析視角”企業(yè)內(nèi)網(wǎng)私有域名、split-horizon DNS、按地理位置動態(tài)解析的場景均不在覆蓋范圍內(nèi)。若要驗證內(nèi)網(wǎng)域名或本地路由直接用權(quán)威服務(wù)器查詢更合適。需要完整歷史記錄或變更日志接口是即時查詢會返回當(dāng)前從 DoH 源能獲取到的記錄不提供歷史變更軌跡。如果你需要審計“某個域名三個月前做過哪些改動”應(yīng)自行搭建采集任務(wù)并存儲歷史數(shù)據(jù)。接口協(xié)議與參數(shù)邊界項值說明接口路徑GET https://v1.apizero.cn/api/dns-query僅支持 GET 請求限速10 QPS超過之后的行為以文檔為準(zhǔn)分類開發(fā)工具屬于通用查詢能力鑒權(quán)X-API-Key可選不攜帶則走匿名額度Query 參數(shù)參數(shù)必填類型說明host是string域名接口會自動剝離 http(s)://、路徑與端口type否string記錄類型默認(rèn) A支持名稱A/AAAA/NS/CNAME/MX/TXT/CAA/SOA/ANY或數(shù)字編碼1/2/5/6/15/16/28/257type 參數(shù)是接口靈活性的核心既兼容舊調(diào)用方式中的數(shù)字編碼1A、15MX、257CAA也支持可讀性更強的記錄名。如果你的業(yè)務(wù)配置中心已經(jīng)存儲了數(shù)字編碼無需額外做映射即可直接使用。Header 參數(shù)參數(shù)必填類型說明X-API-Key否stringAPI Key不傳則使用匿名額度鑒權(quán)不是硬性前置條件但需要注意的是匿名額度與攜帶 Key 的額度在 QPS 上限上未必一致。具體數(shù)值以官方文檔為準(zhǔn)建議在企業(yè)內(nèi)部統(tǒng)一存放 Key便于后續(xù)做調(diào)用量追蹤。使用 curl 發(fā)起查詢不攜帶 Key 的最簡 A 記錄查詢curl -sS \ -X GET \ https://v1.apizero.cn/api/dns-query?hostexample.com這個請求會返回 example.com 的 A 記錄。由于未填寫 type按參數(shù)默認(rèn)值走 A 查詢。攜帶 API Key 查詢 MX 記錄curl -sS \ -X GET \ -H X-API-Key: $APIZERO_API_KEY \ https://v1.apizero.cn/api/dns-query?hosthosttypeMX使用前請先將$APIZERO_API_KEY與host替換成真實值。查詢?nèi)坑涗涱愋蚦url -sS \ -X GET \ -H X-API-Key: $APIZERO_API_KEY \ https://v1.apizero.cn/api/dns-query?hostexample.comtypeANYANY 的含義是單次請求盡可能多地返回該域名的 DNS 配置。需要說明的是ANY 響應(yīng)仍以三家 DoH 源能取到的記錄為上限若上游源未返回某一類型接口不會憑空補充。響應(yīng)結(jié)構(gòu)逐個拆解接口返回的是 JSON外層字段如下字段類型含義codenumber業(yè)務(wù)狀態(tài)碼0 表示成功msgstring狀態(tài)描述request_idstring單次請求標(biāo)識便于追蹤日志dataobject查詢結(jié)果主體data 對象字段字段說明host實際參與解析的域名input用戶在接口入?yún)⒅袀魅氲脑贾祎ype查詢的記錄類型名稱type_code查詢的記錄類型數(shù)字編碼exec_ms接口執(zhí)行耗時毫秒total返回的記錄條數(shù)notes附加說明通常為 null具體以文檔為準(zhǔn)sources本次查詢可用的 DoH 源名稱列表如 alidns / china360 / dnspodrecords記錄數(shù)組每個包含單條解析記錄input 與 host 分開返回是一個重要設(shè)計當(dāng)你傳入https://example.com/path這類帶協(xié)議和路徑的字符串時host 是剝離后的真實域名input 保留原始值便于排查入?yún)⑶逑词欠裆Аecords 數(shù)組中的單條記錄以 MX 記錄為例{ data: 10 mx.maillb.baidu.com., name: baidu.com, parsed: { exchange: mx.maillb.baidu.com, priority: 10 }, sources: [alidns, china360, dnspod], ttl: 600, type: MX, type_code: 15 }字段解讀data是原始 RDATA 文本MX 記錄就是“優(yōu)先級 郵件服務(wù)器”name是記錄所屬的域名parsed是結(jié)構(gòu)化拆分結(jié)果MX 拆出 exchange 與 priorityCAA 拆出 flags / tag / valueSOA 拆出 mname、serial 等字段sources表示該記錄被哪些 DoH 源返回并非權(quán)威來源標(biāo)識ttl是記錄的緩存時長單位秒type與type_code是記錄類型名稱與數(shù)字編碼。注意sources 字段的語義是“該記錄來源于這幾個 DoH”它不能用來計算“記錄被訪問了多少次”也不代表記錄的權(quán)威歸屬。ANY 聚合查詢的正確打開方式ANY 類型解決的核心問題是“我記不清某個域名到底配了哪幾類記錄”。在交付一個域名前用一次 ANY 請求就能拿到其現(xiàn)有配置輸出中會混有多種 type 的記錄。使用 ANY 時有兩點需要留意ANY 返回的是接口上游源在那一刻能收集到的集合不必追求字段上的絕對完整如果代碼邏輯強依賴“某種類型一定出現(xiàn)在 ANY 結(jié)果里”建議改為顯式指定對應(yīng) type 查詢避免因上游差異導(dǎo)致誤判。具體到某種資源記錄在 ANY 模式下是否被過濾、是否合并請以該接口文檔中的說明為準(zhǔn)。常見錯誤與排查切入點由于錯誤響應(yīng)示例未在本文素材中完整展開這里只列出通用排查思路具體錯誤碼與 HTTP 狀態(tài)對應(yīng)關(guān)系以文檔為準(zhǔn)。請求返回非 200常見原因是域名參數(shù)為空、host 填入的不是合法域名或網(wǎng)絡(luò)層無法連通接口。建議先確認(rèn)請求地址中的 host 已正確 URL 編碼再檢查客戶端到 v1.apizero.cn 的鏈路。code / msg 提示業(yè)務(wù)錯誤一般與參數(shù)校驗相關(guān)例如 type 傳入了不支持的取值。type 允許的名稱僅限 A/AAAA/NS/CNAME/MX/TXT/CAA/SOA/ANY數(shù)字編碼僅限 1/2/5/6/15/16/28/257。查詢成功但 total 為 0表示當(dāng)前域名在該類型下沒有記錄或三家 DoH 源均未返回結(jié)果。可先換一個知名域名做對照測試區(qū)分是接口問題還是域名本身沒有對應(yīng)記錄。接口耗時突然升高接口本身要并發(fā)請求多個 DoH 源耗時受上游影響會浮動。如果連續(xù)請求觸發(fā)限流也表現(xiàn)為耗時上升。發(fā)生時建議減少并發(fā)并觀察是否超出 10 QPS 的限制。工程化落地注意事項調(diào)用端必須做 QPS 控制10 QPS 是接口明確的邊界。若是多線程程序建議在發(fā)送端設(shè)置信號量或令牌桶把并發(fā)數(shù)限制在 10/秒以內(nèi)而不是依賴服務(wù)端限流后的報錯來被動降速。# 偽代碼控制調(diào)用速率 import time from threading import Lock class RateLimiter: def __init__(self, qps10): self.interval 1.0 / qps self.lock Lock() self.next_time time.time() def acquire(self): with self.lock: now time.time() if now self.next_time: time.sleep(self.next_time - now) self.next_time time.time() self.interval實際生產(chǎn)環(huán)境中可以選擇現(xiàn)成的限流庫但核心邏輯一致把速率控制在 10 QPS 以內(nèi)。善用 TTL 字段做緩存records 返回里已經(jīng)帶上了 TTL建議用這個值作為本地緩存的過期時間。例如 TTL 為 600 的記錄緩存 10 分鐘即可減少請求次數(shù)也就不用擔(dān)心 QPS 被打滿。調(diào)用前清洗 host雖然接口支持自動剝離協(xié)議、路徑和端口調(diào)用方仍建議先做一層校驗只把純域名傳給接口。自動化任務(wù)中解析用戶輸入時尤其重要可以避免把異常內(nèi)容帶入日志。關(guān)注 type 參數(shù)默認(rèn)值帶來的可讀性問題不傳 type 時默認(rèn)查詢 A 記錄這在批量場景里容易造成誤解你以為系統(tǒng)在拉 MX實際拉的是 A。建議在調(diào)用代碼中顯式寫明 type 參數(shù)讓日志和代碼語義保持一致。不要把 sources 當(dāng)作權(quán)威依據(jù)sources 描述的是記錄來源不等于這條記錄在公網(wǎng)上“一定正確”。遇到解析爭議時仍應(yīng)回到權(quán)威 DNS 或本地遞歸服務(wù)器做最終裁定。參考文檔文檔頁https://apizero.cn/aidocs/dns-query原始文檔https://apizero.cn/aidocs/dns-query/raw.md