NGINX 1.9.1에는 SO_REUSEPORT 소켓 옵션을 사용할 수 있는 새로운 기능이 도입되었습니다. 이 옵션은 DragonFly BSD와 Linux(커널 버전 3.9 이상)를 비롯한 여러 운영 체제의 최신 버전에서 지원됩니다. 이 소켓 옵션을 사용하면 여러 소켓이 동일한 IP 주소와 포트 조합에서 수신 대기할 수 있습니다. 그러면 커널이 소켓 간에 수신 연결의 부하를 분산합니다.
편집자 주 – NGINX Plus 사용자의 경우 이 기능은 NGINX Plus 릴리스 7(R7) 이상에서 지원됩니다. 해당 릴리스의 모든 새로운 기능에 대한 개요는 블로그의 NGINX Plus R7 발표를 참조하세요.
The SO_REUSEPORT 소켓 옵션은 실제 환경에서 다양하게 활용될 수 있습니다. 다른 서비스에서는 이 옵션을 사용하여 실행 파일을 손쉽게 무중단 업그레이드할 수 있습니다(NGINX는 이미 다른 방식으로 무중단 업그레이드를 지원합니다). NGINX에서 이 소켓 옵션을 활성화하면 잠금 경합이 줄어들어 특정 상황에서 성능이 향상될 수 있습니다.
그림과 같이 SO_REUSEPORT 옵션이 활성화되어 있지 않으면 단일 수신 소켓이 워커에 들어오는 연결을 알리고, 각 워커는 연결을 가져오려고 시도합니다.

With the SO_REUSEPORT 옵션을 활성화하면 각 IP 주소와 포트 조합마다 여러 개의 소켓 리스너가 생성되며, 각 워커 프로세스에 하나씩 할당됩니다. 커널은 사용 가능한 소켓 리스너 중 어느 리스너가 연결을 받을지, 즉 어느 워커가 연결을 처리할지를 결정합니다. 이를 통해 새 연결을 수락하는 워커 간의 잠금 경합을 줄이고 멀티코어 시스템의 성능을 향상할 수 있습니다. 그러나 워커가 블로킹 작업으로 인해 멈추면 해당 워커가 이미 수락한 연결뿐만 아니라 멈춘 이후 커널이 해당 워커에 할당한 연결 요청까지 영향을 받을 수 있습니다.

소켓 샤딩 구성
To enable the SO_REUSEPORT 소켓 옵션을 활성화하려면 다음 예시와 같이 HTTP 또는 TCP(reuseport 트래픽을 위한 listen 지시문에 새로운 stream 모듈) 매개변수를 추가합니다:
http { server {
listen 80 reuseport;
server_name localhost;
# ...
}
}
stream {
server {
listen 12345 reuseport;
# ...
}
}Including the reuseport 매개변수를 지정하면 뮤텍스가 accept_mutex에 중복되므로 해당 소켓의 reuseport 지시문도 비활성화됩니다. accept_mutex를 설정하지 않은 포트가 있다면 reuseport를 설정하는 것이 여전히 유용할 수 있습니다.
성능 벤치마킹: reuseport
I ran a wrk 벤치마크를 36코어 AWS 인스턴스에서 4개의 NGINX 워커로 실행했습니다. 네트워크의 영향을 배제하기 위해 클라이언트와 NGINX를 모두 localhost에서 실행했으며, NGINX가 파일 대신 OK 문자열을 반환하도록 했습니다. 기본 설정(accept_mutex on과 동일), accept_mutex off 설정, reuseport 설정의 세 가지 NGINX 구성을 비교했습니다. 그림에서 볼 수 있듯이 reuseport를 사용하면 초당 요청 수가 2~3배 증가하고, 지연 시간과 지연 시간의 표준 편차가 모두 감소합니다.

