Nginx 의 구조 소개 Nginx 2 편

3039 단어 nginx
Nginx 는 여러 프로 세 스 방식 으로 병행 작업 을 완성 합 니 다.nginx 가 시작 되면 master 프로 세 스 와 여러 worker 프로 세 스 가 있 습 니 다.모든 워 커 프로 세 스 는 클 라 이언 트 로부터 몇 개의 요청 을 처리 합 니 다.워 커 프로 세 스 간 의 위 치 는 같 습 니 다. 워 커 의 개 수 를 cpu 의 핵 으로 설정 하 는 것 을 추천 합 니 다.하나의 요 구 는 하나의 워 커 만 책임 질 수 있 고 중복 되 는 일 을 할 수 없다.
    master 프로 세 스 는 주로 worker 프로 세 스 를 관리 하 는 데 사 용 됩 니 다. 외부 (관리자) 로부터 신 호 를 받 고 각 worker 프로 세 스 에 신 호 를 보 내 며 worker 프로 세 스 의 운행 상 태 를 감시 합 니 다. worker 프로 세 스 가 종료 되면 (이상 한 경우) 새로운 worker 프로 세 스 를 자동 으로 다시 시작 합 니 다.
문제 1: 여러 워 커 프로 세 스 가 요청 을 어떻게 처리 합 니까?
    모든 worker 프로 세 스 는 master 프로 세 스 fork 에서 온 하위 프로 세 스 입 니 다. master 프로 세 스에 서 먼저 listen 이 필요 한 socket 을 만 든 다음 에 fork 에서 여러 개의 worker 프로 세 스 를 만 듭 니 다. 그러면 모든 worker 프로 세 스 는 accept 이 socket (즉, 모든 프로 세 스 의 이 socket 은 같은 ip 주소 와 포트 에 감 측 됩 니 다).특별한 처 리 를 하지 않 으 면 요청 이 오 면 한 명의 워 커 만 accept 에 성공 하고 다른 모든 워 커 는 accept 에 실패 합 니 다 (놀 라 운 현상).Nginx 는 이 를 피하 기 위해 accept 를 제공 합 니 다.mutex, 모든 worker 의 accept 에 공유 자 물 쇠 를 추가 합 니 다.
    현재 대부분의 커 널 이 놀 라 운 문 제 를 해결 한 것 같 습 니 다. 저 는 mac osx 10.9 에서 테스트 를 했 습 니 다. 두 프로 세 스 가 같은 소켓 을 감청 하고 있 습 니 다. 요청 에 왔 을 때 하나의 프로 세 스 만 이 이 요청 을 처리 하 는 것 을 깨 웠 습 니 다.
#include<iostream>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>
using namespace std;

int main()
{	
	int socket_listen, socket_data, c, read_size;
	struct sockaddr_in server, client;
	char client_message[2000];
	socket_listen = socket(AF_INET, SOCK_STREAM, 0);
	if(socket_listen == -1)
		cout<<"create socket fail!"<<endl;
	server.sin_family = AF_INET;
	server.sin_addr.s_addr = INADDR_ANY;
	server.sin_port = htons(8888);
	if(bind(socket_listen, (struct sockaddr*)&server, sizeof(server)) < 0)
		cout<<"bind fail!"<<endl;
	listen(socket_listen, 5);
	c = sizeof(struct sockaddr_in);

	if(fork() != 0)
	{
		cout<<"father will accept."<<endl;
		socket_data = accept(socket_listen, (struct sockaddr*)&client, (socklen_t*)&c);
		cout<<"this is father."<<endl;
	}
	else
	{
		cout<<"son will accept."<<endl;
		socket_data = accept(socket_listen, (struct sockaddr*)&client, (socklen_t*)&c);
		cout<<"this is son."<<endl;
	}

	return 0;
}

프로그램 이 실 행 된 후에 터미널 을 바 꾸 면 lsof - i: 8888 로 두 프로 세 스 가 감청 하 는 로 컬 8888 포트 를 볼 수 있 습 니 다.
telnet localhost 8888
첫 번 째 방문, 부모 프로 세 스 가 자극 되 었 습 니 다.두 번 째 방문, 하위 프로 세 스 가 자극 되 었 습 니 다.내부 핵 에 이 문제 가 존재 하지 않 는 다 는 것 을 알 수 있다.
문제 2: 왜 nginx 의 높 은 병행 이 가능 합 니까?
    nginx 는 비동기 비 차단 방식 으로 요청 을 처리 합 니 다.뭐 가 막 혀?차단 은 프로 세 스 가 읽 기와 쓰기 이 벤트 를 기다 리 는 것 입 니 다. 이 기다 리 는 동안 프로 세 스 는 아무것도 하지 않 습 니 다. cpu 는 다른 프로 세 스에 양보 합 니 다.무엇이 비 차단 입 니까?이벤트 가 준비 되 지 않 았 습 니 다. 바로 EAGAIN (잠시 후에 다시) 으로 돌아 간 다음 에 계속 와 서 봐 야 합 니 다. 그러면 컨 텍스트 전환 의 대 가 를 초래 할 수 있 습 니 다.현재 사용 하고 있 는 메커니즘 은 이벤트 가 준비 되 지 않 았 을 때 epoll 에 넣 고 이벤트 가 준비 되면 읽 고 쓰 는 것 입 니 다.EAGAIN 으로 돌아 갈 때, 우 리 는 그것 을 다시 epoll 에 넣 었 다.이런 방식 은 하나의 스 레 드 가 끊임없이 전환 되 고 여러 요청 을 동시에 처리 할 수 있다.

좋은 웹페이지 즐겨찾기