nginx 소스 코드 분석 - 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
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 }
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
간단! Certbot을 사용하여 웹 사이트를 SSL(HTTPS)화하는 방법초보자가 인프라 주위를 정돈하는 것은 매우 어렵습니다. 이번은 사이트를 간단하게 SSL화(HTTP에서 HTTPS통신)로 변경하는 방법을 소개합니다! 이번에는 소프트웨어 시스템 Nginx CentOS7 의 환경에서 S...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.