-
[Nginx] Worker Connections 알아보기Nginx 2024. 2. 4. 07:53728x90반응형
- 목차
들어가며.
이번 글에서 Nginx 의 Worker Connections 에 대해서 알아보려고 합니다.
Nginx 의 Worker Connections 는 Master Process 와 Worker Process 의 차이점과 역할에 대한 배경 지식이 필요합니다.
아래 링크의 컨텐츠를 참고하시면 도움이 될 것 같네요.
https://westlife0615.tistory.com/337
Nginx 의 Worker Process 는 Client 와 Backend 와 실질적인 데이터 교환을 수행합니다.
이때의 Client 는 TCP 커넥션을 맺은 Client 를 의미하며,
Backend 는 Nginx 가 Reverse Proxy 로써 동작할 때에 네트워크 요청을 포워딩해야하는 다른 서버를 의미합니다.
이처럼 Worker Process 는 클라이언트의 수가 많아질수록 또는 포워딩해야하는 Backend 서버가 많아질수록
Worker Process 가 소화해야하는 Connection 의 숫자가 많아져야합니다.
Nginx 는 worker_connections 라는 디렉티브를 제공하며, 이 worker_connections 디렉티브를 통해서 하나의 Worker Process 가 생성할 수 있는 최대의 Connection 의 숫자를 지정할 수 있습니다.
Worker Connection 이란 무엇인가 ?
그럼 Worker Connection 이라는 것이 정확히 무엇일까요 ?
Worker Connection 은 TCP Socket 을 의미합니다.
즉, Accept System Call 을 통해서 생성되는 TCP Socket 에 해당하며 동시에 100개의 Client 가 네트워크 요청을 보내면
Nginx 의 Worker Process 는 100개의 TCP Socket 을 생성할 수 있어야 합니다.
이때 nginx.conf 의 worker_connections 의 설정값을 통해서 하나의 Worker Process 가 동시에 생성할 수 있는 TCP Socket 의 갯수는 제한됩니다.
그래서 일반적으로 Nginx 가 한번에 처리할 수 있는 요청의 수는 worker_processes x worker_connections 만큼의 값만큼 동시 처리를 수행할 수 있다고 합니다.
왜냐하면 worker_processes 디렉티브의 값만큼 Worker Process 가 생성되고,
하나의 Worker Process 가 worker_connections 디렉티브의 값만큼 TCP Socket 을 생성할 수 있기 때문이죠.
우선 간단히 Worker Connection 이 어떻게 동작하는지 확인해보겠습니다.
아래의 코드들은 1개의 Worker Process 를 생성하도록 지정한 nginx.conf 파일과 nginx 를 실행하는 Docker 명령어입니다.
cat <<'EOF'> /tmp/nginx.conf worker_processes 1; events { worker_connections 1024; multi_accept on; } http { server { listen 80; location / { return 200 $request_uri; } } } EOF docker run --platform linux/arm64 -d -p 8080:80 \ --name nginx \ --user root \ --mount type=bind,source=/tmp/nginx.conf,target=/opt/bitnami/nginx/conf/nginx.conf \ bitnami/nginx:1.24
그리고 생성된 Nginx 를 향해서 GET 요청을 전송합니다.
curl http://localhost:8080
lsof 명령어를 통해서 Worker Process 의 File Descriptor 상태를 확인합니다.
( 참고로 저의 경우에는 Worker Process 의 PID 가 57 입니다.
그리고 lsof 는 프로세스와 관련된 File 들의 목록을 나열하는 명령어입니다. )
lsof -p 57
lsof 의 결과는 아래와 같이 2개의 Socket 이 확인됩니다.
80 포트는 Master Process 로부터 상속받은 Listening Socket 을 의미합니다.
그리고 ESTABLISHED 로 표현된 Socket 이 Client 와 연결된 Accepted Socket 을 의미합니다.
이렇게 총 2개의 Socket 이 만들어지게 됩니다.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 57 nobody 3u IPv4 231596 0t0 TCP e152a46f0969:80->172.17.0.1:57664 (ESTABLISHED) nginx 57 nobody 6u IPv4 201887 0t0 TCP *:80 (LISTEN)
위 Accepted Socket 에 대해서 잠시 분석을 해보면,
- TYPE IPv4 : IPv6 와 IPv4 중에서 IPv4 의 IP 프로토콜을 사용
- Node TCP : TCP 와 UDP 중에서 TCP 프로토콜을 사용한다는 의미이며, HTTP 요청 또한 내부적으로 TCP 통신을 반드시 수행합니다.
- e152a46f0969:80->172.17.0.1:57664
- e152a46f0969 는 Nginx 의 IP 를 지칭하며, 이는 Docker Container 내부에서 동작하기 때문에 이러한 별칭이 연결됨.
- 80 포트는 Nginx 가 사용하는 Port 번호를 의미함.
- 172.17.0.1 는 클라이언트의 IP 를 의미하며, 현재의 경우에는 Docker Bridge Network 의 IP 로 지정됩니다.
- 57664 또한 클라이언트의 Port 를 의미하는데, IP 와 마찬가지로 Docker Bridge Network 의 임시 Port 가 지정되었습니다.
Nginx 가 Reverse Proxy 로써 동작한다면 ?
만약 Nginx 가 Reverse Proxy 로써 동작한다면 1번의 네트워크 연결 시에 Worker Connection 는 2개씩 생성됩니다.
그 이유는 Client - Nginx 그리고 Nginx - Backend Server 와 같이 2개의 TCP Socket 이 필요하기 때문입니다.
아래의 코드는 Nginx 가 Reverse Proxy 로 동작할 때에 Worker Connection 이 2개씩 생성되는 상황을 확인하기 위한 명령어입니다.
cat <<'EOF'> /tmp/nginx.conf worker_processes 1; events { worker_connections 1024; multi_accept on; } http { server { listen 80; location /delay { proxy_pass http://delay:80; } } } EOF docker network create nginx-net docker run --platform linux/arm64 -d -p 8080:80 \ --name nginx \ --network nginx-net \ --user root \ --mount type=bind,source=/tmp/nginx.conf,target=/opt/bitnami/nginx/conf/nginx.conf \ bitnami/nginx:1.24 docker run --network nginx-net -d \ --name delay \ --hostname delay \ kennethreitz/httpbin
위의 명령어를 실행시켜 2개의 Docker Container 를 실행합니다.
실행 후 생성된 서버들의 네트워크 구조를 아래의 이미지와 같습니다.
그리고 아래의 HTTP GET 요청을 통해서 생성되는 Worker Connection 을 확인해봅니다.
curl http://localhost:8080/delay/10
아래와 같이 생성되는 Accepted Socket 은 2개가 관찰됩니다.
하나의 Socket 은 Client -> Nginx 의 Socket.
다른 하나는 Nginx -> Backend Server 로의 Socket.
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 57 nobody 3u IPv4 257095 0t0 TCP 6e4d43dbde8e:80->172.23.0.1:64568 (ESTABLISHED) nginx 57 nobody 6u IPv4 253459 0t0 TCP *:80 (LISTEN) nginx 57 nobody 10u IPv4 256116 0t0 TCP 6e4d43dbde8e:36368->delay.nginx-net:80 (ESTABLISHED)
worker_connections 디렉티브 알아보기.
nginx.conf 파일은 worker_connections 디렉티브를 제공합니다.
worker_connections 지시자를 통해서 하나의 Worker Process 가 생성할 수 있는 최대 Connection 갯수를 제한할 수 있습니다.
우선 아래와 같이 worker_connections 이 4 인 Nginx 를 실행해보도록 하겠습니다.
참고로 아래의 구성은 Nginx 가 Reverse Proxy 로써 동작하기 때문에 하나의 연결 당 2개의 Worker Connection 이 생성됩니다.
cat <<'EOF'> /tmp/nginx.conf worker_processes 1; events { worker_connections 4; multi_accept on; } http { server { listen 80; location /delay { proxy_pass http://delay:80; } } } EOF docker network create nginx-net docker run --platform linux/arm64 -d -p 8080:80 \ --name nginx \ --network nginx-net \ --user root \ --mount type=bind,source=/tmp/nginx.conf,target=/opt/bitnami/nginx/conf/nginx.conf \ bitnami/nginx:1.24 docker run --network nginx-net -d \ --name delay \ --hostname delay \ kennethreitz/httpbin
그리고 아래와 같이 HTTP Get 요청을 통해서 최대값이 지정된 Worker Connections 의 동작을 확인할 수 있습니다.
curl http://localhost:8080/delay/10
아래의 결과는 1초 간격을 HTTP GET 요청에 대한 Nginx 의 Socket 상태를 확인하는 출력인데요.
아래의 결과처럼 매 요청마다 Nginx 의 Worker Process 는 새로운 2개의 Socket 을 생성하며,
각 Socket 마다 새로운 Port 로 연결이 됩니다.
그리고 최대 2개의 Accepted Socket 를 생성하지 못합니다.
그래서 worker_connections 지시자의 설정값과 넉넉히 설정해서 다수의 Client 와 Backend Server 와의 데이터 교환에 차질이 없도록 해야합니다.
반면 worker_connections 의 값을 넉넉히 설정할 경우에 아래의 결과처럼 많은 수의 TCP Socket File Descriptor 들이 확인됩니다.
반응형'Nginx' 카테고리의 다른 글
[Nginx] Web Content Serving 알아보기 ( default.conf ) (0) 2024.03.18 Nginx 구조 알아보기 (0) 2023.10.07 [Nginx] Worker Processes 알아보기 (0) 2023.10.06 Nginx HTTP Upstream 알아보기 (0) 2023.09.16 [Nginx] listen Directive 알아보기 (0) 2023.09.06