웹사이트가 평소보다 느려지거나 특정 페이지에서 응답이 끝나지 않는데도 502 Bad Gateway 오류는 발생하지 않는 상황이 있습니다. Nginx는 실행 중이고 PHP-FPM 서비스도 active 상태로 표시되지만, 실제로는 PHP 요청이 오랫동안 처리되지 않거나 일부 워커 프로세스가 특정 작업에서 멈춘 것처럼 보이는 경우입니다.
이러한 현상은 PHP-FPM 자체가 완전히 종료된 경우와 다릅니다. PHP-FPM 프로세스 멈춤 문제는 데이터베이스 잠금 대기, 외부 API 응답 지연, 파일 I/O 정체, 워커 프로세스 부족, PHP 확장 모듈의 비정상 동작 등으로 발생할 수 있습니다.
특히 서버 상태를 확인했을 때 프로세스가 살아 있다는 이유만으로 정상이라고 판단하면 장애 원인을 놓치기 쉽습니다. 프로세스의 존재 여부와 실제 요청 처리 가능 여부는 서로 다르기 때문입니다.
이번 글에서는 502 오류가 나타나지 않는 이유부터 PHP-FPM 워커 상태, slowlog, 프로세스 풀 설정, 데이터베이스 대기 및 운영체제 로그까지 순서대로 확인합니다.
PHP-FPM 프로세스 멈춤 핵심 명령어 한눈에 보기
다음은 PHP 8.3을 사용하는 Ubuntu 서버의 예시입니다. 실제 서버에서는 PHP 버전과 서비스 이름, 설정 경로를 변경해야 합니다.
| 점검 목적 | 명령어 |
|---|---|
| PHP-FPM 서비스 상태 | systemctl status php8.3-fpm |
| 프로세스 목록 | ps -eo pid,ppid,stat,etime,%cpu,%mem,wchan:24,cmd | grep '[p]hp-fpm' |
| 서비스 로그 | journalctl -u php8.3-fpm -n 100 |
| 프로세스 풀 설정 | grep -E '^(pm\.|request_|slowlog)' /etc/php/8.3/fpm/pool.d/www.conf |
| PHP-FPM 설정 검사 | sudo php-fpm8.3 -tt |
| 메모리 상태 | free -h |
| 커널 OOM 로그 | journalctl -k -b | grep -Ei 'oom|out of memory|killed process' |
| Nginx 오류 로그 | sudo tail -n 100 /var/log/nginx/error.log |
가장 먼저 확인할 것은 PHP-FPM 서비스가 실행 중인지가 아니라 워커 프로세스가 실제로 요청을 처리하고 있는지 여부입니다.

