nginx 네트워크 계층 분석

4271 단어
최근 에 고성능 오픈 소스 http 서버 nginx 의 소스 코드 를 읽 었 습 니 다. 전체 코드 가 10w 줄 에 가 깝 기 때문에 제 가 관심 이 있 는 네트워크 계층 의 연결 처 리 를 먼저 분석 할 수 밖 에 없습니다.
먼저 주 함수 main 에서 들 어가 면 앞의 설정 초기 화 는 생략 하고 다음 코드 를 볼 수 있 습 니 다.
    if (ngx_process == NGX_PROCESS_SINGLE) {
        ngx_single_process_cycle(cycle);

    } else {
        ngx_master_process_cycle(cycle);
    }
일반적으로 다 중 프로 세 스 를 사용 하여 처리 합 니 다. 즉, ngx 를 실행 하 는 것 입 니 다.master_process_cycle(cycle);그리고 함수 에 들 어가 서 이 코드 를 보 았 습 니 다.
    ngx_start_worker_processes(cycle, ccf->worker_processes,
                               NGX_PROCESS_RESPAWN);

워 커 서브 프로 세 스 를 시작 하 는 것 입 니 다. nginx 는 여러 워 커 프로 세 스 를 사용 하여 연결 을 처리 한 다음 master 메 인 프로 세 스 를 관리 합 니 다.함수 에 들 어가 기:
    for (i = 0; i < n; i++) {

        cpu_affinity = ngx_get_cpu_affinity(i);

        ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL,
                          "worker process", type);

        ch.pid = ngx_processes[ngx_process_slot].pid;
        ch.slot = ngx_process_slot;
        ch.fd = ngx_processes[ngx_process_slot].channel[0];

        ngx_pass_open_channel(cycle, &ch);
    }
ngxspawn_process(cycle, ngx_worker_process_cycle, NULL,  "worker process", type);함수, 워 커 프로 세 스 몇 개 만 들 기, ngxworker_process_cycle 는 함수 포인터 로 워 커 의 실제 작업 함수 입 니 다.
이어서 ngx 진입worker_process_cycle 함수 에서:
#if (NGX_THREADS)
    {
    ngx_int_t         n;
    ngx_err_t         err;
    ngx_core_conf_t  *ccf;

    ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);

    if (ngx_threads_n) {
        if (ngx_init_threads(ngx_threads_n, ccf->thread_stack_size, cycle)
            == NGX_ERROR)
        {
            /* fatal */
            exit(2);
        }

        err = ngx_thread_key_create(&ngx_core_tls_key);
        if (err != 0) {
            ngx_log_error(NGX_LOG_ALERT, cycle->log, err,
                          ngx_thread_key_create_n " failed");
            /* fatal */
            exit(2);
        }

        for (n = 0; n < ngx_threads_n; n++) {

            ngx_threads[n].cv = ngx_cond_init(cycle->log);

            if (ngx_threads[n].cv == NULL) {
                /* fatal */
                exit(2);
            }

            if (ngx_create_thread((ngx_tid_t *) &ngx_threads[n].tid,
                                  ngx_worker_thread_cycle,
                                  (void *) &ngx_threads[n], cycle->log)
                != 0)
            {
                /* fatal */
                exit(2);
            }
        }
    }
    }
#endif

프로 세 스 에서 다 중 스 레 드 처리 방식 을 사용 하면 ngx 를 호출 합 니 다.worker_thread_cycle 처리.
함수 안 을 다시 보고 함수 가 순환 에 들 어가 순환 안의 ngx 를 봅 니 다.process_events_and_timers(cycle);함수, 안 에는 프로 세 스 가 각종 사건 을 처리 하 는 위치 가 있 습 니 다.함수 에 들 어가 면 다음 코드 를 볼 수 있 습 니 다:
    if (ngx_use_accept_mutex) {
        if (ngx_accept_disabled > 0) {
            ngx_accept_disabled--;

        } else {
            if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {
                return;
            }

            if (ngx_accept_mutex_held) {
                flags |= NGX_POST_EVENTS;

            } else {
                if (timer == NGX_TIMER_INFINITE
                    || timer > ngx_accept_mutex_delay)
                {
                    timer = ngx_accept_mutex_delay;
                }
            }
        }
    }

여 기 는 linux 2.6 이하 입 니 다.
자 물 쇠 를 얻 으 면 accept 처 리 를 하고 자 물 쇠 를 풀 어 줍 니 다.
    if (ngx_posted_accept_events) {
        ngx_event_process_posted(cycle, &ngx_posted_accept_events);
    }

    if (ngx_accept_mutex_held) {
        ngx_shmtx_unlock(&ngx_accept_mutex);
    }

마지막 으로 각종 이벤트 처리 (void) ngxprocess_events(cycle, timer, flags);
    if (ngx_posted_events) {
        if (ngx_threaded) {
            ngx_wakeup_worker_thread(cycle);

        } else {
            ngx_event_process_posted(cycle, &ngx_posted_events);
        }
    }
이로써 nginx 의 전체 네트워크 층 이 연결 을 대충 처리 하 는 방식 을 볼 수 있 습 니 다. 여러 프로 세 스 를 미리 할당 하 는 동시에 accept 의 처리 방식 도 볼 수 있 습 니 다.

좋은 웹페이지 즐겨찾기