nginx 학습 (2) - 기초 개념의 비동기 비 차단

6026 단어 nginx
이 장 은 타 오 바 오의 nginx 홈 페이지 nginx 플랫폼 초기 탐색 을 참고 합 니 다.
위 에서 nginx 에 관 한 프로 세 스 모델 을 많이 말 했 습 니 다. 다음은 nginx 가 사건 을 어떻게 처리 하 는 지 살 펴 보 겠 습 니 다.
어떤 사람 이 물 어 볼 수도 있 습 니 다. nginx 는 여러 worker 방식 으로 요 구 를 처리 합 니 다. 모든 worker 안에 하나의 메 인 스 레 드 만 있 습 니 다. 그러면 처리 할 수 있 는 병발 수 는 매우 제한 되 어 있 습 니 다. 몇 개의 worker 가 몇 개의 병발 을 처리 할 수 있 습 니까? 어떻게 높 은 병발 을 할 수 있 습 니까?뿐만 아니 라 이것 이 바로 nginx 의 뛰어난 점 입 니 다. nginx 가 사 용 했 습 니 다.
비동기 비 차단 방식 으로 요청 을 처리 합 니 다. 즉, nginx 는 수천 개의 요청 을 동시에 처리 할 수 있 습 니 다.apache 의 일반적인 작업 방식 을 생각해 보 세 요. (apache 도 비동기 비 차단 버 전이 있 지만 일부 모듈 과 충돌 하기 때문에 자주 사용 하지 않 습 니 다)
모든 요청 은 하나의 작업 스 레 드 를 독점 합 니 다. 병발 수가 수천 에 이 르 렀 을 때 동시에 수천 개의 스 레 드 가 요청 을 처리 합 니 다.이것 은 운영 체제 에 있어 적지 않 은 도전 입 니 다. 스 레 드 가 가 져 온 메모리 의 점용 이 매우 크 고 스 레 드 의 컨 텍스트 전환 이 가 져 온 cpu 의 비용 이 매우 많 으 며 자 연 스 러 운 성능 은 올 라 갈 수 없습니다. 이런 비용 은 전혀 의미 가 없습니다.
왜 nginx 는 비동기 비 차단 방식 으로 처리 할 수 있 습 니까? 아니면 비동기 비 차단 은 도대체 어떻게 된 일 입 니까?우 리 는 먼저 원점 으로 돌아 가 요청 의 전체 과정 을 보 았 다.우선 오 라 고 부탁 하고,
연결 을 만 든 다음 에 데 이 터 를 받 고 데 이 터 를 받 은 후에 데 이 터 를 보 내야 합 니 다.구체 적 으로 시스템 밑바닥 까지 는 바로 읽 기와 쓰기 사건 이다. 읽 기와 쓰기 사건 이 준비 되 지 않 았 을 때 반드시 조작 할 수 없다. 만약 에 막 히 지 않 는 방식 으로 호출 하지 않 으 면 호출 을 막 아야 한다. 사건 이 준비 되 지 않 았 을 때 기다 릴 수 밖 에 없다. 사건 이 준비 되면 계속 하 세 요.
호출 을 막 으 면 커 널 에 들 어가 서 기다 리 게 됩 니 다. cpu 는 다른 사람 에 게 사용 하 게 됩 니 다. 단일 스 레 드 의 worker 에 게 는 분명 적합 하지 않 습 니 다. 네트워크 이벤트 가 많 을 수록 모두 가 기다 리 고 있 습 니 다. cpu 는 비어 서 아무 도 사용 하지 않 습 니 다. cpu 의 이 용 률 은 자 연 스 럽 게 올 라 가지 않 습 니 다. 높 은 병발 은 말 할 것 도 없습니다.좋아,
추가 정 도 를 말 합 니 다. 이것 은 apache 의 스 레 드 모델 과 어떤 차이 가 있 습 니까? 불필요 한 컨 텍스트 전환 을 증가 하지 않도록 주의 하 십시오.그래서 nginx 에서 가장 차단 을 꺼 리 는 시스템 호출 입 니 다.막 지 마라, 그러면 막 지 않 겠 다.막 히 지 않 으 면 사건 이 준비 되 지 않 았 으 니 곧 EAGAIN 으로 돌아 가 사건 이 아직 준비 되 지 않 았 다 는 것 을 알려 드 리 겠 습 니 다. 뭘 당황 하 세 요? 이따가 다시 오 세 요.그래, 너 는 잠시 후에 사건 을 다시 한 번 검사 해 봐. 사건 이 준 비 될 때 까지 그 동안 너 는 먼저 다른 일 을 한 다음 에 사건 이 다 되 었 는 지 다시 한 번 볼 수 있어.비록... 일지 라 도
막 히 지 는 않 지만, 당신 은 때때로 와 서 사건 의 상 태 를 검사 해 야 합 니 다. 당신 은 더 많은 일 을 할 수 있 지만, 가 져 온 비용 도 적지 않 습 니 다.그래서 비동기 비 차단 이벤트 처리 체 제 를 가지 게 되 었 습 니 다. 구체 적 으로 시스템 호출 은 select / poll / epol / kqueue 와 같은 시스템 호출 입 니 다.그들 은 하나의 메커니즘 을 제공 했다.
여러 사건 을 동시에 감시 하고 호출 할 수 있 도록 하 는 것 은 막 힌 것 이지 만 시간 초과 시간 을 설정 할 수 있 습 니 다. 시간 초과 시간 안에 사건 이 준비 되면 돌아 갑 니 다.이러한 메커니즘 은 우리 위의 두 가지 문 제 를 해결 하 였 습 니 다. epoll 을 예 로 들 면 (뒤의 예 에서 우 리 는 epoll 을 예 로 들 어 이러한 함 수 를 대표 합 니 다) 사건 이 준비 되 지 않 았 을 때 epoll 에 넣 고 사건 이 준비 되 었 을 때 우 리 는 읽 고 쓰 고 읽 고 쓰기 가 EAGAIN 으로 돌아 갈 때 우 리 는 그것 을 다시 epoll 에 넣 었 습 니 다.이렇게 해서 사건 이 준비 되면 우 리 는 그것 을 처리 할 것 이다. 모든 사건 이 준비 되 지 않 았 을 때 만 epoll 에서 기다 릴 것 이다.이렇게 하면 우 리 는 대량의 병발 을 동시에 처리 할 수 있다. 물론,
여기 서 의 동시 요청 은 처리 되 지 않 은 요청 을 말 합 니 다. 스 레 드 는 하나 밖 에 없 기 때문에 동시에 처리 할 수 있 는 요청 은 당연히 하나 입 니 다. 요청 간 에 계속 전환 할 뿐 전환 도 비동기 사건 이 준비 되 지 않 았 기 때문에 주동 적 으로 양보 한 것 입 니 다.이곳 의 전환 은 아무런 대가 도 없다. 여러 준 비 된 사건 을 순환 적 으로 처리 하 는 것 으로 이해 할 수 있다. 사실은 이렇다.다 중 스 레 드 에 비해 이러한 이벤트 처리 방식 은 매우 큰 장점 을 가진다. 스 레 드 를 만 들 필요 가 없고 모든 요청 이 사용 하 는 메모리 도 적 으 며 문맥 전환 이 없 으 며 이벤트 처리 가 매우 경량급 이다.병발 수가 아무리 많아 도 불필요 한 자원 낭 비 를 초래 하지 않 을 것 이다.더 많은 병발 수 는 단지 더 많은 메모 리 를 차지 할 뿐이다.나 는 이전에 연결 수 를 테스트 한 적 이 있 는데 24G 메모리 의 기계 에서 처리 한 병렬 요청 수 는 200 만 에 달 했다.현재 의 네트워크 서버 는 기본적으로 이런 방식 을 채택 하고 있 는데 이것 도 nginx 의 성능 이 효율 적 인 주요 원인 이다.
전에 말씀 드 렸 듯 이 워 커 의 개 수 를 cpu 의 핵 으로 설정 하 는 것 을 추천 합 니 다. 여기 서 쉽게 이해 할 수 있 습 니 다. 더 많은 워 커 수 는 프로 세 스 가 cpu 자원 을 경쟁 하 게 만 들 고 불필요 한 컨 텍스트 전환 을 가 져 올 수 있 습 니 다.그리고 nginx 는 다 핵 특성 을 잘 이용 하기 위해 제공 했다.
cpu 친연 적 인 바 인 딩 옵션 을 사용 하면 특정한 프로 세 스 를 특정한 핵 에 연결 할 수 있 습 니 다. 프로 세 스 전환 으로 인해 cache 의 실 효 를 가 져 오지 않 습 니 다.이와 같은 작은 최 적 화 는 nginx 에서 흔히 볼 수 있 는 동시에 nginx 작가 의 고심 과 조예 도 설명 했다.예컨대
nginx 는 4 개의 바이트 문자열 을 비교 할 때 4 개의 문 자 를 int 형 으로 바 꾸 고 비교 하여 cpu 의 명령 수 를 줄 입 니 다.
nginx 가 왜 이런 프로 세 스 모델 과 이벤트 모델 을 선 택 했 는 지 알 게 되 었 습 니 다.기본 적 인 웹 서버 에 있어 서 이 벤트 는 보통 세 가지 유형 이 있 는데 그것 이 바로 네트워크 이벤트, 신호, 타이머 이다.위의 설명 에서 알 수 있 듯 이 인터넷 사건 은 비동기 비 차단 을 통 해 잘 해결 할 수 있다.어떻게 신호 와 타 이 머 를 처리 합 니까?
우선 신호 처리.nginx 에 대해 말하자면 특정한 신호 가 있 는데 특정한 의 미 를 대표 한다.신 호 는 프로그램의 현재 운행 을 중단 하고 상 태 를 바 꾼 후에 계속 실 행 됩 니 다.시스템 호출 이 라면 시스템 호출 에 실패 할 수 있 으 므 로 다시 들 어가 야 합 니 다.신호 처리 에 관 해 서 는 전문 서적 을 배 울 수 있 습 니 다. 여 기 는 많 지 않 습 니 다.nginx 에 게 nginx 가 이벤트 (epoll wait) 를 기다 리 고 있 을 때 프로그램 이 신 호 를 받 으 면 신호 처리 함수 가 처 리 된 후 epollwait 는 오 류 를 되 돌려 주 고 프로그램 은 epoll 에 다시 들 어 갈 수 있 습 니 다.wait 호출.
또 타 이 머 를 살 펴 보 자.epoll 때문에wait 등 함수 가 호출 될 때 시간 초과 시간 을 설정 할 수 있 기 때문에 nginx 는 이 시간 초과 시간 을 통 해 타 이 머 를 실현 합 니 다.nginx 의 타이머 이 벤트 는 타이머 유지 보수 의 붉 은 검 은 나무 에 놓 여 있 습 니 다. 매번 epoll 에 들 어 갈 때마다wait 전에 이 붉 은 검 은 나무 에서 모든 타이머 이벤트 의 최소 시간 을 가 져 와 epoll 를 계산 합 니 다.wait 의 시간 초과 후 epoll 입장wait。그래서 사건 이 발생 하지 않 고 신 호 를 중단 하지 않 았 을 때 epollwait 시간 초과, 즉 타이머 이벤트 가 도 착 했 습 니 다.이 때 nginx 는 모든 시간 초과 사건 을 검사 하고 그들의 상 태 를 시간 초과 로 설정 한 다음 에 네트워크 사건 을 처리 합 니 다.이 를 통 해 알 수 있 듯 이 우리 가 nginx 코드 를 쓸 때 네트워크 이벤트 의 반전 함 수 를 처리 할 때 보통
첫 번 째 일 은 시간 초과 판단 을 한 뒤 인터넷 사건 을 처리 하 는 것 이다.
우 리 는 가짜 코드 로 nginx 의 사건 처리 모델 을 정리 할 수 있다.
while (true) {
    for t in run_tasks:
        t.handler();
    update_time(&now);
    timeout = ETERNITY;
    for t in wait_tasks: /* sorted already */
        if (t.time <= now) {
            t.timeout_handler();
        } else {
            timeout = t.time - now;
            break;
        }
    nevents = poll_function(events, timeout);
    for i in nevents:
        task t;
        if (events[i].type == READ) {
            t.handler = read_handler;
        } else { /* events[i].type == WRITE */
            t.handler = write_handler;
        }
        run_tasks_add(t);
}

