Nginx 소스 코드 연구 2: NGINX 의 사건 처리 개론
15829 단어 nginx
이 안에서 두 가지 개념 과 관련 되 는데 하 나 는 사용자 상태 이 고 하 나 는 커 널 상태 이다.응용 프로그램 은 시스템 호출 함 수 를 통 해 커 널 공간 에 들 어가 고 커 널 운행 은 데이터 준비 와 데이터 복사 등 작업 을 한다.NGINX 에 있어 그 는 응용 프로그램 과 운영 체제 의 상호작용, 즉 사용자 상태 와 커 널 상태 간 의 상호작용 이다. NGINX 와 커 널 의 상호작용 방식 이 매우 많다. 예 를 들 어 open (), read () 등 은 모두 커 널 과 상호작용 을 하고 있다. 인터넷 IO 에 있어 우 리 는 Liux 에서 의 네트워크 IO 가 주로 다섯 가지 가 있다 는 것 을 알 고 있다.
첫째, IO 를 막 고 응용 프로그램 은 커 널 함 수 를 호출 하여 커 널 이 데이터 준비 와 데이터 복사 전 과정 을 막 습 니 다.
둘째, 비 차단 IO 입 니 다. 응용 프로그램 은 커 널 함 수 를 호출 하여 커 널 데이터 가 준비 되 어 있 는 지, 커 널 데이터 가 준비 되 어 있 을 때 까지 계속 확인 하고 커 널 이 데이터 복사 가 완 료 될 때 까지 차단 합 니 다.
세 번 째 는 I / O 재 활용 입 니 다. 응용 프로그램 은 커 널 파 라 메 터 를 호출 하여 커 널 의 관심 사 를 알 립 니 다. 커 널 은 이 사건 에 준 비 된 데 이 터 를 받 은 후에 응용 프로그램 에 알 립 니 다. 응용 프로그램 은 커 널 의 데이터 복사 가 완 료 될 때 까지 막 습 니 다. 일반 웹 서버 는 이러한 IO 모델 을 사용 합 니 다. 예 를 들 어 Apache 가 사용 하 는 select / poll, 물론 nginx 도 select / poll 을 지원 하지만 Liux 2.6 이후 에...NGINX 는 보통 epoll 을 선택한다.
네 번 째 는 신호 입 니 다. 응용 프로그램 은 신호 처리 함 수 를 설치 하고 운행 과정 이 막 히 지 않 습 니 다. 운영 시스템 은 데 이 터 를 준비 한 후에 응용 프로그램 에 신 호 를 보 냅 니 다. 응용 프로그램의 신호 처리 함 수 는 IO 처 리 를 할 수 있 습 니 다.
다섯 번 째 비동기, 응용 프로그램 은 운영 체제 에서 제공 하 는 비동기 IO 함수, 예 를 들 어 ao 를 호출 합 니 다.read。
운영 체제 가 보 낸 요청 은 즉시 되 돌아 갈 필요 가 없 음 을 알 리 고 운영 체제 가 데이터 준비 와 데이터 복사 가 끝 난 후에 응용 프로그램 이 시스템 호출 함수 로 지정 한 신 호 를 알 립 니 다.
실제 네트워크 I / O 모델 에서 앞의 네 가 지 는 모두 동기 모델 이 고 다섯 번 째 는 비동기 모델 이다.
NGINX 의 module 에서 지원 하 는 IO 모델 부터 살 펴 보 겠 습 니 다.
|-- event
| |-- modules
| | |-- ngx_aio_module.c
| | |-- ngx_devpoll_module.c
| | |-- ngx_epoll_module.c
| | |-- ngx_eventport_module.c
| | |-- ngx_kqueue_module.c
| | |-- ngx_poll_module.c
| | |-- ngx_rtsig_module.c
| | |-- ngx_select_module.c
| | `-- ngx_win32_select_module.c
이 장 에 서 는 NGINX 가 epoll 을 인터넷 IO 로 사용 하 는 것 을 중점적으로 연구 할 것 이다.
NGINX 는 네트워크 IO 를 하 는데 세 개의 모듈 과 관련된다.
모듈 이름
유형
소재 파일
ngx_events_module
NGX_CORE_MODULE
ngx_event.c
ngx_event_core_module
NGX_EVENT_MODULE
ngx_event.c
ngx_epoll_module
NGX_EVENT_MODULE
module/ngx_epoll_module.c
지난 장 에 서 는 module 의 시작 과정 을 언급 하 였 으 며, initcycle 함수, 대 ngxevents_module 의 설정 정보 가 생 성 되 었 습 니 다. 설정 파일 을 분석 하여 ngx 를 호출 합 니 다.events_commands 대 NGXEVENT_MODULE 은 설정 정보의 생 성, 분석, 초기 화 를 했다.
1. master - work 작업 모델 의 처리 과정
설정 정 보 를 처리 한 후에 프로 세 스 의 처리 과정 을 살 펴 보 겠 습 니 다.
1、 저 희 는 master - work 작업 모드 를 선택 하 겠 습 니 다.
ngx_master_process_cycle(ngx_cycle_t *cycle)
{
......
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
ngx_start_cache_manager_processes(cycle, 0);
......
}
2、
static void
ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
{
ngx_int_t i;
ngx_channel_t ch;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
ch.command = NGX_CMD_OPEN_CHANNEL;
for (i = 0; i < n; i++) {
ngx_spawn_process(cycle, ngx_worker_process_cycle,
(void *) (intptr_t) i, "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);
}
}
3、
//
ngx_pid_t
ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
char *name, ngx_int_t respawn)
{
……
pid = fork();
switch (pid) {
case -1:
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"fork() failed while spawning \"%s\"", name);
ngx_close_channel(ngx_processes[s].channel, cycle->log);
return NGX_INVALID_PID;
case 0: // proc
ngx_pid = ngx_getpid();
proc(cycle, data);
break;
default: //
break;
}
……
return pid;
}
4、
static void
ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
{
……
ngx_worker_process_init(cycle, worker);
ngx_setproctitle("worker process");
……
for ( ;; ) {
……
ngx_process_events_and_timers(cycle);
……
}
}
5、
static void
ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
{
……
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_process) {
if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
/* fatal */
exit(2);
}
}
}
……
if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
ngx_channel_handler)
== NGX_ERROR)
{
/* fatal */
exit(2);
}
}
6、
static ngx_int_t
ngx_event_process_init(ngx_cycle_t *cycle)
{
......
// module action
......
cycle->connections =
ngx_alloc(sizeof(ngx_connection_t) * cycle->connection_n, cycle->log);
if (cycle->connections == NULL) {
return NGX_ERROR;
}
c = cycle->connections;
cycle->read_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
cycle->log);
if (cycle->read_events == NULL) {
return NGX_ERROR;
}
rev = cycle->read_events;
for (i = 0; i < cycle->connection_n; i++) {
rev[i].closed = 1;
rev[i].instance = 1;
#if (NGX_THREADS)
rev[i].lock = &c[i].lock;
rev[i].own_lock = &c[i].lock;
#endif
}
cycle->write_events = ngx_alloc(sizeof(ngx_event_t) * cycle->connection_n,
cycle->log);
if (cycle->write_events == NULL) {
return NGX_ERROR;
}
wev = cycle->write_events;
for (i = 0; i < cycle->connection_n; i++) {
wev[i].closed = 1;
#if (NGX_THREADS)
wev[i].lock = &c[i].lock;
wev[i].own_lock = &c[i].lock;
#endif
}
i = cycle->connection_n;
next = NULL;
do {
i--;
c[i].data = next;
c[i].read = &cycle->read_events[i];
c[i].write = &cycle->write_events[i];
c[i].fd = (ngx_socket_t) -1;
next = &c[i];
#if (NGX_THREADS)
c[i].lock = 0;
#endif
} while (i);
cycle->free_connections = next;
cycle->free_connection_n = cycle->connection_n;
/* for each listening socket */
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
......
rev->handler = ngx_event_accept;
if (ngx_use_accept_mutex) {
continue;
}
if (ngx_event_flags & NGX_USE_RTSIG_EVENT) {
if (ngx_add_conn(c) == NGX_ERROR) {
return NGX_ERROR;
}
} else {
if (ngx_add_event(rev, NGX_READ_EVENT, 0) == NGX_ERROR) {
return NGX_ERROR;
}
}
#endif
}
return NGX_OK;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 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에 따라 라이센스가 부여됩니다.