nginx 소스 코드 분석 - nginx 상하 문 구조 초기 화

13714 단어 nginx배치 하 다.
앞에서 말 하 다.
본 논문 의 토론 을 바탕 으로 하 는 nginx 버 전 은 1. 2.1 이다.
글 은 nginx 의 일부 배경 지식 (예 를 들 어 모듈, 문맥 등) 에 대해 많이 언급 하지 않 았 고 본 고 는 nginx 에 대해 어느 정도 알 고 있 는 친구 에 게 적합 하 다.
 
ngx_conf_t *cf; nginx 모듈 개발 을 했 거나 nginx 소스 코드 를 배 운 동창 회 는 이 구조 체 에 대해 매우 낯 이 익 습 니 다.
ngx_cycle.c:251 conf.ctx = cycle->conf_ctx;
 
ctx (context) 는 nginx 에서 어디서나 볼 수 있 고 글자 의 이 해 는 문맥 입 니 다.nginx 에 저 장 된 모든 모듈 의 설정 구조 입 니 다.
cycle->conf_ctx 는 4 중 지침 인 데 왜 4 중 지침 이 필요 합 니까?본문 을 다 읽 으 면 이해 에 도움 이 되 기 를 바 랍 니 다.
 
 
nginx 프로필 nginx. conf (글 은 이 프로필 을 중심 으로 nginx 가 모듈 컨 텍스트 를 분석 하고 저장 하 는 과정)
1 http {
2     resolver 8.8.8.8;
3
4     server
5     {
6         listen 80;
7         server_name dcshi.com
8         root /data/html
9
10         location /a
11         {
12             set $foo $bar;
13
14             return 200;
15         }
16
17         location /b.html
18         {
19             root /opt/html;
20         }
21
22     }
23
24     server
25     {
26         listen 80;
27         server_name s2.dcshi.com
28
29         location /a {}
30
31         location /b {}
32     }
33 }

 
상기 프로필 에 대응 하 는 모듈 상하 문 (ctx) 구조 도:
1)ngx_cycle.c
215     for (i = 0; ngx_modules[i]; i++) {
216         if (ngx_modules[i]->type != NGX_CORE_MODULE) {
217             continue;
218         }
219
220         module = ngx_modules[i]->ctx;

/*        ,      create_conf,      create_conf         */
222         if (module->create_conf) {
223             rv = module->create_conf(cycle);
224             if (rv == NULL) {
225                 ngx_destroy_pool(pool);
226                 return NULL;
227             }
228             cycle->conf_ctx[ngx_modules[i]->index] = rv;
229         }
230     }

 
2)ngx_cycle.c
/*
*   ngx_conf_parse        (nginx.conf),ngx_conf_parse         。
*          ,    NULL,      block  。{ }             block。
* /
268     if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
269         environ = senv;
270         ngx_destroy_cycle_pools(&conf);
271         return NULL;
272     }

 
3)ngx_conf_file.c:
/*
*        handler  ,     
* cf->handler       NULL?     。
*/
222         if (cf->handler) {
223
224             /*
225              * the custom handler, i.e., that is used in the http's
226              * "types { ... }" directive
227              */
228
229             rv = (*cf->handler)(cf, NULL, cf->handler_conf);
230             if (rv == NGX_CONF_OK) {
231                 continue;
232             }
233
234             if (rv == NGX_CONF_ERROR) {
235                 goto failed;
236             }
237
238             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, rv);
239
240             goto failed;
241         }
242
243
// cf->hanlder NULL,   ngx_conf_handler          ,             。
244         rc = ngx_conf_handler(cf, rc);

 
4)ngx_conf_file.c
/*
* NGX_DIRECT_CONF    direct(  ),         core   
* direct         (  )            ,               , worker_processes  
*     direct             , http  (http     ,      ,     !)
*         ,nginx         ,     NGX_CORE_MODULE    create_conf,
* direct               .
*
*/
380             if (cmd->type & NGX_DIRECT_CONF) {
381                 conf = ((void **) cf->ctx)[ngx_modules[i]->index];
382
/*
* http      NGX_MAIN_CONF  (      type,  ngx_command_s  )
*        ,381  384       ,          。
* c/c++         func(char *p)   func(char **p)   。   func      p      
*  http    ,http     ngx_http_module,     create_conf(ngx_http.c:98)
*           ngx_http_module        ,     ngx_http_block       
*   ,                 。
*      ngx_http_module    create_conf  ,        ?          。
*/
383             } else if (cmd->type & NGX_MAIN_CONF) {
384                 conf = &(((void **) cf->ctx)[ngx_modules[i]->index]);
385
386             } else if (cf->ctx) {
/*
* cmd->conf   ?set   conf  NGX_HTTP_LOC_CONF_OFFSET(ngx_http_rewrite_module.c:81)
* #define NGX_HTTP_LOC_CONF_OFFSET   offsetof(ngx_http_conf_ctx_t, loc_conf)
*         ,      cmd->conf         struct    
* nginx   http          (ngx_http_conf_ctx_t)  main_conf, srv_conf, loc_conf     ;
*         ,             *_conf;       (      )  ,         *_conf。
* set       location server,set            srv_conf or loc_conf?                      。
*/
387                 confp = *(void **) ((char *) cf->ctx + cmd->conf);
388
389                 if (confp) {
390                     conf = confp[ngx_modules[i]->ctx_index];
391                 }
392             }
393
/*                    */
394             rv = cmd->set(cf, cmd, conf);

 
위의 코드 세 션 을 통 해 nginx 는 설정 파일 을 분석 하면 서 해당 하 는 모듈 명령 을 찾 고 명령 에 연 결 된 리 셋 함 수 를 호출 하여 초기 화 하 는 것 을 이해 할 수 있 습 니 다.다음은 http 명령 의 정의 입 니 다.
83 static ngx_command_t  ngx_http_commands[] = {
84
85     { ngx_string("http"),
86       NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
87       ngx_http_block,
88       0,
89       0,
90       NULL },
91
92       ngx_null_command
93 };

