1. 솔루션
각 작업자 프로세스가 생성되면 ngx_worker_process_init() 메서드가 호출되어 현재 작업자 프로세스를 초기화합니다. 이 프로세스에는 매우 중요한 단계가 있습니다. 즉, 각 작업자 프로세스가 epoll_create를 호출합니다. () 메소드는 자체적으로 고유한 epoll 핸들을 생성합니다. 모니터링해야 하는 각 포트에는 이에 해당하는 파일 설명자가 있으며 작업자 프로세스는 epoll_ctl() 메서드를 통해 현재 프로세스의 epoll 핸들에 파일 설명자를 추가하고 accept 이벤트를 수신하기만 합니다. 이벤트를 처리하기 위한 클라이언트의 연결 설정 이벤트입니다. 또한 작업자 프로세스가 모니터링해야 하는 포트에 해당하는 파일 설명자를 프로세스의 epoll 핸들에 추가하지 않으면 해당 이벤트가 트리거될 수 없음을 알 수 있습니다. 이 원칙에 따라 nginx는 공유 잠금을 사용하여 현재 프로세스의 epoll 핸들에 모니터링해야 하는 포트를 추가할 수 있는 권한이 있는지 여부를 제어합니다. 즉, 잠금을 획득한 프로세스만 수신 대기합니다. 대상 포트로. 이러한 방식으로 이벤트가 발생할 때마다 하나의 작업자 프로세스만 트리거되는 것이 보장됩니다. 다음 그림은 작업자 프로세스의 작업 주기에 대한 개략도입니다.
그림의 프로세스와 관련하여 설명해야 할 한 가지는 각 작업자 프로세스가 해당 프로세스에 진입한 후 공유 잠금을 획득하려고 시도한다는 것입니다. 루프를 얻지 못하면 모니터링되는 포트의 파일 설명자가 현재 프로세스의 epoll 핸들에서 제거됩니다(존재하지 않더라도 제거됩니다). 클라이언트 연결 이벤트의 손실로 인해 약간의 Thundering 무리 문제가 발생할 수 있지만 심각하지는 않습니다. 이론에 따르면 현재 프로세스가 잠금을 해제할 때 수신 포트의 파일 설명자가 epoll 핸들에서 제거되고 다음 작업자 프로세스가 잠금을 획득하기 전에 이 기간 동안 각 포트에 해당하는 파일 설명자는 다음과 같습니다. 수신할 epoll 핸들이 없으면 이벤트가 손실됩니다. 반면, 그림과 같이 잠금 획득에 실패한 경우에만 모니터링되는 파일 설명자를 제거하는 경우 잠금 획득에 실패하므로 현재 이러한 파일 설명자를 모니터링하는 프로세스가 있어야 하므로 안전합니다. 지금은 제거하세요. 그러나 이로 인해 발생할 수 있는 한 가지 문제는 위 그림에 따르면 현재 프로세스가 루프 실행을 완료할 때 잠금을 해제한 다음 다른 이벤트를 처리한다는 것입니다. 이 프로세스 중에는 모니터링되는 파일 설명자를 해제하지 않는다는 점에 유의하세요. . 이때 다른 프로세스가 잠금을 획득하고 파일 디스크립터를 모니터링하면 이때 파일 디스크립터를 모니터링하는 프로세스가 두 개이므로 클라이언트에서 연결 설정 이벤트가 발생하면 두 개의 워커 프로세스가 트리거됩니다. 이 문제는 두 가지 주요 이유 때문에 허용됩니다.
이 엄청난 무리 현상은 더 적은 수의 작업자 프로세스만 트리거하며, 이는 매번 모든 작업자 프로세스를 깨우는 것보다 훨씬 낫습니다.
이 문제의 주된 이유 패닉 문제는 현재 프로세스가 잠금을 해제하지만 모니터링되는 파일 설명자를 해제하지 않는다는 것입니다. 그러나 잠금을 해제한 후 작업자 프로세스는 주로 클라이언트 연결의 읽기 및 쓰기 이벤트를 처리하고 플래그 비트를 확인합니다. 매우 짧습니다. 처리 후 잠금을 획득하려고 시도하지만 이때 모니터링되는 파일 설명자는 잠금을 획득한 작업자 프로세스가 클라이언트의 연결 설정 이벤트를 처리하기 위해 대기합니다. , 따라서 천둥소리가 나는 무리 문제가 발생할 확률은 여전히 상대적으로 작습니다.
2. 소스코드 설명
작업자 프로세스의 초기 이벤트 메소드는 주로 ngx_process_events_and_timers() 메소드에서 전체 프로세스를 처리하는 방법을 살펴보겠습니다. method 소스 코드:
void ngx_process_events_and_timers(ngx_cycle_t *cycle) { ngx_uint_t flags; ngx_msec_t timer, delta; if (ngx_trylock_accept_mutex(cycle) == ngx_error) { return; } // 这里开始处理事件,对于kqueue模型,其指向的是ngx_kqueue_process_events()方法, // 而对于epoll模型,其指向的是ngx_epoll_process_events()方法 // 这个方法的主要作用是,在对应的事件模型中获取事件列表,然后将事件添加到ngx_posted_accept_events // 队列或者ngx_posted_events队列中 (void) ngx_process_events(cycle, timer, flags); // 这里开始处理accept事件,将其交由ngx_event_accept.c的ngx_event_accept()方法处理; ngx_event_process_posted(cycle, &ngx_posted_accept_events); // 开始释放锁 if (ngx_accept_mutex_held) { ngx_shmtx_unlock(&ngx_accept_mutex); } // 如果不需要在事件队列中进行处理,则直接处理该事件 // 对于事件的处理,如果是accept事件,则将其交由ngx_event_accept.c的ngx_event_accept()方法处理; // 如果是读事件,则将其交由ngx_http_request.c的ngx_http_wait_request_handler()方法处理; // 对于处理完成的事件,最后会交由ngx_http_request.c的ngx_http_keepalive_handler()方法处理。 // 这里开始处理除accept事件外的其他事件 ngx_event_process_posted(cycle, &ngx_posted_events); }
위 코드에서는 대부분의 확인 작업을 생략하고 스켈레톤 코드만 남겼습니다. 먼저 작업자 프로세스는 잠금을 획득하기 위해 ngx_trylock_accept_mutex() 메서드를 호출합니다. 잠금이 획득되면 각 포트에 해당하는 파일 설명자를 수신합니다. 그런 다음 ngx_process_events() 메서드가 호출되어 epoll 핸들에서 모니터링되는 이벤트를 처리합니다. 그런 다음 공유 잠금이 해제되고 마지막으로 연결된 클라이언트의 읽기 및 쓰기 이벤트가 처리됩니다. ngx_trylock_accept_mutex() 메서드가 공유 잠금을 획득하는 방법을 살펴보겠습니다.
ngx_int_t ngx_trylock_accept_mutex(ngx_cycle_t *cycle) { // 尝试使用cas算法获取共享锁 if (ngx_shmtx_trylock(&ngx_accept_mutex)) { // ngx_accept_mutex_held为1表示当前进程已经获取到了锁 if (ngx_accept_mutex_held && ngx_accept_events == 0) { return ngx_ok; } // 这里主要是将当前连接的文件描述符注册到对应事件的队列中,比如kqueue模型的change_list数组 // nginx在启用各个worker进程的时候,默认情况下,worker进程是会继承master进程所监听的socket句柄的, // 这就导致一个问题,就是当某个端口有客户端事件时,就会把监听该端口的进程都给唤醒, // 但是只有一个worker进程能够成功处理该事件,而其他的进程被唤醒之后发现事件已经过期, // 因而会继续进入等待状态,这种现象称为"惊群"现象。 // nginx解决惊群现象的方式一方面是通过这里的共享锁的方式,即只有获取到锁的worker进程才能处理 // 客户端事件,但实际上,worker进程是通过在获取锁的过程中,为当前worker进程重新添加各个端口的监听事件, // 而其他worker进程则不会监听。也就是说同一时间只有一个worker进程会监听各个端口, // 这样就避免了"惊群"问题。 // 这里的ngx_enable_accept_events()方法就是为当前进程重新添加各个端口的监听事件的。 if (ngx_enable_accept_events(cycle) == ngx_error) { ngx_shmtx_unlock(&ngx_accept_mutex); return ngx_error; } // 标志当前已经成功获取到了锁 ngx_accept_events = 0; ngx_accept_mutex_held = 1; return ngx_ok; } // 前面获取锁失败了,因而这里需要重置ngx_accept_mutex_held的状态,并且将当前连接的事件给清除掉 if (ngx_accept_mutex_held) { // 如果当前进程的ngx_accept_mutex_held为1,则将其重置为0,并且将当前进程在各个端口上的监听 // 事件给删除掉 if (ngx_disable_accept_events(cycle, 0) == ngx_error) { return ngx_error; } ngx_accept_mutex_held = 0; } return ngx_ok; }
위 코드에서는 기본적으로 세 가지 주요 작업을 수행합니다.
cas 메서드를 사용하여 ngx_shmtx_trylock(을 통해 공유 잠금을 획득해 보세요. ) 메서드;
잠금을 획득한 후 ngx_enable_accept_events() 메서드를 호출하여 대상 포트에 해당하는 파일 설명자를 모니터링합니다.
잠금을 획득하지 못한 경우 ngx_disable_accept_events() 메서드를 호출하여 모니터링을 해제합니다. 파일 설명자.
위 내용은 nginx 패닉 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

NginXunit은 여러 프로그래밍 언어를 지원하고 동적 구성, 제로 다운 타임 업데이트 및 내장로드 밸런싱과 같은 기능을 제공하는 오픈 소스 응용 프로그램 서버입니다. 1. 동적 구성 : 다시 시작하지 않고 구성을 수정할 수 있습니다. 2. 다국어 지원 : Python, Go, Java, PHP 등과 호환됩니다. 3. 제로 다운 타임 업데이트 : 서비스를 중단하지 않는 응용 프로그램 업데이트를 지원합니다. 4. 내장로드 밸런싱 : 요청을 여러 응용 프로그램 인스턴스에 배포 할 수 있습니다.

NginxUnit은 다국어 프로젝트 및 동적 구성 요구 사항에 적합한 Apachetomcat, Gunicorn 및 Node.js 내장 HTTP 서버보다 낫습니다. 1) 여러 프로그래밍 언어를 지원하고, 2) 동적 구성 재 장전을 제공합니다. 3) 확장 성과 신뢰성이 높은 프로젝트에 적합한 내장로드 밸런싱 기능.

