Nginx 소스 코드 학습 - 프로 세 스 통신
8318 단어 NginxNginx 소스 코드 학습
Linux 신호
Linux 시스템 과 Nginx 는 신 호 를 통 해 통신 합 니 다. 예 를 들 어 Linux 명령 줄 에서 두 드 리 는 것 입 니 다. / nginx - s stop 은 실제 시스템 에서 Master 프로 세 스 를 새로 엽 니 다. 이 프로 세 스 는 원래 Master 에 신 호 를 보 내 고 신 호 를 보 내 면 이 프로 세 스 가 끊 깁 니 다. 원래 Master 프로 세 스 는 신 호 를 받 은 후에 해당 하 는 작업 을 수행 합 니 다.
1. 신호 정의 및 등록
Nginx 는 ngx 를 정의 합 니 다.signal_t 구조 체 는 신 호 를 받 는 행 위 를 설명 하 는 데 사용 된다.
typedef struct { //signals
int signo; //
char *signame; //
char *name; // Nginx
void (*handler)(int signo); // signo handler
} ngx_signal_t;
Nginx 는 시작 할 때 ngx 를 호출 합 니 다.init_signals 함수, 이 함 수 는 sigaction 시스템 호출 을 통 해 모든 신 호 를 초기 화하 고 해당 하 는 신호 처리 함 수 를 등록 합 니 다.모든 초기 화 작업 이 완료 되면 Master 프로 세 스 가 ngx 를 호출 합 니 다.master_process_cycle 함수 가 자체 이벤트 순환 에 들 어가 신 호 를 감청 하고 신 호 를 받 으 면 대응 하 는 신호 처리 함 수 를 실행 합 니 다.
ngx_int_t ngx_init_signals(ngx_log_t *log)
{
ngx_signal_t *sig;
struct sigaction sa;
for (sig = signals; sig->signo != 0; sig++) {
ngx_memzero(&sa, sizeof(struct sigaction));
sa.sa_handler = sig->handler;
sigemptyset(&sa.sa_mask);
if (sigaction(sig->signo, &sa, NULL) == -1) {
#if (NGX_VALGRIND)
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
"sigaction(%s) failed, ignored", sig->signame);
#else
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
"sigaction(%s) failed", sig->signame);
return NGX_ERROR;
#endif
}
}
return NGX_OK;
}
2. 신호 전송
실행. / nginx - s stop 명령 을 실행 하면 새로운 Master 프로 세 스 가 시 작 됩 니 다. 이 프로 세 스 는 - s 매개 변수 에 따라 사용자 가 Nginx 에 신 호 를 보 내야 한 다 는 것 을 알 고 ngx 를 통 해get_options () 함수 가 보 낼 신 호 를 분석 한 후 ngx 를 실행 합 니 다.signal_process () 함수, 이 함 수 는 먼저 원래 Master 프로 세 스 의 pid 를 가 져 온 다음 에 원래 Master 프로 세 스에 구체 적 인 신 호 를 보 내 통신 을 완성 합 니 다.
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
/*
reload reload nginx master+worker master reload , master , worker , worker
quit , , , worker 。 ngx_signal_handler
*/
|| ngx_strcmp(ngx_signal, "reload") == 0)
{
ngx_process = NGX_PROCESS_SIGNALLER;
goto next;
}
/*
:
ngx_core_module ngx_core_conf_t;
, "/usr/local/nginx/logs/nginx.pid"( nginx ID, pid);
, pid;
ngx_os_signal_process() ;
*/
ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig)
{
...
// master NGX_PID_PATH
file.name = ccf->pid;
file.log = cycle->log;
file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY,
NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS);
if (file.fd == NGX_INVALID_FILE) {
ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
ngx_open_file_n " \"%s\" failed", file.name.data);
return 1;
}
n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0);
if (ngx_close_file(file.fd) == NGX_FILE_ERROR) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_close_file_n " \"%s\" failed", file.name.data);
}
if (n == NGX_ERROR) {
return 1;
}
while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ }
pid = ngx_atoi(buf, ++n); //master id
if (pid == NGX_ERROR) {
ngx_log_error(NGX_LOG_ERR, cycle->log, 0,
"invalid PID number \"%*s\" in \"%s\"",
n, buf, file.name.data);
return 1;
}
return ngx_os_signal_process(cycle, sig, pid);
}
Channel
Nginx 에 서 는 socketpair () 함 수 를 이용 하여 서로 연 결 된 socket 을 만 들 고 부자 프로 세 스 의 통신 을 실현 합 니 다. 즉, Master 프로 세 스 와 Worker 프로 세 스 의 통신 을 실현 합 니 다. Nginx 에 서 는 이러한 통신 을 채널 - channel 로 정의 합 니 다.
1. channel 정의
typedef struct {
ngx_uint_t command; // NGX_CMD_OPEN_CHANNEL
ngx_pid_t pid; // id ID, ID
ngx_int_t slot; // ngx_processes
ngx_fd_t fd; // fd
} ngx_channel_t;
2. channel 등록
Master 프로 세 스 는 fork () 함 수 를 통 해 하위 프로 세 스 를 만 듭 니 다. fork 전에 socketpair () 를 사용 하여 연 결 된 소켓 을 만 듭 니 다. 부자 프로 세 스 간 통신 에 사용 되 며, 하위 프로 세 스 도 이 소켓 을 얻 을 수 있 습 니 다. 하위 프로 세 스 가 초기 화 될 때 소켓 을 epoll 에 추가 하여 부모 프로 세 스 의 메 시 지 를 기다 리 고 메시지 처리 함 수 를 등록 합 니 다.부모 프로 세 스 통과 ngxwrite_channel () 메 시 지 를 보 내 고 하위 프로 세 스 는 ngxread_channel () 에서 메 시 지 를 읽 습 니 다.
ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
char *name, ngx_int_t respawn) //respawn NGX_PROCESS_RESPAWN , ngx_processes[]
{
...
if (socketpair(AF_UNIX, SOCK_STREAM, 0, ngx_processes[s].channel) == -1) // ngx_worker_process_init
{
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"socketpair() failed while spawning \"%s\"", name);
return NGX_INVALID_PID;
}
/* master channel[0]( ),channel[1]( ) */
if (ngx_nonblocking(ngx_processes[s].channel[0]) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_nonblocking_n " failed while spawning \"%s\"",
name);
ngx_close_channel(ngx_processes[s].channel, cycle->log);
return NGX_INVALID_PID;
}
if (ngx_nonblocking(ngx_processes[s].channel[1]) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
ngx_nonblocking_n " failed while spawning \"%s\"",
name);
ngx_close_channel(ngx_processes[s].channel, cycle->log);
return NGX_INVALID_PID;
}
...
pid = fork();
}
static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_int_t worker)
{
// epoll add ngx_chanel epoll
if (ngx_add_channel_event(cycle, ngx_channel, NGX_READ_EVENT,
ngx_channel_handler) // ngx_spawn_process
== NGX_ERROR)
{
/* fatal */
exit(2);
}
}
공유 메모리
Nginx 에서 각 Worker 프로 세 스 는 공유 메모 리 를 통 해 통신 합 니 다. 공유 메모 리 는 Linux 에서 제공 하 는 가장 기본 적 인 프로 세 스 간 통신 방식 입 니 다. mmap 와 shmget 시스템 호출 을 통 해 메모리 에 연속 적 인 선형 주소 공간 을 만 들 었 고 munmap 또는 shmdt 시스템 호출 을 통 해 이 메모 리 를 방출 할 수 있 습 니 다.공유 메모 리 를 사용 하 는 장점 은 여러 프로 세 스 가 같은 공유 메모 리 를 사용 할 때 모든 프로 세 스 가 공유 메모리 의 내용 을 수정 한 후에 다른 프로 세 스 가 이 공유 메모리 에 접근 하면 수 정 된 내용 을 얻 을 수 있다 는 것 이다.
Nginx 는 ngx 를 정의 합 니 다.shm_t 구조 체, 공유 메모리 설명 에 사용
typedef struct {
u_char *addr; //
size_t size; //
ngx_str_t name; //
ngx_log_t *log; //shm.log = cycle->log; ngx_log_t
ngx_uint_t exists; /* unsigned exists:1; */ // , 1
} ngx_shm_t;
조작 ngxshm_t 구조 체 의 방법 은 두 가지 가 있다. ngxshm_alloc (mmap 기반 구현) 는 새로운 공유 메모리 할당 에 사용 되 며, ngxshm_free (munmap 기반) 는 이미 존재 하 는 공유 메모 리 를 방출 하 는 데 사 용 됩 니 다.공유 메모 리 는 Master 프로 세 스 가 만 들 고 Worker 프로 세 스 가 공유 합 니 다.Nginx 놀 라 운 문 제 를 해결 하 는 것 은 상호 배척 자 물 쇠 를 설정 함으로써 상호 배척 자 물 쇠 를 가 진 작업 프로 세 스 만 이 고객 과 연결 하 는 임 무 를 맡 을 수 있 고 이 상호 배척 자 물 쇠 는 공유 메모리 에 넣 습 니 다.또한 ngin 은 연결 수 를 집계 하고 이 전역 변 수 는 공유 메모리 에 도 넣 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
linux2에 nginx 설치설치 가능한 nginx를 확인하고, 해당 nginx를 설치한다. localhost 혹은 해당 ip로 접속을 하면 nginx 화면을 볼 수 있다....
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.