Nginx 소스 코드 분석 - 주류 프로 세 스 - Nginx 의 시작 프로 세 스
이 장 은 주로 Nginx 의 주요 절 차 를 분석 하기 시작 했다.
Nginx 의 메 인 프로 세 스 구현 함 수 는... / src / core / nginx. c 파일 에 있 습 니 다.main () 함 수 를 통 해 우 리 는 Nginx 가 시작 하 는 모든 절 차 를 엿 볼 수 있 습 니 다.
Nginx 시작 과정
main () 함수 의 시작 과정 은 다음 과 같 습 니 다.
ngx_get_options 외부 매개 변수 분석
ngx_get_options 방법 은 주로 명령 행 외부 인 자 를 분석 하 는 데 사 용 됩 니 다.예 를 들 어:. / nginx - s stop | start | restart
/* */
if (ngx_get_options(argc, argv) != NGX_OK) {
return 1;
}
/**
*
* ./nginx -s stop|start|restart
*/
static ngx_int_t
ngx_get_options(int argc, char *const *argv)
{
u_char *p;
ngx_int_t i;
for (i = 1; i < argc; i++) {
p = (u_char *) argv[i];
if (*p++ != '-') {
ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);
return NGX_ERROR;
}
while (*p) {
switch (*p++) {
case '?':
case 'h':
ngx_show_version = 1;
ngx_show_help = 1;
break;
case 'v':
ngx_show_version = 1;
break;
case 'V':
ngx_show_version = 1;
ngx_show_configure = 1;
break;
case 't':
ngx_test_config = 1;
break;
case 'T':
ngx_test_config = 1;
ngx_dump_config = 1;
break;
case 'q':
ngx_quiet_mode = 1;
break;
case 'p':
if (*p) {
ngx_prefix = p;
goto next;
}
if (argv[++i]) {
ngx_prefix = (u_char *) argv[i];
goto next;
}
ngx_log_stderr(0, "option \"-p\" requires directory name");
return NGX_ERROR;
case 'c':
if (*p) {
ngx_conf_file = p;
goto next;
}
if (argv[++i]) {
ngx_conf_file = (u_char *) argv[i];
goto next;
}
ngx_log_stderr(0, "option \"-c\" requires file name");
return NGX_ERROR;
case 'g':
if (*p) {
ngx_conf_params = p;
goto next;
}
if (argv[++i]) {
ngx_conf_params = (u_char *) argv[i];
goto next;
}
ngx_log_stderr(0, "option \"-g\" requires parameter");
return NGX_ERROR;
case 's':
if (*p) {
ngx_signal = (char *) p;
} else if (argv[++i]) {
ngx_signal = argv[i];
} else {
ngx_log_stderr(0, "option \"-s\" requires parameter");
return NGX_ERROR;
}
if (ngx_strcmp(ngx_signal, "stop") == 0
|| ngx_strcmp(ngx_signal, "quit") == 0
|| ngx_strcmp(ngx_signal, "reopen") == 0
|| ngx_strcmp(ngx_signal, "reload") == 0)
{
ngx_process = NGX_PROCESS_SIGNALLER;
goto next;
}
ngx_log_stderr(0, "invalid option: \"-s %s\"", ngx_signal);
return NGX_ERROR;
default:
ngx_log_stderr(0, "invalid option: \"%c\"", *(p - 1));
return NGX_ERROR;
}
}
next:
continue;
}
return NGX_OK;
}
init_cycle 전역 변수 초기 화
init 초기 화cycle Nginx 의 전역 변수 입 니 다.메모리 탱크 에 기본 크기 1024 의 전역 변 수 를 만 듭 니 다.이것 은 단지 가장 간단 한 초기 화 변수 일 뿐이다.
/*
* init_cycle->log is required for signal handlers and
* ngx_process_options()
*/
/* Nginx init_cycle */
ngx_memzero(&init_cycle, sizeof(ngx_cycle_t));
init_cycle.log = log;
ngx_cycle = &init_cycle;
/* 1024*/
init_cycle.pool = ngx_create_pool(1024, log);
if (init_cycle.pool == NULL) {
return 1;
}
초기 화
ngx_init_cycle 함수 중.ngx_init_cycle 은 Nginx 의 전역 변 수 를 모두 초기 화 하 는 과정 을 포함 하고 있 으 며, 다음 에 따로 글 을 열 어 설명 합 니 다.
/* cycle */
cycle = ngx_init_cycle(&init_cycle);
if (cycle == NULL) {
if (ngx_test_config) {
ngx_log_stderr(0, "configuration file %s test failed",
init_cycle.conf_file.data);
}
return 1;
}
변수 저장 방법 ngxsave_argv 와 ngxprocess_options
ngx_save_argv: Nginx 명령 행 의 인자 와 변 수 를 저장 하고 전역 변수 ngxargv
ngx_process_options: ngxget_options 에서 이 매개 변 수 를 획득 하여 ngx 에 값 을 부여 합 니 다.cycle 중.prefix, conf_prefix, conf_file, conf_param 등 필드.
/* Nginx , ngx_argv */
if (ngx_save_argv(&init_cycle, argc, argv) != NGX_OK) {
return 1;
}
/* ngx_get_options ngx_cycle */
if (ngx_process_options(&init_cycle) != NGX_OK) {
return 1;
}
머리의 전역 변수 정의/**
*
*/
static ngx_uint_t ngx_show_help; //
static ngx_uint_t ngx_show_version; //
static ngx_uint_t ngx_show_configure; //
static u_char *ngx_prefix; //Nginx
static u_char *ngx_conf_file; //
static u_char *ngx_conf_params; //
static char *ngx_signal; //
int ngx_argc; //
char **ngx_argv; //
char **ngx_os_argv;
/**
* Nginx
* ngx_argv
*/
static ngx_int_t
ngx_save_argv(ngx_cycle_t *cycle, int argc, char *const *argv)
{
#if (NGX_FREEBSD)
ngx_os_argv = (char **) argv;
ngx_argc = argc;
ngx_argv = (char **) argv;
#else
size_t len;
ngx_int_t i;
ngx_os_argv = (char **) argv;
ngx_argc = argc;
ngx_argv = ngx_alloc((argc + 1) * sizeof(char *), cycle->log);
if (ngx_argv == NULL) {
return NGX_ERROR;
}
for (i = 0; i < argc; i++) {
len = ngx_strlen(argv[i]) + 1;
ngx_argv[i] = ngx_alloc(len, cycle->log);
if (ngx_argv[i] == NULL) {
return NGX_ERROR;
}
(void) ngx_cpystrn((u_char *) ngx_argv[i], (u_char *) argv[i], len);
}
ngx_argv[i] = NULL;
#endif
ngx_os_environ = environ;
return NGX_OK;
}
/**
* ngx_get_options ngx_cycle
*/
static ngx_int_t
ngx_process_options(ngx_cycle_t *cycle)
{
u_char *p;
size_t len;
/* Nginx */
if (ngx_prefix) {
len = ngx_strlen(ngx_prefix);
p = ngx_prefix;
if (len && !ngx_path_separator(p[len - 1])) {
p = ngx_pnalloc(cycle->pool, len + 1);
if (p == NULL) {
return NGX_ERROR;
}
ngx_memcpy(p, ngx_prefix, len);
p[len++] = '/';
}
cycle->conf_prefix.len = len;
cycle->conf_prefix.data = p;
cycle->prefix.len = len;
cycle->prefix.data = p;
} else {
#ifndef NGX_PREFIX
p = ngx_pnalloc(cycle->pool, NGX_MAX_PATH);
if (p == NULL) {
return NGX_ERROR;
}
if (ngx_getcwd(p, NGX_MAX_PATH) == 0) {
ngx_log_stderr(ngx_errno, "[emerg]: " ngx_getcwd_n " failed");
return NGX_ERROR;
}
len = ngx_strlen(p);
p[len++] = '/';
cycle->conf_prefix.len = len;
cycle->conf_prefix.data = p;
cycle->prefix.len = len;
cycle->prefix.data = p;
#else
#ifdef NGX_CONF_PREFIX
ngx_str_set(&cycle->conf_prefix, NGX_CONF_PREFIX);
#else
ngx_str_set(&cycle->conf_prefix, NGX_PREFIX);
#endif
ngx_str_set(&cycle->prefix, NGX_PREFIX);
#endif
}
/* */
if (ngx_conf_file) {
cycle->conf_file.len = ngx_strlen(ngx_conf_file);
cycle->conf_file.data = ngx_conf_file;
} else {
ngx_str_set(&cycle->conf_file, NGX_CONF_PATH);
}
if (ngx_conf_full_name(cycle, &cycle->conf_file, 0) != NGX_OK) {
return NGX_ERROR;
}
for (p = cycle->conf_file.data + cycle->conf_file.len - 1;
p > cycle->conf_file.data;
p--)
{
if (ngx_path_separator(*p)) {
cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1;
cycle->conf_prefix.data = ngx_cycle->conf_file.data;
break;
}
}
/* */
if (ngx_conf_params) {
cycle->conf_param.len = ngx_strlen(ngx_conf_params);
cycle->conf_param.data = ngx_conf_params;
}
if (ngx_test_config) {
cycle->log->log_level = NGX_LOG_INFO;
}
return NGX_OK;
}
모듈 에 표시 ngxpreinit_modules
ngx_preinit_modules 방법 은 주로 모든 모듈 을 초기 화 합 니 다.모든 모듈 에 번호 처리 하기;
/* ; ;
* ngx_modules , objs/ngx_modules.c */
if (ngx_preinit_modules() != NGX_OK) {
return 1;
}
ngx_module.c
/**
* ; ;
*/
ngx_int_t
ngx_preinit_modules(void)
{
ngx_uint_t i;
for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = i;
ngx_modules[i]->name = ngx_module_names[i];
}
ngx_modules_n = i;
ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES;
return NGX_OK;
}
PID 파일 생 성 ngxcreate_pidfile
ngx_create_pidfile PID 파일 생 성
/* PID */
if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) {
return 1;
}
ngx_cycle.c /**
* PID
*/
ngx_int_t
ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
{
size_t len;
ngx_uint_t create;
ngx_file_t file;
u_char pid[NGX_INT64_LEN + 2];
if (ngx_process > NGX_PROCESS_MASTER) {
return NGX_OK;
}
ngx_memzero(&file, sizeof(ngx_file_t));
file.name = *name;
file.log = log;
create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE;
file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR,
create, NGX_FILE_DEFAULT_ACCESS);
if (file.fd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
ngx_open_file_n " \"%s\" failed", file.name.data);
return NGX_ERROR;
}
if (!ngx_test_config) {
len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
return NGX_ERROR;
}
}
if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_close_file_n " \"%s\" failed", file.name.data);
}
return NGX_OK;
}
기타 중요 모듈
아래 모듈 에 서 는 새로운 글 을 작성 하여 구체 적 으로 상세 하 게 해석 합 니 다.
ngx_add_inherited_sockets 계승 Socket 파일 핸들
ngx_init_cycle 전역 프로필 cycle 상세 설명
ngx_signal_process 신호 처리 메커니즘
ngx_master_process_cycle 다 중 프로 세 스 순환 메커니즘
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.