nginx 소스 학습 노트 (15) - ngxmaster_process_cycle 다 중 프로 세 스 (1)

core 모듈 을 이해 하기 전에 ngx 를 배 워 야 합 니 다.start_worker_processes 함수, 오늘 이 방법 을 자세히 배 워 보 겠 습 니 다. 주요 내용 은...http://blog.sina.com.cn/s/blog_677be95b0100iivk.html。
 
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) 신호.
 
다음 절 에 서 는 하위 프로 세 스 생 성과 작업 을 계속 이야기 합 니 다.

좋은 웹페이지 즐겨찾기