NGINX proxy_pass 域名解析问题
前两天发现一个问题,当使用proxy_pass的时候,发现域名对应IP是缓存的,这样一旦VIP变化之后,就会报错,下面就来详细分析一下这个问题。
一、问题说明
location = /test { internal; no_error_pages; proxy_pass_request_headers off; proxy_pass 'http://www.taobao.com/test/router/rest'; }
大家应该知道,这是向http://www.taobao.com/test/router/rest发送请求,其实是向202.108.250.251发送请求
ping www.taobao.com PING scorpio.danuoyi.tbcache.com (202.108.250.251): 56 data bytes 64 bytes from 202.108.250.251: icmp_seq=0 ttl=54 time=4.324 ms 64 bytes from 202.108.250.251: icmp_seq=1 ttl=54 time=8.320 ms
如果在服务的过程中突然www.taobao.com对应的IP变化了(这是非常常见的,因为taobao.com对应多个域名),那么NGINX仍然会访问以前的IP202.108.250.251,这是为什么呐?下面咱们就来分析一下。
二、HTTP模块
打开NGINX的源代码,搜索proxy_pass,发现在文件:src/http/modules/ngx_http_proxy_module.c实现了这个方法
static char * ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
......
}
那么,继续往下看
1、url = &value[1]; //获取url
2、ngx_memzero(&u, sizeof(ngx_url_t));
3、plcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
用gdb分析,发现ngx_http_upstream_add()函数在文件src/http/ngx_http_upstream.c里面。代码如下:
4682 ngx_http_upstream_srv_conf_t * 4683 ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags)
............................................................ - 4692 if (ngx_parse_url(cf->pool, u) != NGX_OK) { 3 4693 if (u->err) { 3 4694 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"%s in upstream \"%V\"", u->err, &u->url); 3 4696 } 3 4698 return NULL; 3 4699 }
.............................................................
4、ngx_parse_url,它实在文件core/ngx_inet.c里面,下面是调用的顺序
- ngx_parse_url()调用ngx_parse_inet_url()
- ngx_parse_inet_url()调用ngx_inet_resolve_host()
- ngx_inet_resolve_host()调用gethostbyname()
- gethostbyname()函数就是通过域名获取IP的函数
三、问题解决
未完,待续。。。