우리는 프로세스와 스레드가 메모리와 기타 시스템 리소스를 소비하며 컨텍스트 전환이 필요하다는 것을 알고 있습니다. 대부분의 최신 서버는 수백 개의 프로세스 또는 스레드를 동시에 처리할 수 있지만 메모리가 고갈되면 성능이 저하되고 IO 로드가 높은 시간에는 컨텍스트 전환이 자주 발생합니다.
네트워크를 처리하는 일반적인 방법은 각 연결마다 프로세스나 스레드를 만드는 것입니다. 이 방법은 구현하기 쉽지만 확장하기가 어렵습니다.
그러면 Nginx는 어떻게 하는 걸까요? NGINX는 어떻게 작동하나요?
nginx가 시작된 후에는 마스터 프로세스와 여러 작업자 프로세스가 있습니다. 마스터 프로세스는 외부 세계로부터 신호 수신, 각 작업자 프로세스에 신호 보내기, 작업자 프로세스의 실행 상태 모니터링, 작업자 프로세스 종료 시 자동으로 새 작업자 프로세스 다시 시작 등 작업자 프로세스를 관리하는 데 사용됩니다. 비정상적인 상황). 기본 네트워크 이벤트는 작업자 프로세스에서 처리됩니다. 여러 작업자 프로세스는 P2P 방식으로 클라이언트의 요청을 놓고 동등하게 경쟁하며 각 프로세스는 서로 독립적입니다. 요청은 하나의 작업자 프로세스에서만 처리할 수 있으며 작업자 프로세스는 다른 프로세스의 요청을 처리할 수 없습니다. 작업자 프로세스 수는 설정할 수 있으며 일반적으로 머신의 CPU 코어 수와 일치하도록 설정합니다. 그 이유는 nginx의 프로세스 모델 및 이벤트 처리 모델과 불가분의 관계입니다. nginx의 프로세스 모델은 다음 그림으로 표현 가능하다.
작업자 프로세스는 마스터가 관리하는 것을 볼 수 있다. 마스터 프로세스는 외부 세계로부터 신호를 수신한 다음 신호를 기반으로 다양한 작업을 수행합니다. 따라서 nginx를 제어하려면 마스터 프로세스에 신호만 보내면 됩니다. 예를 들어, ./nginx -s reload는 nginx를 다시 시작하는 것입니다. 이 명령은 마스터 프로세스에 신호를 보냅니다. 먼저 신호를 받은 후 마스터 프로세스는 구성 파일을 다시 로드한 다음 새 프로세스를 시작합니다. 프로세스는 모든 이전 프로세스에 명예롭게 은퇴할 수 있다는 신호를 보냅니다. 새 프로세스가 시작된 후 새 요청을 받기 시작하지만 이전 프로세스는 마스터로부터 신호를 받은 후 더 이상 새 요청을 받지 않으며 현재 프로세스에서 처리되지 않은 모든 요청이 처리된 후 종료됩니다.
그렇다면 작업자 프로세스는 요청을 어떻게 처리합니까?
앞서 언급했듯이 작업자 프로세스는 동일하며 각 프로세스는 요청을 처리할 수 있는 동일한 기회를 갖습니다. 포트 80에서 http 서비스를 제공하고 연결 요청이 오면 각 프로세스가 연결을 처리할 수 있습니다. 먼저 마스터 프로세스에서 각 작업자 프로세스가 분기되어 마스터 프로세스에서 청취해야 할 소켓이 먼저 설정된 다음 여러 작업자 프로세스가 분기되어 각 작업자 프로세스가 이 소켓을 받아들일 수 있습니다(물론입니다. 동일한 소켓은 아니지만 각 프로세스의 소켓은 동일한 IP 주소와 포트를 모니터링합니다. 이는 네트워크 프로토콜에서 허용됩니다. nginx는 accept_mutex를 제공합니다. 이름에서 이것이 accept에 추가된 공유 잠금임을 알 수 있습니다. 이 잠금을 사용하면 동시에 Accpet을 연결하는 하나의 프로세스만 있게 됩니다. accept_mutex는 명시적으로 끌 수 있는 제어 가능한 옵션입니다. 기본적으로 켜져 있습니다. 작업자 프로세스가 연결을 수락하면 요청 읽기, 요청 구문 분석, 요청 처리, 데이터 생성을 시작한 다음 이를 클라이언트에 반환하고 마지막으로 연결을 끊습니다. 이것이 완전한 요청의 모습입니다. 요청이 작업자 프로세스에 의해 완전히 처리되고 하나의 작업자 프로세스에서만 처리되는 것을 볼 수 있습니다.
그렇다면 nginx가 이 프로세스 모델을 채택하면 어떤 이점이 있을까요?
1) 각 작업자 프로세스는 독립적이며 잠금이 필요하지 않으므로 잠금 오버헤드가 제거되고 프로그래밍이 단순해집니다.
2) 프로세스는 서로 독립적이며 서로 영향을 미치지 않습니다. 한 프로세스가 종료된 후(예: 예외 발생) 다른 프로세스는 정상적으로 작동하며 서비스가 중단되지 않습니다.
3) 컨텍스트 전환이 없어 불필요한 시스템 오버헤드 감소
Nginx는 Linux의 epoll과 같은 시스템 호출인 이벤트 중심 처리 메커니즘을 사용합니다. 여러 이벤트를 동시에 모니터링할 수 있으며, 타임아웃 시간 내에 이벤트가 준비되면 준비된 이벤트를 반환합니다. 이런 식으로 이벤트가 준비되면 처리하고, 모든 이벤트가 준비되지 않은 경우에만 epoll에서 차단하고 대기합니다. 이런 식으로 높은 동시성 처리를 수행할 수 있습니다. 전환은 이벤트가 준비되지 않아 적극적으로 포기하기 때문입니다. 여기서 전환하는 데는 비용이 들지 않으며, 준비된 여러 이벤트를 루프에서 처리하는 것으로 간단히 이해하면 됩니다.
멀티스레딩에 비해 이 이벤트 처리 방법은 스레드를 생성할 필요가 없고, 각 요청이 매우 적은 메모리를 차지하며, 컨텍스트 전환이 없고, 이벤트 처리가 매우 가볍다는 장점이 있습니다. 동시성이 아무리 많아도 불필요한 리소스 낭비(컨텍스트 전환)가 발생하지 않습니다. 더 많은 동시성은 더 많은 메모리를 차지할 뿐이며, 이는 nginx가 효율적인 성능을 갖는 주된 이유이기도 합니다.
다음은 Nginx 공식 웹사이트에서 가져온 것입니다:
NGINX 서버가 활성화되면 작업자 프로세스만 사용 중입니다. 각 작업자 프로세스는 비차단 방식으로 여러 연결을 처리하여 컨텍스트 전환 수를 줄입니다.
각 작업자 프로세스는 단일 스레드로 독립적으로 실행되어 새로운 연결을 확보하고 이를 처리합니다. 프로세스는 공유 캐시 데이터, 세션 지속성 데이터 및 기타 공유 리소스를 위한 공유 메모리를 사용하여 통신할 수 있습니다.
각 NGINX 작업자 프로세스는 다음과 같습니다. NGINX 구성으로 초기화되고 마스터 프로세스에 의해 청취 소켓 세트가 제공됩니다.
NGINX 작업자 프로세스는 청취 소켓(accept_mutex 및 커널 소켓 샤딩)에서 이벤트를 기다리는 것으로 시작됩니다. 이벤트는 새로 들어오는 연결에 의해 시작됩니다. 이러한 연결은 상태 머신에 할당됩니다. HTTP 상태 머신이 가장 일반적으로 사용되지만 NGINX입니다. 또한 스트림(원시 TCP) 트래픽과 다양한 메일 프로토콜(SMTP, IMAP 및 POP3)에 대한 상태 시스템을 구현합니다.
저작권 설명: 이 문서는 블로거이며 블로거의 허락 없이는 복제가 허용되지 않습니다.
위 내용은 다양한 측면을 포함하여 Nginx2의 작동 메커니즘을 소개합니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되기를 바랍니다.