配置解析阶段:
Syntax: resolver address ... [valid=time];
ngx_http_core_resolver()
clcf->resolver = ngx_resolver_create()
• 设置cleanup的handler (ngx_resolver_cleanup)
• 初始化保存域名节点信息的红黑树 (r->name_rbtree)
• 初始化重传和过期队列 (r->name_resend_queue r->name_expire_queue)
• 设置超时事件的handler (ngx_resolver_resend_handler)
• 解析dns server的ip并设置到地址数组 (r->udp_connections)
• 解析参数 (valid, ipv6 等)
请求构造阶段:
proxy_pass http://$host;
ngx_resolver_ctx_t ctx 每次域名解析都会生成这个结构体, 直接malloc,未使用r->pool.
ctx = ngx_resolve_start()
• 如果$host是ip地址, 直接设置ctx->quick = 1, 表示后续逻辑不需要走dns解析逻辑.
• 如果r->udp_connections 不存在, 返回NGX_NO_RESOLVER, 最终请求返回502.
初始化ctx参数
• ctx->type = NGX_RESOLVE_A;
• ctx->handler = ngx_http_upstream_resolve_handler;
• ctx->timeout = clcf->resolver_timeout;
• ngx_resolve_name(ctx)
• 如果 ctx->quick == 1, 直接调用 ctx->handler, 跳过dns解析.
• 否者调用 ngx_resolve_name_locked, 执行dns解析.
• ngx_resolve_name_locked(r, ctx)
1 调用ngx_resolver_lookup_name查找域名节点rn是否在r->name_rbtree缓存节点中, 存在进入(2), 否者进入 (5)
2 判断rn->valid是否过期,没有过期进入(3), 否者进入(4).
3 如果存在 rn->naddrs, 是A记录节点, 循环调用rn->waiting链表上的 ctx->handler, 然后函数返回OK; 如果不存在 rn->naddrs, 表示是CNAME记录节点, 那么递归调用ngx_resolve_name_locked,进入步骤 (1).
4 rn->valid已经过期, 如果存在rn->waiting, 表示已经触发了新的dns请求, 只需要把ctx挂在到链表上, 函数返回NGX_AGAIN. 如果不存在rn->waiting,表示这是域名失效之后的第一个请求, 需要清空上一次dns请求申请的内
存, 进入 (6)
5 不存在rn, 表示第一次域名请求, 初始化rn节点, 并加入 r->name_rbtree红黑树.
6 创建域名查询请求 ngx_resolver_create_name_query
7 发送域名查询请求 ngx_resolver_send_query, 并设置dns查询的读事件 uc->connection->read->handler = ngx_resolver_read_response
8 挂载超时事件 ngx_add_timer(ctx->event, ctx->timeout) ctx->event->handler->ngx_resolver_timeout_handler
9 函数结束, 返回NGX_AGAIN.
dns域名查询的发送请求阶段完成, 接下来请求将等待事件触发.
事件触发阶段:
DNS查询可读事件 ( ngx_resolver_read_response )
1 读事件触发, 调用ngx_resolver_read_response
2 最终调用到 ngx_resolver_process_a.
3 如果是A记录, 设置rn的ip地址, 并循环调用 ctx->waiting的handler, 把堆积的请求都处理完, 函数返回.
4 如果是CNAME记录, 将rn->waiting链表中的ctx循环调用ngx_resolve_name_locked, 继续进行dns解析流程.
超时事件 ( ngx_resolver_timeout_handler )
1 如果在ctx->timeout (resolver_timeout) 时间内没有可读事件, 将触发 ngx_resolver_timeout_handler.
2 该函数将 ctx->state = NGX_RESOLVE_TIMEDOUT, 并调用 ctx->handler,handler会判断ctx->state,返回502.
请求结束阶段:
ngx_resolve_name_done(ctx) 每个请求在结束的时候会调用
• 如果关闭了请求的时候还没有域名解析超时, 删除定时器. ngx_del_timer(ctx->event)
• 如果ctx存在于rn->waiting链表中, 从链表中删除ctx.
• 释放ctx分配的内存.
• 调用ngx_resolver_expire, 遍历r->name_expire_queue队列删除r->name_rbtree中的过期rn.
DNS异步重传阶段: (跟请求无关)
重传函数 ngx_resolver_resend_handler
• 遍历r->name_resend_queue链表, 如果存在rn->waiting, 表示还有请求在等待域名解析结果, 需要重新发送域名请求(ngx_resolver_send_query); 否则就从r->name_rbtree中删除rn节点.
• 重新挂载超时定时器, 等待下次重传事件.
重传队列和过期队列:
• r->name_expire_queue 过期队列 每次域名查询之后都会更新时间 rn->expire = ngx_time() + r->expire (30s)
• r->name_resend_queue 重传队列 每次域名重传之后都会更新时间 rn->expire = ngx_time() + r->resend_timeout (5s)
rn必在其中一个队列: 初始化时构造DNS请求, 在resend队列, 在DNS解析成功之后, 放入expire队列. 如果ttl过期了, 将从expire队列删除, 放入resend队列, 构造新的DNS请求....
rn->waiting 在nginx启动或者域名过期, 等待dns查询结果返回的过程中, 请求这个域名的请求(ctx)都将挂载在这个队列上.等查询结果返回之后, 循环调用链表中每个请求的handler.如果在查询结果返回之前请求就因为其他原因终止了, 请求会通过调用ngx_resolve_name_done把自己从链表中删除.
感谢田阳的整理,http://note.youdao.com/share/?id=397ef05d764de5aaa5b8f33ecf528d3c&type=note
相关推荐
最近碰到一个问题就是nginx转发到另一个nginx...发现使用test1.sg.com访问IP地址不一样,原来是后面域名解析地址改变了,但没有重启nginx,导致dns缓存存在使用原来老的IP地址,(热)重启nginx就可以了 nginx -s reload
可以指定多个 DNS 并重置域名 TTL 延长 nginx 解析缓存来保障解析成功率: 代码如下: resolver 223.5.5.5 223.6.6.6 1.2.4.8 114.114.114.114 valid=3600s; 如果还有解析错误,可以用 dnsmasq 在本地自建 DNS,顺带...
然而,当这些IP发生变更时,Nginx不会自动更新其内部的DNS解析,导致请求无法正确路由到新的IP。为了解决这个问题,我们可以编写一个Shell脚本来定期检查IP变化并自动执行`nginx -s reload`命令来强制Nginx重新加载...
- **测试 DNS 解析**:可以使用 `nslookup` 或 `dig` 命令来测试域名是否成功解析到对应的 IP 地址。例如: ```bash nslookup mgcrazy.com nslookup www.mgcrazy.com ``` ##### 2. Nginx 配置 - **编辑 Nginx ...
- **DNS查询**:使用`nslookup`或`dig`命令验证DNS解析是否正确。 - **HTTP/HTTPS访问**:通过浏览器访问各个域名,确认内容正确显示,同时检查HTTPS连接的安全性。 完成这些步骤后,你将拥有一个能够通过域名...
这里的`nameserver`指向了一个DNS服务器地址,用于处理域名解析请求。此外,还给出了一个`/etc/hosts`文件的部分内容: ```bash 172.31.68.52 www.wg.com ``` 这表示将`www.wg.com`这个域名映射到了IP地址`172.31.68...
通过在Nginx中正确配置多个域名和协议监听,可以为网站提供稳定、安全、高效的网络服务。在实际应用中,应该结合具体的服务器配置和网络安全策略,来优化Nginx的设置,以达到最佳的性能和安全效果。
在Nginx中配置中文域名是一项特殊的任务,因为传统的DNS系统并不直接支持中文域名的解析。中文域名在互联网上的实际应用需要通过Punycode编码技术进行转换,以确保其能在全球范围内正确解析和访问。以下是对Nginx中...
在DNS解析生效后,通过浏览器访问域名,就能看到Nginx服务器响应的页面。 总的来说,绑定域名到Nginx服务是一个相对简单的过程,但需要对Nginx的配置文件结构和指令有充分的理解。掌握以上内容后,可以实现将多个...
- 设置客户机的DNS首选服务器为`192.168.1.254`,以便正确解析域名。 **十一、客户机上分别通过两个域名访问 HTTPD 和 Tomcat** - 最终用户可以通过以下域名访问相应的服务: - `http://www.benet.com`:访问...
然而,配置过程中可能遇到各种问题,如DNS解析失败、Web服务器未响应等,这时需要检查相关配置文件、网络连接及服务器状态,确保一切正常。同时,了解和遵循最佳实践,如使用SSL/TLS加密、定期备份DNS记录,以确保...
#### DNS 域名解析流程概述 DNS(Domain Name System,域名系统)是互联网的一项服务,用来实现域名到 IP 地址之间的转换。下面是对 DNS 解析过程的详细解释: 1. **浏览器缓存检查**:浏览器首先检查其缓存中是否...
- 监控DNS解析速度和稳定性,确保用户体验。 6. **文件名称解析** - `说明.htm`:可能包含DNS配置的详细步骤或常见问题解答。 - `如何配置dns系统虚拟域名的配置和设置方法.pdf`:这应该是一个详细的PDF指南,...
nginx上游动态服务器一个nginx模块,用于解析上游内部的域名并保持最新状态。 默认情况下,仅在nginx启动时才解析在nginx上游中定义的服务器。 该模块为server定义提供了附加的resolve参数,可用于异步解析上游域名...
标题“根据ip进行域名跳转”所涉及的核心知识点包括IP识别、DNS解析和服务器配置。 首先,我们要理解IP地址是互联网上每个设备的唯一标识,而域名则是便于人们记忆的友好名称。当用户在浏览器中输入域名时,DNS...
4. 分配相应的 DNS 解析记录,确保各层代理之间的通信可以正确进行。例如: ``` mail.first.com -> 21.67.38.47 host.second.com -> 187.50.112.135 oa.finalc2.com -> 208.36.69.66 ``` 5. 使用外部监听器...
同时,需要配置`resolver`以指定DNS服务器,用于解析从内部网络收到的域名请求,获取目标服务器的IP地址,然后将请求转发到正确的外部服务器。 例如,配置文件中可能包含如下内容: ```nginx server { listen 80 ...
**DNS 解析过程** - 首先查看本地 hosts 文件,如果找不到对应 IP,则向 DNS 服务器发起请求,最终获得目标服务器的 IP 地址。 总之,Nginx 是一款功能强大的网络服务器,广泛应用于各种场景,通过深入学习和实践...
确保每个项目都有独立的域名,这可以通过DNS解析或者在本地`/etc/hosts`文件中映射。例如,`vue.example.com`指向Vue.js项目,`java.example.com`指向Java项目。这样,当用户访问不同的域名时,Nginx会根据配置将...