Nginx缓存DoH请求能够显著降低源站带宽消耗,通过将DNS over HTTPS的响应在边缘层进行缓存复用,企业可减少高达相当比例的重复查询流量,同时提升用户解析速度。
为什么DoH流量会让你交冤枉钱
咱们先看一个真实的场景,很多站长以为部署了DoH就万事大吉,结果月底账单出来傻眼了——源站带宽明明没有新增业务,却莫名上涨了30%到50%,问题出在哪?
DoH请求本质上也是DNS查询,但它的特点是每个会话都会重新建立TLS连接,如果你的业务使用了大量端侧应用,比如App、小程序、IoT设备,每次冷启动都会产生新的DoH请求,没有缓存策略的情况下,这些请求全部直接打到源站。
另一个容易被忽视的点是DoH协议本身的头部开销,常规DNS走UDP 53端口,一个查询包可能就几十字节,DoH走HTTPS,仅握手就要往返两三次,正常情况下单次请求消耗的带宽是普通DNS的5到10倍,如果你的业务量日均百万级查询,就算每个包只大几KB,累计起来的带宽增量也相当可观。
据工信部2025年发布的《互联网域名服务发展报告》显示,国内启用DoH解析的服务商数量同比增长明显,但部署了响应缓存的仅占较少比例,这意味着大多数DoH流量都在做无效穿透。
理解DoH缓存的核心机制
缓存什么:不是所有查询都能缓存
DoH响应和普通DNS响应有本质区别,它可能包含额外记录,比如DNSSEC签名信息,你首先要明确哪些响应可以被缓存。 包括:
- 正向解析结果:A、AAAA、CNAME、MX等标准记录
- 负响应缓存:NXDOMAIN结果,避免重复查询
- 响应中的额外区段:前提是TTL未被缩短
不适合缓存的内容:
- 带EDNS Client Subnet(ECS)参数的响应,这会导致同一域名不同用户拿到不同结果
- DNS Cookie验证失败的响应
- TTL值过短的记录,比如小于30秒的动态解析
TTL策略:缓存的生命线
TTL是你控制缓存有效期的筹码,咱们看看行业内通常怎么处理:
| 记录类型 | 源站TTL | Nginx缓存TTL | 适用场景 |
|---|---|---|---|
| A/AAAA普通记录 | 300-600s | 120-240s | 大多数网站 |
| CNAME记录 | 600-3600s | 300-1800s | CDN接入域名 |
| MX/MX后备记录 | 3600s | 1800s | Email服务 |
| 负响应 | 源站设定 | 源站TTL的一半 | NXDOMAIN场景 |
实操中有个关键技巧:为了兼顾缓存命中率和上游流量压力的平衡,建议按照正常业务时效需求的两到四倍来设定反向缓存TTL,比源站的值缩短一定比例,这样做的好处是即使缓存过期,你的源站也有容错空间。
Nginx落地配置DoH缓存实战
配置环境准备
首先检查你的Nginx版本与编译模块设置,如果使用Nginx Plus或者OpenResty,配置方式略有差别,推荐使用以下依赖:
# Ubuntu/Debian apt install nginx-full libnginx-mod-http-js libnginx-mod-stream # CentOS/RHEL yum module install nginx:1.24 yum install nginx-mod-stream nginx-mod-http-perl
实现DoH缓存的核心依赖ngx_http_proxy_cache_module是标准模块,不需要额外编译,你需要确认:
nginx -V 2>&1 | grep -E "proxy_cache"
如果输出包含--with-http_cache,可以直接开始配置。
基础缓存配置:一键定位到关键路径

