nginx's DNS resolves domain names

Configuration parsing phase:
Syntax: resolver address ... [valid=time];
ngx_http_core_resolver()
clcf->resolver = ngx_resolver_create()
• Set the handler for cleanup (ngx_resolver_cleanup)
• Initialize the red-black tree (r->name_rbtree) that saves domain name node information
• Initialize retransmission and expiration queues (r->name_resend_queue r->name_expire_queue)
• Set the handler for timeout events (ngx_resolver_resend_handler)
• Resolve the ip of the dns server and set it to the address array (r->udp_connections)
• Parse parameters (valid, ipv6, etc.)
 
Request construction phase:
proxy_pass http://$host;
ngx_resolver_ctx_t ctx will generate this structure every time the domain name is resolved, directly malloc, not using r->pool.
ctx = ngx_resolve_start()
• If $host is an ip address, directly set ctx->quick = 1, which means that the subsequent logic does not need to go through the dns parsing logic.
• If r->udp_connections does not exist, NGX_NO_RESOLVER is returned, and the final request returns 502.
Initialize the ctx parameter
• ctx->type = NGX_RESOLVE_A;
• ctx->handler = ngx_http_upstream_resolve_handler;
• ctx->timeout = clcf->resolver_timeout;
• ngx_resolve_name(ctx)
• If ctx->quick == 1, call ctx->handler directly, skip dns resolution.
• Otherwise, call ngx_resolve_name_locked to perform dns resolution.
• ngx_resolve_name_locked(r, ctx)
1 Call ngx_resolver_lookup_name to find out if the domain name node rn is in the r->name_rbtree cache node, if it exists, enter (2), otherwise enter (5)
2 Judge whether rn->valid has expired, enter (3) if it does not expire, and enter (4) if not.
3 If there is rn->naddrs, it is an A record node, cyclically call ctx->handler on the rn->waiting linked list, and then the function returns OK; if rn->naddrs does not exist, it means it is a CNAME record node, then recursively call ngx_resolve_name_locked , go to step (1).
4 rn->valid has expired, if rn->waiting exists, it means that a new dns request has been triggered, just hang ctx on the linked list, and the function returns NGX_AGAIN. If rn->waiting does not exist, it means this is a domain name The first request after the invalidation needs to clear the content of the last dns request application
save, enter (6)
5 If rn does not exist, it means the first domain name request, initialize the rn node, and join the r->name_rbtree red-black tree.
6 Create a domain name query request ngx_resolver_create_name_query
7 Send the domain name query request ngx_resolver_send_query, and set the read event uc->connection->read->handler = ngx_resolver_read_response of the dns query
8 Mount timeout event ngx_add_timer(ctx->event, ctx->timeout) ctx->event->handler->ngx_resolver_timeout_handler
9 When the function ends, return NGX_AGAIN.
The sending request phase of the DNS domain name query is completed, and the next request will wait for the event to be triggered.
 
Event trigger stage:
DNS query read event ( ngx_resolver_read_response )
1 read event trigger, call ngx_resolver_read_response
2 Finally call to ngx_resolver_process_a.
3 If it is an A record, set the ip address of rn, and call the handler of ctx->waiting in a loop to process all the accumulated requests, and the function returns.
4 If it is a CNAME record, call ngx_resolve_name_locked cyclically from ctx in the rn->waiting linked list, and continue the dns resolution process.
 
 
Timeout event ( ngx_resolver_timeout_handler )
1 If there is no readable event within ctx->timeout (resolver_timeout) time, ngx_resolver_timeout_handler will be triggered.
2 This function will ctx->state = NGX_RESOLVE_TIMEDOUT, and call ctx->handler, the handler will judge ctx->state and return 502.
 
 
Request end stage:
ngx_resolve_name_done(ctx) will be called at the end of each request
• If there is no domain name resolution timeout when the request is closed, delete the timer. ngx_del_timer(ctx->event)
• If ctx exists in the rn->waiting list, remove ctx from the list.
• Free the memory allocated by ctx.
• Call ngx_resolver_expire, traverse the r->name_expire_queue queue to delete the expired rn in r->name_rbtree.
 
 
DNS asynchronous retransmission phase: (not related to the request)
Retransmission function ngx_resolver_resend_handler
• Traverse the r->name_resend_queue list, if there is rn->waiting, it means that there are still requests waiting for the domain name resolution result, and the domain name request needs to be resent (ngx_resolver_send_query); otherwise, delete the rn node from r->name_rbtree.
• Remount the timeout timer and wait for the next retransmission event.
 
 
Retransmission queue and expiration queue:
• r->name_expire_queue The expiration queue will update the time after each domain name query rn->expire = ngx_time() + r->expire (30s)
• r->name_resend_queue The retransmission queue will update the time after each domain name retransmission rn->expire = ngx_time() + r->resend_timeout (5s)
rn must be in one of the queues: construct a DNS request during initialization, put it in the expire queue in the resend queue, and after the DNS resolution is successful. If the ttl expires, it will be deleted from the expire queue, put in the resend queue, and a new DNS request will be constructed. ...
rn->waiting When nginx starts or the domain name expires, while waiting for the dns query result to return, the request (ctx) for this domain name will be mounted on this queue. After the query result is returned, each request in the linked list is called cyclically The handler. If the request is terminated for other reasons before the query result is returned, the request will delete itself from the linked list by calling ngx_resolve_name_done.
 
 
Thanks to Tian Yang for finishing, http://note.youdao.com/share/?id=397ef05d764de5aaa5b8f33ecf528d3c&type=note

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326490376&siteId=291194637