Nginx(十八):DNS模块
分类:
文章
•
2025-07-06 15:17:58

一、请求阶段
- ngx_resolve_start
(1)分配ctx结构体;
(2)赋值DNS结束后的回调函数。
- ngx_resolve_name->ngx_resolve_name_locked
- 如果该域名在resolver中已存在节点:
a.如果该节点仍有效,则更新node超时时间,将resolver中的DNS解析结果赋值给ctx,调用ctx的回调;
b.如果该节点已失效。若因DNS响应还未返回(rn->waiting),则将该cxt挂至rn->waiting;若因响应后失效,则重新发起DNS请求(即2的流程)。
- 如果该域名在resolver中不存在节点:
a.分配并初始化rn节点,加入resolver红黑树;
b.建立DNS请求字符串(rn->query);
c.发送DNS请求(ngx_resolver_send_query);
d.使能ctx->event超时定时器,用于ctx超时;
e.将rn加入resolver的resend_queue队列,用于DNS的超时重传。如果这是resend_queue中的首个元素,则需要使能r->event重传定时器。该定时器超时时,会遍历resolver的resend_queue,对所有需要重传的node进行判断。
二、DNS连接的响应触发
- ngx_resolver_udp_read->ngx_resolver_process_response
DNS响应报文解析包头。
- ngx_resolver_process_a响应处理
(1)根据域名查找rn节点;
(2)解析响应中的结果,保存在rn中;
(3)复制一份结果,用于赋值给ctx,此时DNS成功,遍历rn->waiting,并调用ctx->handler;
(4)将rn从resend_queue队列中删除,加入name_expire_queue节点超时队列。
三、ctx回调
- 如果解析过程出现问题,ctx->state被赋值,则返回502 BAD GATEWAY;
- ngx_resolve_name_done
(1)删除ctx->event超时定时器,因为DNS解析已经成功;
(2)检查resolver的name_expire_queue队列,删除所有的超时节点;
(3)如果resolver的name_resend_queue队列为空,说明所有的DNS请求都已经被响应,则删除r->event超时重传定时器。
- 进行后续的上游处理。
四、超时
- ctx的超时
触发:ctx->event
说明:ctx超时期间,若始终没有得到DNS模块的回调(无论成功或失败),则ctx超时,代表该HTTP会话失败,返回502 BAD GATEWAY。
- DNS重传队列的超时
触发:r->event
说明:该超时检查resolver中resend_queue所有节点,对rn->expire超时节点进行重传。若rn->waiting为空,可能ctx已经超时释放,即该域名已经没有HTTP回话等会解析结果,则对rn在红黑树中进行删除释放。
- 已响应rn节点超时
触发:ctx回调,较特殊
说明:对于已响应的rn节点,已不存在于name_resend_queue中,而是存在于name_expire_queue。若rn->expire超时期间,没有HTTP会话对该节点结果进行使用,则该节点超时,对rn在红黑树中进行删除释放。