PHP-FPM과 LocalPort 문제

아재발자·2024년 6월 2일
0

제가 2018년 1월부터 2021년 9월까지, 총 3년 9개월을 다녔던 회사에서 근무하면서 직접 경험한 내용을 바탕으로 공부하고 알게된 지식을 간단하게 정리하는 글입니다.

TCP 통신과 Linux Socket 관련 내용은 여기에서 확인해주세요.


PHP-FPM (PHP FastCGI Process Manager)

CGI (Common Gateway Interface)

웹서버와 외부 프로토콜을 연결시켜주는 표준 프로토콜로서, 기본적으로 Request 요청별로 프로세스를 생성하여 처리하는 방식을 의미합니다.

FastCGI

Request가 발생할 때 마다 프로세스를 생성하여 처리하고, 프로세스를 종료하는 CGI의 단점을 개선한 방식으로, Request 요청을 처리할 프로세스를 미리 만들어두고 재사용하는 방식으로 처리를 합니다.

PHP-FPM

php-fpm은 PHP FastCGI Process Manager의 약자로서, PHP 스크립트를 실행하는 FastCGI 서버로 동작합니다.

php-fpm은 Worker 프로세스를 관리하는 Master 프로세스와 PHP 스크립트를 실행하는 Worker 프로세스로 구분되며, Master 프로세스는 웹 서버(예: Nginx, Apache 등)로부터 FastCGI 요청을 수신받아 Worker 프로세스로 전달하는 역할도 합니다.

참고!
php-fpm은 max_children 옵션을 통해 미리 만들어둘 프로세스의 수량을 지정할 수 있습니다.
메모리 누수 등의 문제를 최소화하기 위해 max_requests 옵션도 제공합니다.

그 외 FastCGI 동작에 관련된 많은 설정을 제공하고 있습니다.


PHP-FPM과 LocalPort의 문제

php-fpm은 일반적으로 Server의 역할을 수행하기 때문에 LocalPort를 고갈시키지 않습니다.

하지만 소스 코드 내에 MySQL, Redis 등 외부 서비스로 연결하는 로직이 포함되면 이야기가 달라집니다.

PHP는 MySQL, Redis 등 외부 서비스로 연결하는 과정에서 TCP 소켓을 생성하게 되는데, 이 과정에서 PHP는 커널에게 LocalPort을 요청하게 되고, 이후 외부 서비스와의 연결을 Disconnect하는 과정에서 소켓의 상태를 TIME_WAIT로 변경합니다.

참고!
TIME_WAIT 상태를 갖는 소켓은 패킷 유실 등의 처리를 위해 약 1분동안 대기한 다음 연결을 종료하게 됩니다.

여기서 중요한 점은 php-fpm은 Request 단위로 처리를 한다는 점입니다.

만약 1분도 안되는 시간에 트래픽(사용자의 요청)이 급격하게 증가하면 TIME_WAIT 상태를 갖는 소켓으로 인해 리눅스의 LocalPort가 고갈되어 서비스에 장애가 발생할 수 있습니다.

참고!
소켓은 TCP 통신을 위해 생성된 File Descriptor를 의미합니다. 따라서 Process별로 가질 수 있는 File Descriptor 설정에도 영향을 받습니다.

profile
안녕하세요. 아재 개발자입니다. 공부한 내용을 기록하고 잘못된 부분에 대해서 조언을 받기 위해 velog를 시작했습니다. :)

0개의 댓글