nginx解析nginx.conf源码流程分析

nginx配置文件内容示例

基本上列出了经常用到的配置项

user  olwaf;
worker_processes  auto;
worker_cpu_affinity  auto;
worker_rlimit_nofile  200000;
error_log  syslog:facility=local3,severity=warn,server=logserver:514,tag=olwaf warn;
error_log  /dev/null warn;
pid  /home/openstack/olwaf/nginx.pid;
events {
accept_mutex  off;
use  epoll;
worker_connections  150000;
}
http {
default_type  application/octet-stream;
sendfile  on;
tcp_nopush  on;
server_tokens  off;
server_info  off;
server_tag  "OLWAF 1.0.0";
keepalive_timeout  300s;
client_header_timeout  5m;
send_timeout  1m;
check_shm_size  50m;
client_body_buffer_size  64k;
large_client_header_buffers  4 32k;
proxy_request_buffering  off;
fastcgi_request_buffering  off;
client_body_postpone_size  64k;
proxy_buffering  off;
proxy_buffer_size  16k;
underscores_in_headers  on;
ignore_invalid_headers  off;
server_names_hash_max_size  40000;
server_names_hash_bucket_size  128;
proxy_connect_timeout  5s;
index  index.html index.htm;
log_format  proxyformat "$time_iso8601 $remote_addr:$remote_port $server_addr:$server_port $upstream_addr $request_time $upstream_response_time $status $upstream_status $request_length $body_bytes_sent \"$request_method $scheme://$http_host$request_uri $server_protocol\" \"$http_referer\" \"$http_user_agent\"";
access_log  syslog:facility=local3,severity=info,server=logserver:515,tag=olwaf proxyformat;
log_not_found  off;
gzip  on;
gzip_http_version  1.0;
gzip_comp_level  6;
gzip_min_length  1024;
gzip_proxied  any;
gzip_vary  on;
gzip_disable  msie6;
gzip_buffers  96 8k;
gzip_types  text/xml text/plain text/css application/javascript application/x-javascript application/rss+xml application/atom+xml application/xml application/json;
proxy_redirect  off;
proxy_buffers  128 8k;
proxy_intercept_errors  off;
limit_req_zone  $binary_remote_addr zone=req50k:30m rate=10000r/s;
req_status_zone  req_server_status "$server_addr:$server_port,$server_name" 50M;
req_status  req_server_status;

server {
listen  10.65.27.212:80 backlog=20480;
allow  10.65.27.212;
allow  127.0.0.1;
deny  all;
access_log  off;
location /check_healthcheck_status {
check_status  csv;
}
location /check_req_status {
req_status_show req_server_status;
}
location = /nginx_status {
stub_status  on;
}
}
server {
listen  10.56.66.76:8080 backlog=20480;
proxy_set_header  Host $http_host;
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header  X-Forwarded-Proto $scheme;
proxy_set_header  X-Forwarded-Port $remote_port;
limit_req  zone=req50k burst=1000;
location / {
proxy_pass  http://rs_10_56_66_76_8080;
}
}
upstream rs_10_56_66_76_8080 {
check  type=http default_down=false timeout=4000 rise=5 fall=4 interval=5000;
check_http_send  "HEAD /healthCheck HTTP/1.0\r\nHOST:10.56.66.76\r\n\r\n";
server  10.56.16.5:9090 weight=20;
server  10.56.16.6:9090 weight=20;
}
server {
listen  10.56.66.76:443 backlog=20480;
ssl  on;
ssl_certificate  /home/openstack/olwaf/certificates/olwaf.crt;
ssl_certificate_key  /home/openstack/olwaf/certificates/olwaf.key;
ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers  ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS:!DH:!EDH;
ssl_prefer_server_ciphers  on;
ssl_session_cache  shared:rs_10_56_66_76_443:10m;
ssl_session_timeout  600s;
proxy_set_header  Host $http_host;
proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header  X-Forwarded-Proto $scheme;
proxy_set_header  X-Forwarded-Port $remote_port;
limit_req  zone=req50k burst=1000;
location / {
proxy_pass  http://rs_10_56_66_76_443;
}
}
upstream rs_10_56_66_76_443 {
check  type=http default_down=false timeout=4000 rise=5 fall=4 interval=5000;
check_http_send  "HEAD / HTTP/1.0\r\nHOST:10.56.66.76\r\n\r\n";
server  172.10.10.6:443 weight=20;
}
}

 

nginx配置解析过程ngx_init_cycle函数

资源初始化的入口:

ngx_cycle_t *ngx_init_cycle(ngx_cycle_t *old_cycle)
{
...
//core module create conf.
for (i = 0; ngx_modules[i]; i++) {                 
if (ngx_modules[i]->type != NGX_CORE_MODULE) { 
continue;                                  
}                                              
module = ngx_modules[i]->ctx;                  
if (module->create_conf) {                     
rv = module->create_conf(cycle);           
if (rv == NULL) {                          
ngx_destroy_pool(pool);                
return NULL;                           
}                                          
cycle->conf_ctx[ngx_modules[i]->index] = rv;
}                                              
}
...
conf.ctx = cycle->conf_ctx;                                  
conf.cycle = cycle;                                          
conf.pool = pool;                                            
conf.log = log;                                              
conf.module_type = NGX_CORE_MODULE;                          
conf.cmd_type = NGX_MAIN_CONF;                               
#if (NGX_SSL && NGX_SSL_ASYNC)                                   
conf.no_ssl_init = cycle->no_ssl_init;                       
#endif                                                           
#if 0                                                            
log->log_level = NGX_LOG_DEBUG_ALL;                          
#endif                                                           
//命令行解析                                                             
if (ngx_conf_param(&conf) != NGX_CONF_OK) {                  
environ = senv;                                          
ngx_destroy_cycle_pools(&conf);                          
return NULL;                                             
}                                                            
//配置解析                                                             
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
environ = senv;                                          
ngx_destroy_cycle_pools(&conf);                          
return NULL;                                             
}                                                            
...
//core module init conf.
for (i = 0; ngx_modules[i]; i++) {                                         
if (ngx_modules[i]->type != NGX_CORE_MODULE) {                         
continue;                                                          
}                                                                      
module = ngx_modules[i]->ctx;                                          
if (module->init_conf) {                                               
if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
== NGX_CONF_ERROR)                                             
{                                                                  
environ = senv;                                                
ngx_destroy_cycle_pools(&conf);                                
return NULL;                                                   
}                                                                  
}                                                                      
}       
...                                                                                                            
}

​​​​​​​

ngx_conf_parse和ngx_conf_handler函数分析:

//ngx_conf_parse函数
...
for ( ;; ) {
    rc = ngx_conf_read_token(cf);
    /*
    * ngx_conf_read_token() may return
    *
    *    NGX_ERROR             there is error
    *    NGX_OK                the token terminated by ";" was found
    *    NGX_CONF_BLOCK_START  the token terminated by "{" was found
    *    NGX_CONF_BLOCK_DONE   the "}" was found
    *    NGX_CONF_FILE_DONE    the configuration file is done
    */
    if (rc == NGX_ERROR) {
        goto done; 
    }
    if (rc == NGX_CONF_BLOCK_DONE) {
    if (type != parse_block) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected \"}\"");
        goto failed;
    }
    goto done;
}
if (rc == NGX_CONF_FILE_DONE) {
    if (type == parse_block) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unexpected end of file, expecting\"}\"");
        goto failed;
    }
    goto done;
}

if (rc == NGX_CONF_BLOCK_START) {
    if (type == parse_param) {
        ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"block directives are not supported" "in -g option");
        goto failed;
    }
}  
            
//cmd回调函数的执行                                                  
rc = ngx_conf_handler(cf, rc);
if (rc == NGX_ERROR) {       
    goto failed;            
}  

...
//ngx_conf_handler函数
if (cmd->type & NGX_DIRECT_CONF) {                         
    conf = ((void **) cf->ctx)[ngx_modules[i]->index];    
} else if (cmd->type & NGX_MAIN_CONF) {                    
    conf = &(((void **) cf->ctx)[ngx_modules[i]->index]); 
} else if (cf->ctx) {                                      
    confp = *(void **) ((char *) cf->ctx + cmd->conf);    
    if (confp) {                                          
        conf = confp[ngx_modules[i]->ctx_index];          
    }                                                     
}                                                          
rv = cmd->set(cf, cmd, conf);                              

if (rv == NGX_CONF_OK) {                                   
    return NGX_OK;                                        
}                                                          
if (rv == NGX_CONF_ERROR) {                                
    return NGX_ERROR;                                     
}                                                          
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"\"%s\" directive %s", name->data, rv); 
...

http core module函数分析

...
//create main, server, location conf.
for (m = 0; ngx_modules[m]; m++) {                       
    if (ngx_modules[m]->type != NGX_HTTP_MODULE) {      
    continue;                                       
    }                                                    
    module = ngx_modules[m]->ctx;                        
    mi = ngx_modules[m]->ctx_index;                      
    if (module->create_main_conf) {                      
        ctx->main_conf[mi] = module->create_main_conf(cf);
        if (ctx->main_conf[mi] == NULL) {               
            return NGX_CONF_ERROR;                      
        }                                               
    }                                                    
    if (module->create_srv_conf) {                       
        ctx->srv_conf[mi] = module->create_srv_conf(cf);
        if (ctx->srv_conf[mi] == NULL) {                
            return NGX_CONF_ERROR;                      
        }                                               
    }                                                    
    if (module->create_loc_conf) {                       
        ctx->loc_conf[mi] = module->create_loc_conf(cf);
        if (ctx->loc_conf[mi] == NULL) {                
            return NGX_CONF_ERROR;                      
        }                                               
    }                                                    
} 
pcf = *cf;                                                       
cf->ctx = ctx;
                                                   