NginxUnit은 모듈 식 아키텍처 및 동적 재구성 기능으로 응용 프로그램 성능 및 관리 가능성을 향상시킵니다. 1) 모듈 식 설계에는 마스터 프로세스, 라우터 및 응용 프로그램 프로세스가 포함되어 효율적인 관리 및 확장을 지원합니다. 2) 동적 재구성을 통해 CI/CD 환경에 적합한 런타임시 구성을 완벽하게 업데이트 할 수 있습니다. 3) 다국어 지원은 언어 런타임의 동적로드를 통해 구현되어 개발 유연성을 향상시킵니다. 4) 고성능은 이벤트 중심 모델과 비동기 I/O를 통해 달성되며 높은 동시성에서도 효율적으로 유지됩니다. 5) 응용 프로그램 프로세스를 분리하고 응용 프로그램 간의 상호 영향을 줄임으로써 보안이 향상됩니다.

NginxUnit을 사용하여 여러 언어로 응용 프로그램을 배포하고 관리 할 수 있습니다. 1) nginxunit을 설치하십시오. 2) Python 및 PHP와 같은 다른 유형의 응용 프로그램을 실행하도록 구성하십시오. 3) 응용 프로그램 관리에 동적 구성 기능을 사용하십시오. 이러한 단계를 통해 응용 프로그램을 효율적으로 배포하고 관리하고 프로젝트 효율성을 향상시킬 수 있습니다.