ngx_http_block 은 매우 중요 한 함수 입 니 다. nginx 가 설정 파일 을 분석 하 는 단계 에서 http 명령 을 읽 으 면 ngx 를 호출 합 니 다.http_block 함 수 는 http {...} 괄호 안의 설정 을 분석 합 니 다.
 
5)ngx_http.c
120 ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
121 {
…...

130
131     /* the main http context */
132
133     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
134     if (ctx == NULL) {
135         return NGX_CONF_ERROR;
136     }
137
/*

*   ,    conf    。

*   http_module  core  ,       create_conf,         http_module       

* http   NGX_MAIN_CONF,  conf             

*            ,  conf    

*/
138     *(ngx_http_conf_ctx_t **) conf = ctx;
139
140
141     /*     http module  ctx_index */
142
143     ngx_http_max_module = 0;
144     for (m = 0; ngx_modules[m]; m++) {
145         if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
146             continue;
147         }
148
149         ngx_modules[m]->ctx_index = ngx_http_max_module++;
150     }
151
152
/*
*  http ctx  main_conf, srv_conf loc_conf     ;
*       *_conf     ,   ngx_http_max_module,
*           main_conf, srv_conf loc_conf,          。
*/
155     ctx->main_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
…...
167     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
…….
178     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
/*        ,               */
189     for (m = 0; ngx_modules[m]; m++) {
190         if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
191             continue;
192         }
193
194         module = ngx_modules[m]->ctx;
195         mi = ngx_modules[m]->ctx_index;
196
197         if (module->create_main_conf) {
198             ctx->main_conf[mi] = module->create_main_conf(cf);
202         }
203
204         if (module->create_srv_conf) {
205             ctx->srv_conf[mi] = module->create_srv_conf(cf);
209         }
210
211         if (module->create_loc_conf) {
212             ctx->loc_conf[mi] = module->create_loc_conf(cf);
216         }
217     }
218
/*  cf        , 329     。 */
219     pcf = *cf;
/*
*   :  cf->ctx    ;nginx           ,cf->ctx      (     )。
*    http {}    cf->ctx  http_module      
*    server{}    cf->ctx    server      
*    location{}    ,cf->ctx    location      
*              
*/
220     cf->ctx = ctx;
…...
235
236     /*   http { },              ,server  http        ,            */
238     cf->module_type = NGX_HTTP_MODULE;
239     cf->cmd_type = NGX_HTTP_MAIN_CONF;
240     rv = ngx_conf_parse(cf, NULL);
241
242     if (rv != NGX_CONF_OK) {
243         goto failed;
244     }
…..
328
329     *cf = pcf;

 
6)ngx_http_core_module.c
/*
*   :          -dummy(  ),        .
*        conf, http server ctx      ?(           )
*/
2832 ngx_http_core_server(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
2833 {
……
/*  server         ,        http          */
2845     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2846     if (ctx == NULL) {
2847         return NGX_CONF_ERROR;
2848     }
/*
*   :server ctx->main_conf     http_ctx(http ctx, server ctx    ) main_conf
*  ngx_http_block  ,           srv_conf loc_conf      
*      , server           main_conf     .
*      ,location         main_conf srv_conf,      loc_conf    (ngx_http_core_location)
*               
*/
2850     http_ctx = cf->ctx;
2851     ctx->main_conf = http_ctx->main_conf;
2852
…….
2855     ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
…….
2862     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
/*      http module,     create_srv_conf   create_loc_conf           */
2867     for (i = 0; ngx_modules[i]; i++) {
2868         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2869             continue;
2870         }
2871
2872         module = ngx_modules[i]->ctx;
2873
2874         if (module->create_srv_conf) {
2875             mconf = module->create_srv_conf(cf);
2880             ctx->srv_conf[ngx_modules[i]->ctx_index] = mconf;
2881         }
2882
2883         if (module->create_loc_conf) {
2884             mconf = module->create_loc_conf(cf);
2889             ctx->loc_conf[ngx_modules[i]->ctx_index] = mconf;
2890         }
2891     }
/*
*     ,       http_ctx srv_ctx    
* 2896, 2897       srv_ctx     ngx_http_core_module   ctx   
*        
*/
2896     cscf = ctx->srv_conf[ngx_http_core_module.ctx_index];
2897     cscf->ctx = ctx;
2898
/*
*    ,http_ctx->main_conf( srv_ctx->main_conf    ,   2851  ?)
* 2900 - 2907         :  ctx       ,      ngx_http_core_module       
* cmcf->servers   array  ,  nginx.conf      server        
*        
* /
2900     cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
2902     cscfp = ngx_array_push(&cmcf->servers);
2903     if (cscfp == NULL) {
2904         return NGX_CONF_ERROR;
2905     }
2906
2907     *cscfp = cscf;
2908
/*     ngx_conf_parse server{ }     ,  location  server      ,         。   7 */
2911
2912     pcf = *cf;
2913     cf->ctx = ctx;
2914     cf->cmd_type = NGX_HTTP_SRV_CONF;
2915
2916     rv = ngx_conf_parse(cf, NULL);
2917

/* cf    */
2918     *cf = pcf;

 
7) ngx_http_core_module.c
/*
*   :          -dummy(  ),        .
*/
2956 ngx_http_core_location(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
2957 {
…….
2968     ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));
2969     if (ctx == NULL) {
2970         return NGX_CONF_ERROR;
2971     }
2972
/*       ,location         main_conf srv_conf,      loc_conf     */
2973     pctx = cf->ctx;
2974     ctx->main_conf = pctx->main_conf;
2975     ctx->srv_conf = pctx->srv_conf;
2976
2977     ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);
/*     http module,    create_loc_conf           */
2982     for (i = 0; ngx_modules[i]; i++) {
2983         if (ngx_modules[i]->type != NGX_HTTP_MODULE) {
2984             continue;
2985         }

2987         module = ngx_modules[i]->ctx;
2988
2989         if (module->create_loc_conf) {
2990             ctx->loc_conf[ngx_modules[i]->ctx_index] = module->create_loc_conf(cf);
2996     }
2997
/*
* 2998 - 3084    6  ,  ngx_http_core_module     
*        
*/
2998     clcf = ctx->loc_conf[ngx_http_core_module.ctx_index];
2999     clcf->loc_conf = ctx->loc_conf;
3000
…….
3083     pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index];
3084
3085     if (pclcf->name.len) {
……. //location      , location /a { location /b { } } ,    
3131     }
3132
3133     if (ngx_http_add_location(cf, &pclcf->locations, clcf) != NGX_OK) {
3134         return NGX_CONF_ERROR;
3135     }
/*     location        ;      ,cf->ctx   ,      location ctx */