요약:
IO 밀집 형 장면 에서 IO 를 막 으 면 CPU 가 양보 되 고 nginx 의 Worker 는 단일 스 레 드 (IO 를 하고 있 으 며 다른 것 은 아무것도 할 수 없다) 로 인해 CPU 이 용 률 이 떨어진다.
이 때 프로 세 스 를 추가 하면 아파 치 의 스 레 드 모델 과 마찬가지 로 불필요 한 컨 텍스트 전환 이 추 가 됩 니 다.
동기 화 비 차단, 즉시 EAGAIN 으로 돌아 가 데이터 가 준비 되 지 않 아 다른 일 을 할 수 있 음 을 알 리 지만 문의 가 필요 합 니 다.
비동기 비 차단 은 여러 사건 을 동시에 감시 할 수 있 습 니 다. 호출 할 때 시간 초과 가 있 는 차단 입 니 다. 준비 가 되면 돌아 갑 니 다. epoll 에 넣 고 기다 릴 준비 가 되 지 않 았 습 니 다.여기 Worker 는 단일 스 레 드 입 니 다. 처리 할 수 있 는 요청 은 하나 뿐 이지 만 요청 사이 에서 전환 합 니 다. 이 전환 은 비용 이 들 지 않 습 니 다. 비동기 이벤트 가 준비 되 지 않 아 자동 으로 양보 합 니 다.

좋은 웹페이지 즐겨찾기