Nginx는 높은 동시 연결을 처리하는 데 더 적합한 반면 Apache는 복잡한 구성 및 모듈 확장이 필요한 시나리오에 더 적합합니다. 1.NGINX는 고성능 및 낮은 자원 소비로 유명하며 높은 동시성에 적합합니다. 2. Aapache는 안정성과 풍부한 모듈 확장으로 유명하며 복잡한 구성 요구에 적합합니다.

NginxUnit은 동적 구성 및 고성능 아키텍처로 응용 프로그램 유연성 및 성능을 향상시킵니다. 1. 동적 구성을 사용하면 서버를 다시 시작하지 않고 응용 프로그램 구성을 조정할 수 있습니다. 2. 고성능은 이벤트 중심 및 비 블로킹 아키텍처 및 다중 프로세스 모델에 반영되며 동시 연결을 효율적으로 처리하고 멀티 코어 CPU를 활용할 수 있습니다.

Nginx와 Apache는 성능, 확장 성 및 효율성 측면에서 고유 한 장점과 단점을 가진 강력한 웹 서버입니다. 1) NGINX는 정적 컨텐츠를 처리하고 역전 프록시를 처리 할 때 잘 수행되며 동시 동시성 시나리오에 적합합니다. 2) Apache는 동적 컨텐츠를 처리 할 때 더 나은 성능을 발휘하며 풍부한 모듈 지원이 필요한 프로젝트에 적합합니다. 서버 선택은 프로젝트 요구 사항 및 시나리오에 따라 결정해야합니다.

Nginx는 높은 동시 요청을 처리하는 데 적합한 반면 Apache는 복잡한 구성 및 기능 확장이 필요한 시나리오에 적합합니다. 1.NGINX는 이벤트 중심의 비 블로킹 아키텍처를 채택하며, 대결 환경에 적합합니다. 2. Apache는 프로세스 또는 스레드 모델을 채택하여 복잡한 구성 요구에 적합한 풍부한 모듈 생태계를 제공합니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

에디트플러스 중국어 크랙 버전
작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

Dreamweaver Mac版
시각적 웹 개발 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

맨티스BT
Mantis는 제품 결함 추적을 돕기 위해 설계된 배포하기 쉬운 웹 기반 결함 추적 도구입니다. PHP, MySQL 및 웹 서버가 필요합니다. 데모 및 호스팅 서비스를 확인해 보세요.

드림위버 CS6
시각적 웹 개발 도구