/* init input body filter pointer */                             
ngx_http_top_input_body_filter = ngx_http_dummy_input_body_filter;
//执行preconfiguration                            

for (m = 0; ngx_modules[m]; m++) {                               
    if (ngx_modules[m]->type != NGX_HTTP_MODULE) {              
    continue;                                               
    }                                                            
    module = ngx_modules[m]->ctx;                                
    if (module->preconfiguration) {                              
        if (module->preconfiguration(cf) != NGX_OK) {           
            return NGX_CONF_ERROR;                              
        }                                                        
    }                                                            
}                                                 
/* parse inside the http{} block */                        
cf->module_type = NGX_HTTP_MODULE;                         
cf->cmd_type = NGX_HTTP_MAIN_CONF;                         
rv = ngx_conf_parse(cf, NULL);                             

if (rv != NGX_CONF_OK) {                                   
    goto failed;                                          
}
                                                          
/*                                                         
* init http{} main_conf's, merge the server{}s' srv_conf's
* and its location{}s' loc_conf's                         
*/                                                        
cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];     
cscfp = cmcf->servers.elts;                                

//执行模块的init_main_conf                                                           
for (m = 0; ngx_modules[m]; m++) {                         
    if (ngx_modules[m]->type != NGX_HTTP_MODULE) {        
        continue;                                         
    }                                                      
    module = ngx_modules[m]->ctx;                          
    mi = ngx_modules[m]->ctx_index;                        
    /* init http{} main_conf's */                          
    if (module->init_main_conf) {                          
        rv = module->init_main_conf(cf, ctx->main_conf[mi]);
        if (rv != NGX_CONF_OK) {                          
            goto failed;                                  
        }                                                 
    }                                                      
    rv = ngx_http_merge_servers(cf, cmcf, module, mi);     
    if (rv != NGX_CONF_OK) {                               
        goto failed;                                      
    }                                                      
}                                                                         
/* create location trees */                                       
//创建location 二树 
                                                                 
for (s = 0; s < cmcf->servers.nelts; s++) {                       
    clcf = cscfp[s]->ctx->loc_conf[ngx_http_core_module.ctx_index];
    if (ngx_http_init_locations(cf, cscfp[s], clcf) != NGX_OK) { 
        return NGX_CONF_ERROR;                                   
    }                                                            
    if (ngx_http_init_static_location_trees(cf, clcf) != NGX_OK) {
        return NGX_CONF_ERROR;                                   
    }                                                            
}                                                                 
...
//模块postconfiguration                                          
for (m = 0; ngx_modules[m]; m++) {                                
    if (ngx_modules[m]->type != NGX_HTTP_MODULE) {               
        continue;                                                
    }                                                             
    module = ngx_modules[m]->ctx;                                 
    if (module->postconfiguration) {                              
        if (module->postconfiguration(cf) != NGX_OK) {           
            return NGX_CONF_ERROR;                               
        }                                                         
    }                                                             
}                                                                 
if (ngx_http_variables_init_vars(cf) != NGX_OK) {                 
    return NGX_CONF_ERROR;                                       
}                     
...

ngx_http_core_server函数分析

...
//server 块中create_srv_conf & create_loc_conf
for (i = 0; ngx_modules[i]; i++) {                       
    if (ngx_modules[i]->type != NGX_HTTP_MODULE) {      
    continue;                                       
    }
                                                    
    module = ngx_modules[i]->ctx;                        
    if (module->create_srv_conf) {                       
        mconf = module->create_srv_conf(cf);            
        if (mconf == NULL) {                            
            return NGX_CONF_ERROR;                      
        }                                               
        ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
    }                                                    
    if (module->create_loc_conf) {                       
        mconf = module->create_loc_conf(cf);            
        if (mconf == NULL) {                            
            return NGX_CONF_ERROR;                      
        }                                               
        ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
    }                                                  
}
...
/* parse inside server{} */     
pcf = *cf;                      
cf->ctx = ctx;                  
cf->cmd_type = NGX_HTTP_SRV_CONF;
rv = ngx_conf_parse(cf, NULL);  
*cf = pcf;                      
...

ngx_http_core_location函数分析

...
for (i = 0; ngx_modules[i]; i++) {                                          
    if (ngx_modules[i]->type != NGX_HTTP_MODULE) {                          
    continue;                                                           
    }                                                                       
    module = ngx_modules[i]->ctx;                                           
    if (module->create_loc_conf) {                                          
        ctx->loc_conf[ngx_modules[i]->ctx_index] =                          
        module->create_loc_conf(cf); 
        if (ctx->loc_conf[ngx_modules[i]->ctx_index] == NULL) {             
            return NGX_CONF_ERROR;                                         
        }                                                                   
    }                                                                       
}                                                                           
...

​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值