1. PHP-FPM이 멈췄는데 502 오류가 발생하지 않는 이유
PHP-FPM은 PHP 요청을 처리하는 FastCGI 프로세스 관리자입니다. Nginx나 Apache가 전달한 PHP 요청을 워커 프로세스가 실행한 뒤 처리 결과를 웹서버에 반환하는 구조입니다.
그런데 PHP-FPM 워커가 특정 작업에서 오랫동안 대기하면 웹서버와의 연결이 즉시 끊어지지 않을 수 있습니다. 이 경우 요청은 완료되지 않았지만 아직 502 오류가 발생할 조건에도 도달하지 않은 상태일 수 있습니다.
예를 들어 다음과 같은 상황이 발생할 수 있습니다.
- PHP 요청이 DB 잠금 해제를 기다리는 경우
- 외부 API 연결이나 응답을 장시간 기다리는 경우
- 디스크 또는 네트워크 파일시스템의 I/O가 지연되는 경우
- 모든 PHP-FPM 워커가 사용 중이어서 새로운 요청이 대기하는 경우
- 웹서버의 FastCGI 타임아웃에 도달하기 전까지 요청이 유지되는 경우
이후 타임아웃이 발생하면 502가 아닌 504 Gateway Timeout으로 표시될 수도 있습니다. 또한 브라우저나 프록시가 먼저 연결을 종료하면 사용자가 HTTP 오류 페이지를 보지 못할 수도 있습니다.
따라서 502 오류가 없다는 사실만으로 PHP-FPM이 정상이라고 판단해서는 안 됩니다.
2. PHP-FPM 프로세스가 실제로 실행 중인지 확인하기
먼저 서비스 상태를 확인합니다.
systemctl status php8.3-fpm
서비스가 실행 중이라면 다음과 같이 표시될 수 있습니다.
Active: active (running)
하지만 이 상태는 PHP-FPM의 마스터 프로세스가 실행 중이라는 정보일 뿐, 모든 워커가 정상적으로 요청을 처리한다는 뜻은 아닙니다.
프로세스 목록과 상태를 확인합니다.
ps -eo pid,ppid,stat,etime,%cpu,%mem,wchan:24,cmd | grep '[p]hp-fpm'
확인할 주요 항목은 다음과 같습니다.
- STAT: 프로세스의 실행 또는 대기 상태
- ETIME: 프로세스가 시작된 이후 경과 시간
- %CPU: CPU 사용률
- %MEM: 메모리 사용 비율
- WCHAN: 커널에서 대기 중인 위치에 대한 단서
특히 D 상태가 지속된다면
중단하기 어려운 커널 대기 상태에 있는지 확인해야 합니다.
디스크 또는 네트워크 파일시스템의 I/O 정체와 관련될 수 있습니다.
다만 S 상태라고 해서 반드시 문제가 있는 것은 아닙니다.
정상적인 유휴 프로세스도 대기 상태로 표시될 수 있으므로
요청 처리 상황과 함께 해석해야 합니다.
3. pm.max_children 부족으로 요청이 대기하는 경우
PHP-FPM은 프로세스 풀 설정에 따라 동시에 실행할 수 있는 워커 수가 제한됩니다.
대표적인 설정이 pm.max_children입니다.
현재 설정을 확인합니다.
sudo grep -E '^(pm|pm\.max_children|pm\.max_requests|pm\.start_servers|pm\.min_spare_servers|pm\.max_spare_servers)' \
/etc/php/8.3/fpm/pool.d/www.conf
설정 예시는 다음과 같습니다.
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
이 환경에서 20개의 워커가 모두 장시간 실행되는 요청을 처리하고 있다면 새로운 요청이 대기할 수 있습니다.
PHP-FPM 로그에 다음과 같은 메시지가 나타날 수도 있습니다.
server reached pm.max_children setting (20),
consider raising it
그러나 pm.max_children을 무조건 높이는 것은
올바른 해결 방법이 아닙니다.
워커 수를 늘리면 메모리 사용량도 증가하므로 현재 워커의 실제 메모리 사용량과 서버의 가용 메모리를 확인해야 합니다.
또한 워커가 DB 잠금이나 외부 API 대기 때문에 점유되어 있다면 워커 수를 늘려도 근본적인 문제가 남을 수 있습니다.
4. PHP-FPM slowlog로 오래 실행되는 PHP 코드 찾기
PHP-FPM 프로세스가 멈춘 것처럼 보이는 원인을 분석할 때 가장 유용한 기능 중 하나가 slowlog입니다.
slowlog는 설정한 시간을 초과해 실행되는 PHP 요청의 실행 위치를 기록하는 기능입니다.
PHP-FPM 풀 설정 파일에 다음과 같은 항목을 지정할 수 있습니다.
request_slowlog_timeout = 5s
slowlog = /var/log/php-fpm/www-slow.log
위 경로는 예시이며, PHP-FPM 워커와 서비스가 해당 로그 경로에 기록할 수 있도록 디렉터리와 권한이 준비되어 있어야 합니다.
설정을 적용하기 전에 문법을 검사합니다.
sudo php-fpm8.3 -tt
문제가 없다면 운영 환경의 변경 절차에 따라 PHP-FPM 서비스를 재로드할 수 있습니다.
sudo systemctl reload php8.3-fpm
이후 느린 요청이 발생하면 slowlog에 PHP 함수 호출 위치와 실행 흐름이 기록될 수 있습니다.
예를 들어 DB 쿼리 호출이나 HTTP 요청 함수에서 오랫동안 대기하는 상황을 찾는 데 도움이 됩니다.
단, slowlog는 모든 종류의 커널 대기나 네이티브 확장 모듈 내부 문제를 완벽하게 보여주는 도구는 아닙니다.
5. DB 잠금과 느린 쿼리로 PHP 요청이 멈추는 경우
PHP 애플리케이션이 MySQL이나 MariaDB를 사용한다면 데이터베이스 쿼리 대기를 확인해야 합니다.
특히 트랜잭션이 잠금을 오래 유지하거나 느린 쿼리가 반복되면 PHP 워커가 DB 응답을 기다리면서 요청 처리 시간이 길어질 수 있습니다.
MySQL에서는 다음 명령어로 현재 실행 중인 세션을 확인할 수 있습니다.
SHOW FULL PROCESSLIST;
MySQL 8.0 환경에서는 InnoDB 잠금 대기를 다음 뷰로 확인할 수도 있습니다.
SELECT *
FROM sys.innodb_lock_waits;
다만 해당 뷰의 사용 가능 여부는 MySQL 버전과 sys 스키마 구성에 따라 달라집니다.
확인해야 할 항목은 다음과 같습니다.
- 장시간 실행 중인 쿼리가 있는지
- 잠금을 기다리는 트랜잭션이 있는지
- 인덱스 부족으로 쿼리가 느려지는지
- DB 연결 수가 한계에 도달했는지
- DB 서버의 CPU·디스크 사용량이 과도한지
잠금 대기가 확인되더라도 원인을 파악하지 않고 DB 세션을 강제로 종료하면 트랜잭션 롤백이나 서비스 오류가 발생할 수 있습니다.
6. 외부 API와 네트워크 연결 지연 확인하기
PHP 코드에서 외부 API를 호출하는 경우 상대 서버의 응답 지연이 PHP-FPM 워커 점유로 이어질 수 있습니다.
예를 들어 결제 API, 인증 서버, 외부 데이터 조회, SMTP 연결 등이 영향을 줄 수 있습니다.
PHP cURL을 사용하는 애플리케이션에서는 연결 제한 시간과 전체 요청 제한 시간을 명시적으로 설정하는 것이 좋습니다.
$ch = curl_init('https://api.example.com/data');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
if ($response === false) {
error_log(curl_error($ch));
}
curl_close($ch);
위 코드는 진단용 예시이며 실제 서비스에서는 오류 처리, 재시도 정책, 응답 코드 검증을 추가해야 합니다.
외부 연결을 점검할 때는 PHP-FPM 워커가 특정 원격 주소에 연결되어 있는지도 확인할 수 있습니다.
sudo ss -tnp
다만 네트워크 연결이 존재한다는 사실만으로 해당 연결이 장애 원인이라고 단정할 수는 없습니다. 애플리케이션 로그와 요청 처리 시간을 함께 분석해야 합니다.
7. 메모리 부족과 OOM으로 PHP-FPM 워커가 종료되는 경우
PHP-FPM이 정상적으로 실행되는 것처럼 보여도 일부 워커가 메모리 부족으로 종료되고 새 워커가 생성되는 상황이 반복될 수 있습니다.
현재 메모리 상태를 확인합니다.
free -h
커널 로그에서 OOM 관련 메시지를 검색합니다.
sudo journalctl -k -b | grep -Ei 'oom|out of memory|killed process'
OOM 로그에서 PHP-FPM 워커가 종료된 기록이 있다면 프로세스별 메모리 사용량과 메모리 제한을 확인해야 합니다.
특히 컨테이너나 cgroup으로 관리되는 서버에서는 호스트 메모리가 충분해 보여도 서비스에 적용된 메모리 제한으로 인해 워커가 종료될 수 있습니다.
또한 PHP의 memory_limit는
개별 PHP 스크립트의 메모리 사용 제한과 관련된 설정이며,
PHP-FPM 전체 프로세스 풀의 메모리 사용량을 직접 제한하는 값은 아닙니다.
8. PHP-FPM 상태 페이지로 워커 포화 확인하기
PHP-FPM의 pm.status_path 기능을 사용하면
프로세스 풀의 상태를 더 구체적으로 확인할 수 있습니다.
풀 설정에 다음과 같은 항목을 지정할 수 있습니다.
pm.status_path = /fpm-status
상태 페이지에서는 다음 정보를 확인할 수 있습니다.
- active processes: 현재 요청을 처리 중인 워커 수
- idle processes: 유휴 워커 수
- listen queue: 처리 대기 중인 연결 수
- max children reached: 워커 수 한계에 도달한 횟수
- slow requests: slowlog 기준 시간을 초과한 요청 수
단, pm.status_path를 설정하는 것만으로
외부 HTTP 요청이 자동으로 연결되는 것은 아닙니다.
Nginx 또는 Apache에서 해당 경로를 PHP-FPM으로 전달하도록
별도의 웹서버 설정이 필요합니다.
상태 페이지에는 내부 운영 정보가 포함될 수 있으므로 외부 인터넷에 공개하지 않고 로컬 또는 관리자 전용으로 제한해야 합니다.
또한 기본 풀의 모든 워커가 점유된 상황에서는 같은 풀을 통해 제공하는 상태 페이지도 응답하지 않을 수 있습니다. 필요하다면 PHP-FPM의 별도 상태 리스너 구성을 검토할 수 있습니다.
9. Nginx 로그에서 502 없이 발생하는 응답 지연 확인하기
PHP-FPM 문제가 발생하더라도 Nginx 오류 로그에 항상 502 메시지가 기록되는 것은 아닙니다.
먼저 오류 로그를 확인합니다.
sudo tail -n 100 /var/log/nginx/error.log
다음과 같은 메시지가 나타날 수 있습니다.
upstream timed out (110: Connection timed out)
while reading response header from upstream
이 메시지는 Nginx가 업스트림 응답 헤더를 기다리다가 설정된 제한 시간에 도달했다는 의미입니다.
이런 상황에서는 일반적으로 504 응답이 발생할 수 있지만, 실제 클라이언트가 받은 결과는 연결 종료 시점과 프록시 구성에 따라 달라질 수 있습니다.
또한 Nginx 액세스 로그에
$request_time과
$upstream_response_time이 기록되도록 구성하면
요청 처리 시간을 비교할 수 있습니다.
예를 들어 다음과 같은 로그 형식을 사용할 수 있습니다.
log_format upstream_timing
'$remote_addr "$request" '
'status=$status '
'request_time=$request_time '
'upstream_time=$upstream_response_time';
위 설정은 Nginx의 http 컨텍스트에서 정의하는 예시입니다.
실제 기록에는 액세스 로그에서 해당 형식을 사용하도록
추가 설정해야 합니다.
로그 설정을 변경하기 전에는 반드시 기존 설정과 운영 환경을 확인해야 합니다.
10. PHP 확장 모듈과 파일 I/O 정체 확인하기
일부 PHP 확장 모듈이나 네이티브 라이브러리의 문제도 PHP-FPM 워커가 응답하지 않는 원인이 될 수 있습니다.
예를 들어 이미지 처리, 압축, 데이터베이스 드라이버, 외부 라이브러리 호출 과정에서 비정상적인 대기나 오류가 발생할 수 있습니다.
로드된 PHP 확장 모듈은 다음 명령어로 확인할 수 있습니다.
php -m
다만 CLI PHP와 PHP-FPM은 서로 다른 설정 파일을
사용할 수 있으므로 php -m 결과만으로
FPM의 실제 확장 구성을 확정해서는 안 됩니다.
PHP-FPM 설정 파일과 추가 설정 로딩 상태도 함께 확인해야 합니다.
sudo php-fpm8.3 -i | grep -E 'Loaded Configuration File|Scan this dir'
프로세스가 파일 I/O에서 대기하는지 확인할 때는 프로세스 상태와 커널 로그를 함께 분석해야 합니다.
특히 NFS 또는 네트워크 스토리지를 사용하는 경우에는 파일 접근 지연이 PHP 요청 지연으로 이어질 수 있습니다.
이때 서비스 재시작만 반복하면 일시적으로 증상이 사라지더라도 스토리지나 외부 시스템의 문제가 해결되지 않을 수 있습니다.
실전 점검 순서
502 오류 없이 PHP-FPM 프로세스가 멈춘 것처럼 보인다면 다음 순서로 확인합니다.
# 1. PHP-FPM 서비스 상태
systemctl status php8.3-fpm
# 2. 워커 프로세스 상태
ps -eo pid,ppid,stat,etime,%cpu,%mem,wchan:24,cmd | grep '[p]hp-fpm'
# 3. PHP-FPM 서비스 로그
sudo journalctl -u php8.3-fpm -n 100
# 4. 프로세스 풀 설정
sudo grep -E '^(pm\.|request_|slowlog)' \
/etc/php/8.3/fpm/pool.d/www.conf
# 5. PHP-FPM 설정 문법 검사
sudo php-fpm8.3 -tt
# 6. 메모리 상태
free -h
# 7. OOM 로그
sudo journalctl -k -b | grep -Ei 'oom|out of memory|killed process'
# 8. Nginx 오류 로그
sudo tail -n 100 /var/log/nginx/error.log
# 9. 네트워크 연결
sudo ss -tnp
# 10. PHP-FPM 확장 모듈 정보
sudo php-fpm8.3 -i | grep -E 'Loaded Configuration File|Scan this dir'
위 명령어는 PHP 8.3과 Ubuntu 계열을 기준으로 작성한 예시입니다. 실제 서버에서는 PHP 버전과 배포판에 맞게 변경해야 합니다.
문제가 발생한 시점의 로그와 프로세스 상태를 먼저 확보한 후 설정 변경이나 서비스 재시작을 진행하는 것이 좋습니다.
정리
PHP-FPM 프로세스 멈춤 현상은 502 오류가 발생하지 않아도 나타날 수 있습니다.
PHP-FPM 서비스가 실행 중이더라도 워커가 데이터베이스 잠금, 외부 API 응답, 파일 I/O 또는 장시간 실행되는 PHP 코드에서 대기한다면 실제 요청 처리가 지연될 수 있습니다.
우선 프로세스 상태와 PHP-FPM 로그를 확인하고,
pm.max_children과 slowlog를 통해
워커 포화와 장시간 실행 요청을 분석해야 합니다.
메모리 부족과 OOM 로그, DB 잠금, Nginx 응답 시간도 함께 확인하면 문제가 발생하는 구간을 더 정확하게 좁힐 수 있습니다.
핵심 점검 순서는 PHP-FPM 서비스 상태 확인 → 워커 프로세스 분석 → slowlog 확인 → 프로세스 풀 설정 점검 → DB·API·파일 I/O 대기 분석 → 메모리 및 웹서버 로그 확인입니다.








