nginx 소스 학습 노트 (15) - ngxmaster_process_cycle 다 중 프로 세 스 (1)
nginx 프로 세 스 시작 과정 은 ngxmaster_process_cycle (src / os / unix / ngx process cycle. c) 에서 완 성 된 (단일 프로 세 스 는 ngx single process cycle 을 통 해 완 성 됩 니 다. 여 기 는 다 중 프로 세 스 의 상황 만 분석 합 니 다), ngxmaster_process_cycle 에서 설정 파일 에 따라 workerprocesses 값 은 master 프로 세 스 와 여러 worker 프로 세 스 를 만 듭 니 다.프로 세 스 간, 프로 세 스 와 외부 간 의 통신 을 유지 합 니 다. 프로 세 스 간 에는 socketpair 를 통 해 통신 합 니 다. socketpair 는 두 가지 작업 을 하 는 이름 없 는 socket 입 니 다. 파이프 로 사용 할 수 있 습 니 다. 파이프 와 달리 모든 socket 은 읽 을 수도 있 고 쓸 수도 있 습 니 다. 파 이 프 는 쓰기 나 읽 기 에 만 사용 할 수 있 습 니 다.프로 세 스 와 외부 사 이 는 신 호 를 통 해 통신 된다.
master 프로 세 스 는 주로 전역 적 인 초기 화 작업 과 워 커 관리 작업 을 진행 합 니 다.이벤트 처 리 는 워 커 에서 진행 되 었 습 니 다.
프로 세 스 가 시작 되 는 과정 에서 중요 한 전역 데이터 가 설정 되 며, 가장 중요 한 것 은 프로 세 스 표 ngx 입 니 다.processes, master 는 워 커 를 만 들 때마다 설 치 된 ngxprocess_t 구조 변수 넣 기 ngxprocesses 에서 프로 세 스 표 길 이 는 1024 이 고 방금 만 든 프로 세 스 는 ngx 에 저 장 됩 니 다.process_slot 위치, ngxlast_process 는 프로 세 스 표 의 마지막 저장량 프로 세 스 의 다음 위치 입 니 다. ngxprocess_t 는 프로 세 스 가 nginx 에서 추상 화 된 것 입 니 다.
src/os/unix/ngx_process.h
typedef void (*ngx_spawn_proc_pt) (ngx_cycle_t *cycle, void *data);
typedef struct {
ngx_pid_t pid; // id
int status; //
ngx_socket_t channel[2]; //socketpair socket
ngx_spawn_proc_pt proc; //
void *data; //
char *name; //
unsigned respawn:1; //
unsigned just_spawn:1; //
unsigned detached:1; //
unsigned exiting:1; //
unsigned exited:1; //
} ngx_process_t;
프로 세 스 간 통신 은 socketpair 를 이용 하여 만 든 socket 한 쌍 으로 진행 되 며, 통신 에서 전송 하 는 것 은 ngx 입 니 다.channel_t 구조 변수:
ypedef struct {
ngx_uint_t command;
ngx_pid_t pid; // id
ngx_int_t slot; //
ngx_fd_t fd; //
} ngx_channel_t;(src/os/unix/ngx_channel.h)
/*command , 5 :
#define NGX_CMD_OPEN_CHANNEL 1
#define NGX_CMD_CLOSE_CHANNEL 2
#define NGX_CMD_QUIT 3
#define NGX_CMD_TERMINATE 4
#define NGX_CMD_REOPEN 5
*/
프로 세 스 의 시작 과정 은 비교적 중요 한 부분 입 니 다. 이 과정 을 철저히 분석 하기 위해 서 는 먼저 ngx 를 분석 하 는 것 을 많이 사용 할 것 입 니 다.master_process_cycle 함 수 는 다음 과 같은 각 단계 로 분해 할 수 있 습 니 다. 1. master 는 처리 해 야 할 신 호 를 설정 합 니 다. 이 신 호 는 다음 과 같 습 니 다.
SIGCHLD,SIGALRM,SIGIO,SIGINT,NGX_RECONFIGURE_SIGNAL(SIGHUP),NGX_REOPEN_SIGNAL(SIGUSR1), NGX_NOACCEPT_SIGNAL(SIGWINCH),NGX_TERMINATE_SIGNAL(SIGTERM),NGX_SHUTDOWN_SIGNAL(SIGQUIT), NGX_CHANGEBIN_SIGNAL(SIGUSR2);
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigaddset(&set, SIGALRM);
sigaddset(&set, SIGIO);
sigaddset(&set, SIGINT);
sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL));
2, 호출 ngxsetproctilte 프로 세 스 제목 설정, title = "master process" + ngxargv[0] + ... + ngx_argv[ngx_argc-1];
title = ngx_pnalloc(cycle->pool, size);
p = ngx_cpymem(title, master_process, sizeof(master_process) - 1);
for (i = 0; i < ngx_argc; i++) {
*p++ = ' ';
p = ngx_cpystrn(p, (u_char *) ngx_argv[i], size);
}
ngx_setproctitle(title);
3, 호출 ngxstart_worker_processes (cycle, ccf - > worker processes, NGX PROCESS RESPAWN) 가 worker 프로 세 스 를 시작 합 니 다.
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
4, 호출 ngxstart_cache_manager_processes (cycle, 0) 파일 cache 관리 프로 세 스 를 시작 합 니 다. 일부 모듈 은 파일 cache 가 필요 합 니 다. 예 를 들 어 fastcgi 모듈 등 이 모듈 은 파일 cache 경 로 를 cycle - > paths 에 추가 합 니 다. 파일 cache 관리 프로 세 스 는 정기 적 으로 이 모듈 의 파일 cache 처리 갈 고 리 를 호출 하여 파일 cache 를 처리 합 니 다.
ngx_start_cache_manager_processes(cycle, 0);
주석 코드 의 방식 분석.5. master 순환 처리 신 호 량.
src/os/unix/ngx_process_cycle.c
delay = 0;
sigio = 0;
live = 1;
for ( ;; ) {
//delay worker ,master ,
// worker, worker
if (delay) {
if (ngx_sigalrm) {
sigio = 0;
delay *= 2;
ngx_sigalrm = 0;
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"termination cycle: %d", delay);
itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 0;
itv.it_value.tv_sec = delay / 1000;
itv.it_value.tv_usec = (delay % 1000 ) * 1000;
//
// , SIGALRM
if (setitimer(ITIMER_REAL, &itv, NULL) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"setitimer() failed");
}
}
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend");
//
sigsuspend(&set);
ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"wake up, sigio %i", sigio);
// SIGCHLD , worker (ngx_reap == 1)
if (ngx_reap) {
ngx_reap = 0;
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
// worker, worker ,
// worker, worker , 0
live = ngx_reap_children(cycle);
}
// worker
// NGX_CMD_TERMINATE SIGTERM SIGINT (ngx_terminate ==1)
// NGX_CMD_QUIT SIGQUIT (ngx_quit == 1), master
if (!live && (ngx_terminate || ngx_quit)) {
ngx_master_process_exit(cycle);
}
// NGX_CMD_TERMINATE SIGTERM SIGINT (ngx_terminate ==1)
// worker , worker
if (ngx_terminate) {
if (delay == 0) {
//
delay = 50;
}
if (sigio) {
sigio--;
continue;
}
sigio = ccf->worker_processes + 2 /* cache processes */;
if (delay > 1000) {
// , worker SIGKILL , worker
ngx_signal_worker_processes(cycle, SIGKILL);
} else {
// worker SIGTERM , worker
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_TERMINATE_SIGNAL));
}
continue;
}
//NGX_CMD_QUIT SIGQUIT (ngx_quit == 1)
if (ngx_quit) {
// worker SIGQUIT
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
// socket
ls = cycle->listening.elts;
for (n = 0; n < cycle->listening.nelts; n++) {
if (ngx_close_socket(ls[n].fd) == -1) {
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
ngx_close_socket_n " %V failed",
&ls[n].addr_text);
}
}
cycle->listening.nelts = 0;
continue;
}
// SIGHUP
if (ngx_reconfigure) {
ngx_reconfigure = 0;
// , worker, 。
if (ngx_new_binary) {
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
ngx_start_cache_manager_processes(cycle, 0);
ngx_noaccepting = 0;
continue;
}
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring");
//
cycle = ngx_init_cycle(cycle);
if (cycle == NULL) {
cycle = (ngx_cycle_t *) ngx_cycle;
continue;
}
// worker
ngx_cycle = cycle;
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx,
ngx_core_module);
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_JUST_RESPAWN);
ngx_start_cache_manager_processes(cycle, 1);
live = 1;
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
}
// ngx_noaccepting==1 , ngx_restart 1, worker
if (ngx_restart) {
ngx_restart = 0;
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
ngx_start_cache_manager_processes(cycle, 0);
live = 1;
}
// SIGUSR1 , log
if (ngx_reopen) {
ngx_reopen = 0;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs");
ngx_reopen_files(cycle, ccf->user);
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_REOPEN_SIGNAL));
}
// SIGUSER2,
if (ngx_change_binary) {
ngx_change_binary = 0;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "changing binary");
ngx_new_binary = ngx_exec_new_binary(cycle, ngx_argv);
}
// SIGWINCH ,worker ,master
if (ngx_noaccept) {
ngx_noaccept = 0;
ngx_noaccepting = 1;
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
}
}
다음 에 정리 하고 여러분 의 친구 들 도 다시 정 리 를 보기 전에 (적어도 한 번 은 봤 습 니 다) 위의 코드 주석 을 읽 었 으 면 좋 겠 습 니 다!!
총 결http://blog.csdn.net/lu_ming/article/details/5144427 작가 의 사심 없 는 헌신 에 매우 감사 드 립 니 다.
ngx_master_process_cycle () 함수 입 니 다. 이 함 수 는 작업 프로 세 스 를 시작 하고 신 호 량 을 처리 합 니 다. 처리 하 는 과정 에서 새로운 프로 세 스 를 죽 이거 나 만 듭 니 다.
a) 모든 nginx 관심 신호 차단;
b) 프로 세 스 의 title 을 설정 합 니 다. (ps – aux 로 보면 master 와 worker 프로 세 스 를 구분 할 수 있 습 니 다. 이것 이 title 의 역할 입 니 다.)
c) 대로core_conf_t 중 workerprocesses 수, 몇몇 work 프로 세 스 를 시작 합 니 다.
d) 버퍼 관리 프로 세 스 시작 하기;
e) 몇 개의 플래그 초기 화: ngxnew_binary = 0; delay = 0; live = 1;
f) 뒤의 순환 은 서로 다른 상 태 를 다 르 게 처리 하 는데, 그 상 태 는 대부분 프로 세 스 가 받 은 서로 다른 신호 이다.다음은 각 처리 에 대한 상세 한 설명 입 니 다.
a) delay 는 0 이 아 닙 니 다. SIGALRM 신 호 를 받 으 면 ngxsigalrm 을 1 로 설정 하고 delay 시간 을 2 로 곱 합 니 다.마지막 으로 실시 간 타 이 머 를 설정 합 니 다.
b) 현재 프로 세 스 를 끊 고 신호 가 있 을 때 까지 끊 은 상태 에서 종료 하고 계속 실행 합 니 다.
c) 연결 상 태 를 종료 한 후 운영 체제 시간 에 따라 현재 시간 을 다시 업데이트 합 니 다.
d) ngx_reap 은 1 (SIGCHLD 신 호 를 받 고 worker 종료 (ngx reap = = 1)), ngx 호출reap_children () 회수 서브 프로 세 스;
e) 하위 프로 세 스 가 모두 종료 되면 (! live) 현재 프로 세 스 가 ngx 를 받 습 니 다.signal_value (NGX SHUTDOWN SIGNAL) 또는 ngxsignal_value (NGX TERMINATE SIGNAL) 신호 로 이 프로 세 스 를 종료 처리 합 니 다 (ngx master process exit ().처 리 를 종료 하고 pid 파일 을 삭제 한 다음 에 모든 모듈 의 프로 세 스 를 호출 하여 갈 고 리 를 종료 하고 메모리 풀 대상 을 소각 합 니 다.
f) 하면, 만약, 만약...terminate 는 1 이 고 delay 는 0 이 며 50 으로 설정 합 니 다.delay > 1000 이면 work 프로 세 스에 SIGKILL 신 호 를 보 냅 니 다. 그렇지 않 으 면 work 프로 세 스에 ngx 를 보 냅 니 다.signal_value (NGX TERMINATE SIGNAL) 신호;
g) 하면, 만약, 만약...quit 1, work 프로 세 스에 ngx 보 내기signal_value (NGX SHUTDOWN SIGNAL) 신 호 를 보 낸 다음 전체 listening 의 socket 을 모두 닫 습 니 다.continue;
h) 하면, 만약, 만약...reconfigure 가 1 (ngx signal value (NGX RECONFIGURE SIGNAL) 신호 대응) 이면 config 파일 을 다시 읽 습 니 다.ngx 다시 만 들 고 초기 화cycle 대상, work 프로 세 스 를 시작 하고 버퍼 관리 프로 세 스 를 시작 합 니 다. live 를 1 로 설정 하고 ngx 를 호출 합 니 다.signal_worker_processes () 발송 ngxsignal_value (NGX SHUTDOWN SIGNAL) 신호;
i) ngx_new_binary 는 1 (새로 시작 한 프로 세 스 임 을 표시 합 니 다) 입 니 다. work 프로 세 스 를 시작 하고 버퍼 관리 프로 세 스 를 시작 한 다음 ngxnoaccepting 을 0 으로 설정 합 니 다.continue;
j) 하면, 만약, 만약...restart 는 1 (ngx noaccepting = 1 일 때 ngx restart 를 1 로 설정 하고 worker 를 다시 시작 합 니 다) 입 니 다. work 프로 세 스 를 시작 하고 버퍼 관리 프로 세 스 를 시작 합 니 다. live 는 1 로 설정 합 니 다.
k) 하면, 만약, 만약...reopen 이 1 (ngx signal value (NGX REOPEN SIGNAL) 신호 대응) 이면 로그 파일 을 다시 찾 아 ngx 를 호출 합 니 다.signal_worker_processes () 발송 ngxsignal_value (NGX REOPEN SIGNAL) 신호;
l) 하면, 만약, 만약...change_binary 는 1 (ngx signal value (NGX CHANGEBIN SIGNAL) 신호 대응), ngx 호출exec_new_binary () 새 프로 세 스 실행 하기;
m) 하면, 만약, 만약...noaccept 는 1 (ngx signal value (NGX NOACCEPT SIGNAL) 대응), ngxnoaccepting 을 1 로, ngx 호출signal_worker_processes () 발송 ngxsignal_value (NGX SHUTDOWN SIGNAL) 신호.
다음 절 에 서 는 하위 프로 세 스 생 성과 작업 을 계속 이야기 합 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.