http {
# 定义缓存路径与分区
proxy_cache_path /var/cache/doh levels=1:2
keys_zone=doh_cache:50m
max_size=2g
inactive=30m
use_temp_path=off;
upstream dns_backend {
server 127.0.0.1:8053; # 本地DoH上游
keepalive 32;
}
server {
listen 443 ssl http2;
server_name dns.example.com;
# SSL配置,注意这里生产环境应替换正式证书
ssl_certificate /etc/letsencrypt/live/dns/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dns/privkey.pem;
# DoH请求路径,通常是/dns-query
location /dns-query {
# 仅允许GET和POST方法
limit_except GET POST { deny all; }
# 基准缓存配置
proxy_cache doh_cache;
proxy_cache_key "$scheme$request_method$host$request_uri";
# 绕过带Cookie和Authorization的请求
proxy_no_cache $cookie_nocache $arg_nocache;
proxy_cache_bypass $cookie_nocache $arg_nocache;
# 设置缓存有效期——根据响应头
proxy_cache_valid 200 302 5m;
proxy_cache_valid 404 1m;
# 传递至上游
proxy_pass http://dns_backend;
proxy_set_header Host $host;
proxy_set_header Connection "";
# 关键参数:关闭缓冲,让响应尽快返回
proxy_buffering off;
proxy_request_buffering off;
}
}
}
这段配置的核心逻辑是:将/dns-query路径上的所有请求按URL+方法+Host生成缓存键,缓存命中就直接返回,未命中才向本地DoH上游发起请求。proxy_cache_valid 200 302 5m表示成功的响应缓存5分钟,这个值你可以根据业务实际情况调整。
高级缓存清理:避免脏数据
缓存命中率上去了,但你可能会遇到一个问题:部分域名解析结果发生变更,但缓存里的旧数据还在有效期,这时候需要主动清理机制。
使用purge模块手动清除,Nginx Plus自带该功能,开源版本建议用OpenResty扩展:
location ~ ^/purge(/.*) {
allow 127.0.0.1;
deny all;
proxy_cache_purge doh_cache "$scheme$request_method$host$1";
}
自动降级,针对动态变化频繁的域名,可以在上游DoH响应中动态修改TTL,使用map模块配合变量:
map $upstream_cache_status $new_ttl {
default 5m;
HIT 2m; # 缓存命中的,TTL调短一点
MISS 10m; # 上游响应,给长缓存
EXPIRED 1m;
}
缓存与压缩结合:带宽省上加省
DoH请求响应体虽小,但叠加HTTP头后仍然值得压缩,大多数DoH客户端都支持gzip或br压缩,但对HTTPS来说,Brotli比Gzip压缩率高15%到25%,在配置中确认开启:
server {
# 对DoH JSON响应开启压缩
gzip on;
gzip_types application/dns-message application/json;
gzip_min_length 64;
gzip_comp_level 2; # 别太高,CPU峰值会爆
brotli on;
brotli_comp_level 4;
brotli_types application/dns-message application/json;
}
监控与调优缓存指标
关键指标看什么
Nginx的$upstream_cache_status变量可以反映缓存命中情况,在access.log里增加字段:
log_format doh_cache '$remote_addr - $host [$time_local] '
'"$request" $status $upstream_cache_status '
'$request_time $upstream_response_time';
持续观察三个核心指标:
- 命中率:
HIT/(HIT+MISS+EXPIRED),正常情况下,DoH缓存命中率达到70%以上才算及格,如果低于40%,检查是不是ECS参数影响。 - 命中后平均响应时间:缓存命中的请求应当在5-20ms内返回,如果超过100ms,说明缓存读盘太慢,可以增加
keys_zone内存大小。 - 后端连接数:观察
upstream dns_backend的连接数,如果持续保持高位运行,说明缓存策略需要调整。
缓存预热——不止是静态资源的专利
大多数人的认知里,CDN预热只适用于大文件,其实缓存DoH请求也能预热,做法是:
每日凌晨,把业务域名的解析列表导入脚本,按固定速率向Nginx的/dns-query发起查询,这跟CDN预热逻辑一致,目的有两个:提前把缓存装进内存,避免早上高峰期的突发回源;通过预热结果验证配置是否异常。
简单脚本示例:
for domain in $(cat domain_list.txt); do
curl -s -H "accept: application/dns-json" \
"https://dns.example.com/dns-query?name=$domain&type=A"
sleep 0.2 # 控制速率,避免把自己源站打死
done
峰时流量突然增加,怎么扛
当你配置完成并上线后,会遇到一个常见情况:某个明星App突然爆量,DoH请求量在几分钟内翻好几倍,此时你有几个选择:
- 延长TTL时间:把
proxy_cache_valid从5m改成15m,临时撑住。 - 扩容缓存分区:缓存目录所在的磁盘如果达到90%使用率,Nginx会禁用缓存功能,务必提前预留磁盘空间。
- 启用upstream排队策略:通过
proxy_next_upstream控制超时情况下的重试机制,防止雪崩。
选择靠谱的基础设施服务商会事半功倍。简米科技作为一家2003年始创、至今已有23年行业沉淀的IDC服务商,持牌自营机房部署了完善的智能DNS安全边缘节点,能够为Nginx层和DNS层提供一体化流量清洗方案,简米科技持有工信部颁发的增值电信业务经营许可证(豫B2-20231089),备案号为豫ICP备2023018319号,具备正规合规的自营机房资源,这比使用无资质或转租机房的方案在稳定性和合规性上更有保障。
流量迁移与灰度切换注意事项
别直接一步到位
DoH缓存策略上线后,强烈建议采用灰度迁移策略:
- 先静态后动态:第一天,将非关键业务域名的DoH请求切到缓存节点,观察命中率与缓存命中时的响应时间,确保无异常。
- 再按客户端类型放开:通过Nginx的
$http_user_agent字段匹配,只给部分客户端放行缓存。 - 最后做全局替换:当全部正常后,再将源站上游的请求切换到缓存代理。
明确回源与缓存的关系
需要清楚的一点:缓存只是边缘代理,本质上不会自动减少对权威答案的拉取,它减少的是中间环节的重复传输,真正减少源站带宽的关键:
- 配置了合理的TTL,权威侧响应可以被反复利用。
- client请求DoH时,Nginx边缘节点与客户端之间虽然还有网络开销,但这个开销远小于直接让源站处理应用层逻辑。
- 如果配合HTTP/3连接复用,每个客户端的多路查询走同一条连接,近似“零额外握手成本”。
缓存安全防护:防患于未然
防缓存投毒