또한 클라이언트와 NGINX를 서로 다른 호스트에서 실행하고 NGINX가 HTML 파일을 반환하도록 구성하여 관련 벤치마크를 수행했습니다. 다음 표에서 볼 수 있듯이 reuseport를 사용했을 때 지연 시간 감소 폭은 이전 벤치마크와 비슷했으며, 표준 편차는 훨씬 더 큰 폭으로 감소했습니다(거의 10분의 1 수준). 표에 표시되지 않은 다른 결과도 긍정적이었습니다. reuseport를 사용하면 부하가 워커 프로세스 전체에 고르게 분산되었습니다. 기본 조건(accept_mutex on과 동일)에서는 일부 워커에 더 많은 부하가 집중되었으며, accept_mutex off를 사용하면 모든 워커에 높은 부하가 발생했습니다.
지연 시간(ms) 지연 시간 표준 편차(ms) CPU 부하기본값 15.65 26.59 0.3accept_mutex off 15.59 26.48 10reuseport 12.35 3.15 0.3
이 벤치마크에서는 연결 요청 빈도가 높지만 요청 자체에는 많은 처리가 필요하지 않습니다. 다른 예비 테스트에서도 트래픽이 이 프로필과 일치할 때 reuseport가 성능을 가장 크게 향상시키는 것으로 나타났습니다. (예를 들어 이메일 트래픽은 이 프로필과 전혀 일치하지 않으므로 reuseport 매개변수는 listen 지시문의 mail 컨텍스트에서 사용할 수 없습니다.) 따라서 이를 일괄적으로 적용하기보다는 reuseport를 테스트하여 NGINX 배포 환경에서 성능이 향상되는지 확인하는 것이 좋습니다. NGINX 성능 테스트에 관한 몇 가지 팁은 nginx.conf 2014에서 발표된 Konstantin Pavlov의 강연을 참조하세요.
감사의 말
NGINX 프로젝트에서 SO_REUSEPORT 소켓 옵션을 사용할 수 있도록 각각 솔루션을 제공해 주신 Intel의 Yingqi Lu와 Sepherosa Ziehau에게 감사드립니다. NGINX 팀은 두 기여자의 아이디어를 결합하여 저희가 생각하는 이상적인 솔루션을 만들었습니다.
관련 블로그 게시물
시청하기: KubeCon North America 2023에서의 NGINX Gateway Fabric
이 영상에서는 KubeCon의 NGINX 부스를 찾아가, 저희가 공개한 Kubernetes Gateway API 구현을 살펴봅니다.
F5 NGINX로 대규모 WAF 플릿을 확인하고 관리하는 2가지 방법
앱 보안을 강화하는 두 가지 방법을 소개합니다. NGINX Management Suite를 통해 WAF 운영에 대한 가시성을 높이고, NGINX App Protect WAF를 활용해 코드형 보안을 구현하는 것입니다.
Ingress 컨트롤러 선택 가이드, 4부: NGINX Ingress Controller 옵션
개발 주체, 개발 철학, 프로덕션 환경 준비도, 보안 및 지원을 기준으로 어떤 NGINX Ingress 컨트롤러가 가장 적합한지 알아보세요.
진화하는 공격 환경에 NGINX App Protect Denial of Service가 적응하는 방법
NGINX App Protect Denial of Service(DoS)가 계층 7 DoS 공격을 방어하기 위해 완화 방법을 실시간으로 조정하는 방식을 설명합니다. 정상적인 사용자 행동과 서버 상태에 대한 모델을 생성하여 공격을 나타내는 이상 징후를 감지하고 맞춤형 완화 시그니처를 적용할 수 있습니다.
NGINX Instance Manager를 활용한 대규모 구성 업데이트 및 인증서 관리
NGINX Instance Manager 버전 1.0에는 두 가지 새로운 기능이 도입되었습니다. NGINX 인스턴스에 태그와 사용자 역할을 지정하면 전체 그룹에 구성을 한 번에 적용할 수 있습니다. 인증서 검사는 만료 예정인 인증서를 감지하여 서비스 중단을 방지할 수 있도록 인증서를 교체할 수 있게 해줍니다.
Netflix가 자사 CDN의 핵심으로 NGINX를 선택한 이유
Netflix가 글로벌 콘텐츠 전송 네트워크인 Open Connect의 스트리밍 미디어 기술로 NGINX를 선택한 이유를 NGINX 개발자 Gleb Smirnoff에게서 알아보세요.