NGINX在配置上游服务器时支持域名配置。根据不同的配置,NGINX提供了两种方法:静态和动态分析。本文尝试分析如何从代码级别实现动态DNS分析。
A。静态分析
作为上述配置,在运行和运行NGINX时,/etc/hosts和/etc/resolve.conf中的主机和DNS服务器将使用机器和DNS服务器到域名http://private.server1.com。
如果分析失败,则无法成功启动NGINX。获得的IP地址将始终伴随着NGINX的整个生命周期。如果在运行期间域名的IP地址更改,则该服务将中断。唯一的解决方案。是重新启动nginx。
b。动态分析
NGINX的开源版本为解析器提供了动态DNS解决方案。核心思想是NGINX本身充当DNS客户端的动态DNS分析。
如果上述配置,则在访问服务器的根目录时,请求将转移到由测试变量定义的服务器。此外,服务器http://private.server1.com.cn由此测试变量定义为通过解析器定义的DNS服务器动态解析。
在此配置中,通过解析器获得的分析结果有效期为10秒。有效期后,当再次访问根目录时,将更换域名。
应该注意的是,如果代理_pass是域名,而不是背后的变量,那么对域名的分析也发生在分辨率期间,并且无法完成动态域名分析功能。
动态域名分析是通过分辨率指令和变量实现的。指令分辨率可以在HTTP范围内全局设置,也可以在某个服务器甚至某个局部设置中分别设置。
.8.8和114.114.114.114。此外,两个DNS服务器分辨率的结果不能在根目录和/poplate/Directory上共享。
指令解析器的配置语法为:Resolver 114.114.114.114 8.8.8值= 10S IPv6 = off;
此配置指定两个DNS服务器114.114.114.114和8.8.8.8。这两个DNS服务器将依次使用,而不是使用主巩固的角色。
如果不可用DNS服务器,您将尝试另一项DNS服务,直到有DNS服务器返回分辨率结果为止。没有记录返回结果是成功还是失败,将采用它。
即使失败了,您也不会尝试其他DNS服务器。此外,如果由于网络原因而暂时不便,则原始DNS过期的缓存无法重复使用。
参数值指定分析结果的有效期。
参数IPv6用于指示是否接收了分辨率结果中的IPv6地址。对于IPv6的配置,默认值已打开,也就是说,域名被解析为现有
当IPv4具有IPv6时,它将被解析。IPV6可以由IPv6 = ON |控制离开。
与解析器相关的数据结构如下所示。主要相关数据结构是:
从这种数据结构关系中,我们可以看到当HTTP请求需要动态DNS解析时,如何连接主数据结构。
有了数据结构的一般概念,我们将在下面尝试分析代码级别的整个解析器的工作流程和工作原理。
有两个指令与动态DNS解析功能有关:proxy_pass和Resolver。
A。在配置阶段,与解析器指令相对应的分析函数为NGX_HTTP_CORE_RESOLVER。该函数将生成NGX_RESOLVER_T结构并连接NGX_HTTP_CORE_CORE_CORE_COREF_CONF_TINGEL,该结构与本地相通用。如上图所示。如上图所示。
b。对应于指令proxy_pass的分析功能是ngx_http_proxy_pass。
如果代理 - 通行证背后的参数不是变量,则上游主机的IP地址将在配置解析阶段中解析并生成上游结构,并连接到NGX_HTTP_PROXY_LOC_LOC_CONF_CONF_T中的NGX_HTTP_HTTP_HTTP_HTTP_HTTPEREAM结构。
同时,设置HTTP_Proxy模块的处理函数为NGX_HTTP_PROXY_HANDLER.AS如上图B所示。当HTTP处理每个模块的回调功能时,调用了此功能。
2.数据水平
当NGINX接收客户端请求,然后连接到上游上游服务器时,就会发生动态DNS分析。
在下面,我们分析了从NGINX接收客户请求的完整过程,以接收到DNS域名并完成连接的客户请求。
2.1。
A。当客户发送TCP连接请求时,NGX_EPOLL_PROCESS_EVENTS返回listerfd可读事件,并调用NGX_EVENT_ACCESS函数接收客户端请求。然后调用相应的侦听插座功能NGX_HTTP_INIT_CONNECTION函数http procestion in ngx__http_ngx_htpp_htpp_htpp_htppp_htpp_htpp_htpp_htpp_htpp_htp_http_http在ngx_http_optimize_servers函数中。
b。在函数ngx_http_init_connection中,生成ngx_http_connection_t结构HC。然后找到相应的服务器地址,并分配给HC的Addr_conf property.fin,以将恢复功能设置为对应于读取的连接并写入ngx_http_wait_request_request_request_request_ernywer.hhtler和ngxrler和ngxhtler和ngxhtler和ngxhtler和ngxhtller和ngxhtter和事件,将调用函数NGX_HTTP_WAIT_REQUEST_HANDLER。
C。函数NGX_HTTP_WAIT_REQUEST_HANDLER通过NGX_HTTP_CREATE_REQUEST.TRES创建http request(r),在同一时间设置读取事件的恢复函数to ngx_http_process_requsess_request_line.s nly nly the data the will beanly the will nlline tire nlline tire time time time tire tire tireppr at ingx_httproct,还要调用函数ngx_http_process_request_line来处理已接收的请求。
F。函数,调用HTTP Multi -stage处理的NGX_HTTP_CORE_RUN_PHASES。功能NGX_HTTP_HANDLER还将http request(r)的write_event_handler设置为ngx_http_http_core_run_phastes。
G。
2.2。
如上所述,有一个普通NGINX HTTP请求的处理过程。直到现在,HTTP的处理逻辑已达到每个模块本身的处理。相应的动态DNS相应的处理功能是NGX_HTTP_PROXY_HANDLER.BELOW,我们从此处理功能开始,并分析和分析功能和分析功能开始如何实现动态DNS分析。
A。相应变量的特定值。然后将此信息存储在HTTP请求(R)上游的分辨率的分辨率变量中。
b。
C。在函数ngx_http_read_client_request_body中,在处理请求主体后,ngx_http_upstream_init函数将初始化上游服务器。在同一时间,http requst(r)read_event_handler和writ_event_handler and writ_event_handler receadler receaid receaid receaid。
d。函数ngx_http_upstream_init将调用ngx_http_upstream_init_request。
函数NGX_HTTP_UPSTREAM_INIT_REQUEST首先检查在HTTP请求(R)上游解决的返回是否已解析为IP地址。与我们分析的情况相对应,当前主机仍然是域名,而不是IP地址。此时,函数ngx_http_upstream_init_request将调用ngx_resolve_start启动房屋的域名分析。在这一点上,真实的动态DNS分析逻辑是正式触发的。
e。函数ngx_resolve_start将生成ngx_resolver_ctx_t.t.t.在同一时间的数据结构CTX,将CTX的分辨率设置为相应位置结构NGX_HTTP_CORE_CORE_LOC_LOC_CONF_T的分辨率成员。该成员是在配置解析期间生成的。此CTX处理程序设置为NGX_HTTP_UPSTREAM_RESOVE_HANDLER.FINALLY,此CTX结构与HTTP请求(R)中上游的分辨率中的CTX变量相关联。
F。函数ngx_http_upstream_init_request通过ngx_resolve_start_tart创建ngx_resolver_ctx_t结构,ngx_resolve_name_locked将通过ngx_reslove_name_locked来调用ngx_resolve_name。
G。函数ngx_resolve_name_locked逻辑过程如下:
如果域名已经存在于解析器中:
我。如果节点仍然有效,请更新节点超时,请分配Resolver中的DNS分辨率结果到CTX,请调用CTX的回调NGX_HTTP_HTTP_UPSTREAM_RESOVE_HANDLER。
ii。如果节点失败。如果尚未返回DNS响应(rn->等待),则cxt将悬挂在rn->等待中;如果由于响应而失败,则再次启动DNS请求。
如果在解析器中不存在域名:
我。分配和初始化RN节点,然后添加解析器红色和黑树。
ii。建立DNS请求字符串(RN->查询)。
iii。发送DNS请求(ngx_resolver_seery/ngx_resolver_send_tcp_qury/ngx_resolver_send_query)。
iv。
v。将RN添加到解析器的resend_queue队列中以重新连接dn的超时。如果这是resend_queue中的第一个元素,您需要启用r->事件来重新传输计时器,当计时器是超时,它是Trawer travers resend_queue的解析器来判断所有需要传输的节点。
H。ngx_resolver_udp_read的相应插座读取事件。
我。当DNS响应软件包到达时,通过ngx_resolver_process_response.ngx_resolver_udp_read将使用响应数据包处理函数NGX_RESOLVER_PROCESS_RESPOSES CALD ngx_RESOLVER_RESOLVER_RESOLVER_PROCESS_A处理V4和V6地址与DOMAIN名称。
j。函数ngx_resolver_process_a将首先根据域名找到RN节点,然后将解析响应的结果存储到RN中。在同一时间,该副本的结果分配给NGX_RESOLVER_CTX_T CTX CTX。rn->等待并称为ctx->处理程序,它是ngx_http_upstream_resoleve_handler.handler.handler.handler函数。
k。功能NGX_HTTP_UPSTREAM_RESOVE_HANDLER首先调用NGX_HTTP_UPSTREAM_CREATE_ROBIN_PEER以初始化http request(r)的上游服务器。
到目前为止,整个DNS分析过程已经完成,分析结果已成功地用于连接上游服务器。
NGINX的开源版本为动态DNS解析提供了一定的支持。通过分析源代码,我们会发现该机制仍然有限。例如,只能通过通过Proxy_pass添加变量来实现。
此外,每个工作过程都需要独立执行DNS分析,并且结果无法共享。
与开源版本的原始生态NGINX相比,我们可以使用Nginx Plus或许多第三方模块来实现越来越多的实用动态DNS分析功能。
作者:Pipiru
资料来源:NGINX开源社区