3137     save = *cf;
3138     cf->ctx = ctx;
3139     cf->cmd_type = NGX_HTTP_LOC_CONF;
3140
3141     rv = ngx_conf_parse(cf, NULL);
3142
3143     *cf = save;
3144
3145     return rv;
3146 }

 
8)ngx_http. c 단계 5, http 에 대응 하 는 리 셋 함 수 는 ngxhttp_Block. 240 줄 에서 http {} block 전 체 를 분석 한 후에 nginx 는 합 쳐 야 합 니 다.위의 분석 에서 언급 된 ctx 는 httpctx, srv_ctx, loc_ctx;이 locconf 의 경우 세 개의 ctx 가 모두 포함 되 어 있 고 서로 독립 되 어 있다.루트 명령 은 server {} 에 정의 할 수도 있 고 location {} 에 정의 할 수도 있 습 니 다.location 에 루트 를 정의 하지 않 으 면 location 의 locconf 는 server {} 의 루트 설정 을 계승 해 야 합 니 다. 이것 이 merge 의 역할 입 니 다.다음 코드 는 nginx 가 merge 를 어떻게 진행 하 는 지 보 여 줍 니 다.
각각 merge httpctx 와 srvctx 의 srvconf 와 locconf
  • merge srv_ctx 와 locctx 의 locconf
  • 251     cmcf = ctx->main_conf[ngx_http_core_module.ctx_index];
    252     cscfp = cmcf->servers.elts;
    253
    254     for (m = 0; ngx_modules[m]; m++) {
    255         if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
    256             continue;
    257         }
    258
    259         module = ngx_modules[m]->ctx;
    260         mi = ngx_modules[m]->ctx_index;
    261
    262         /* init http{} main_conf's */
    263
    264         if (module->init_main_conf) {
    265             rv = module->init_main_conf(cf, ctx->main_conf[mi]);
    266             if (rv != NGX_CONF_OK) {
    267                 goto failed;
    268             }
    269         }
    270
    271         rv = ngx_http_merge_servers(cf, cmcf, module, mi);
    272         if (rv != NGX_CONF_OK) {
    273             goto failed;
    274         }
    275     }

    좋은 웹페이지 즐겨찾기