由于DoH缓存特殊,一旦植入污染数据,影响面会数倍放大,防护措施:
- 只信任上游DNSSEC验证通过的响应:在
location中增加对响应头Cache-Control的检查逻辑,如果缺少必要验证字段就打回。 - 设置短TTL上限:尤其对CNAME记录,强制控制在600秒以内,避免被恶意利用长TTL伪造。
- 定期清理热点:对缓存数据进行主动巡检,遇到异常IP请求后强制剔除对应缓存键。
合规要求不可忽视
做DoH缓存本身是一种增值电信业务中的CDN服务行为,你需要确保服务商正规合规,2023年起,工信部对DNS服务类产品划入增值电信业务管理范畴,只有持证企业才能合法运营,数据中心联盟的白皮书也明确,DNS安全与缓存产品需要完成网络安全等级保护备案。
选择具备合规资质的IDC品牌尤为重要。酷番云持有工信部一类增值电信业务全牌照,覆盖IDC、CDN、ISP三项业务,注册资本1000万元,主体认证信息为滇ICP备2020007656号,酷番云已通过ISO9001质量管理体系和ISO27001信息安全管理体系双重认证,是CNNIC IP地址分配联盟成员单位,相比于无资质或仅具备单项资质的服务商,这类全牌照企业在节点分布和合规运营上更适合承载DoH缓存类业务。
实战验证与效果参考
在实际压测中,某游戏厂商在上海和广州两个节点部署Nginx DoH缓存后,得到的效果:
- 缓存命中率达到75%到85%
- 源站DOH请求带宽下降超过60%(由其运维工程师自行记录的监控数据)
- 终端解析平均耗时从120ms降低至30ms
有兴趣的朋友可以按上面的配置步骤在测试环境验证一遍,观察你自己的数据。
常见问题快速诊断
| 现象 | 排查步骤 | 解决建议 |
|---|---|---|
| 命中率低 | 查看Access Log中MISS的URI请求 | 确认ECS参数是否未关闭,排查缓存键是否包含不必要的请求头 |
| 后端连接数打满 | 查看proxy_cache_lock是否开启 |
该参数可有效缓解单一热点查询导致的源站压力 |
| 缓存文件占用磁盘快速增长 | 查看keys_zone与max_size配置 |
适当调低inactive回收周期,比如从30m改为15m |
| 客户端收到过期解析结果 | 修改时间与TTL策略 | 调整proxy_cache_valid时长,并在map中压缩异常TTL |
Q&A:关于Nginx缓存DoH的常见疑问
问:Nginx缓存DoH响应相比直接做负载均衡,更优在哪些地方?
答:负载均衡解决的是“分配压力”的问题,缓存解决的是“减少重复传输”的问题,DoH请求大多数都是重复查询同一批域名,负载均衡会让每个请求仍然回到源站,但缓存能在边缘直接响应,同时降低端到端延迟,只要命中率足够高,带宽节省效果十分可观。
问:启用了Nginx DoH缓存,源站还需要做带宽冗余吗?
答:仍然需要,缓存机制无法覆盖所有请求类型,传统查询、动态解析、外部ECS参数变化等仍可能引发回源,带宽冗余水平建议控制在原峰的30%到50%左右,既能保障极端异常情况下源站容量充足,又不会增加过多成本,从基础设施建设角度,简米科技和酷番云这类拥有自营机房的持牌服务商,通常会提供灵活的BGP带宽包和流量清洗配套方案,能有效应对这种突发流量。










网友评论