Image

지식 기반 → 트래픽이 많은 사이트를 위한 VPS에 php-fpm 설정

높은 트래픽을 가진 웹사이트는 서비스의 특별한 구성이 필요합니다. 선택한 서비스에 따라 VPS 서버의 높은 성능을 달성하기 위한 권장 사항이 있습니다.

단순히 리소스를 늘리는 것만으로는 VPS 서버의 높은 성능을 얻을 수 없습니다. 서비스 구성도 필요합니다.

기본적으로 서비스는 낮거나 중간 정도의 트래픽을 가진 일반적인 프로젝트에 적합한 기본 설정을 가지고 있습니다.

명확성을 위해 트래픽 기준을 정의하겠습니다:

  • 낮은 웹사이트 트래픽: 월 10,000회 방문 이하(하루 약 300회, 5분마다 1회 방문).
  • 중간 웹사이트 트래픽: 월 10,000~90,000회 방문—평균 50,000회/월(하루 약 1,600회, 분당 1회 방문).
  • 높은 웹사이트 트래픽: 월 100,000회 방문 이상, 즉 분당 2회 방문 이상.

nginx를 프록시 웹 서버로 사용하고 php-fpm(이 경우 php8.3-fpm)을 주요 처리기로 사용하는 구성을 분석해 보겠습니다.

우리는 Linux Debian 12를 실행하는 VPS 서버를 사용했으며, 6개의 CPU 코어, 8GB RAM, 50GB SSD를 갖추고 있습니다.

우리는 php8.3-fpm에 대해 특별히 성능을 최적화할 것입니다. 기본 구성으로 링크 분석 스크립트를 실행했으며, 몇 분 후 요청 속도가 초당 9개에서 5개로 떨어졌습니다. 5분 더 지나자 성능은 초당 1.5개 요청으로 감소했고, 서비스가 병목 현상을 일으키기 시작하여 곧 Bad Gateway 오류를 반환했습니다.

그동안 서버 부하가 크게 증가하지 않았으며, 요청을 처리할 수 있는 충분한 리소스가 여전히 남아 있었습니다.

1. 새로운 php-fpm 구성 파일

/etc/php/8.3/fpm/pool.d/domain.conf 에 새 구성 파일을 만듭니다.

기존 파일은 www.conf.bak 으로 이름을 변경합니다. 이렇게 하면 사용되지 않으며, 필요할 경우 .bak 접미사를 제거하여 복원할 수 있습니다.

2. 구성 세부 사항

[www]
user = www-data
group = www-data
listen = 127.0.0.1:9000
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

; Process manager
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 500
pm.max_spawn_rate = 32
pm.process_idle_timeout = 10s

; Connection settings
listen.backlog = 65535
listen.allowed_clients = 127.0.0.1

; Timeouts
request_terminate_timeout = 30s
request_slowlog_timeout = 5s
slowlog = /var/log/php8.3-fpm/slow.log

; Status monitoring
pm.status_path = /fpm-status
ping.path = /ping
ping.response = pong

; Logging
access.log = /var/log/php8.3-fpm/access.log
access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{milli}dms"
catch_workers_output = yes
decorate_workers_output = no

; Security
security.limit_extensions = .php .php3 .php4 .php5 .php7 .php8
clear_env = no

; Performance tweaks
rlimit_files = 65535
rlimit_core = unlimited

; PHP settings
php_admin_value[error_log] = /var/log/php8.3-fpm/error.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 128M
php_admin_value[post_max_size] = 32M
php_admin_value[upload_max_filesize] = 32M
php_admin_value[max_execution_time] = 30
php_admin_value[session.gc_maxlifetime] = 1440

3. 추가 설정

로그 디렉토리가 존재하지 않으면 생성합니다:

mkdir -p /var/log/php8.3-fpm

3.1 구성 주석

  • listen = 127.0.0.1:9000 - nginx 구성과 일치해야 하며, 그 반대도 마찬가지입니다.
  • pm.max_children = 50 - 사용 가능한 RAM에 따라 달라집니다(자식 프로세스당 50MB → PHP에 약 2GB).
  • pm.start_servers = 10 - pm.max_children`의 약 20%.
  • pm.max_requests = 500 - 메모리 누수를 방지하기 위해 500개 요청 후 워커를 재시작합니다(방문자에게는 감지되지 않으며 작동에 영향을 미치지 않음).
  • request_terminate_timeout = 30s - 멈춘 요청을 종료합니다.
  • request_slowlog_timeout = 5s - 느린 요청을 기록합니다.
  • slowlog = /var/log/php8.3-fpm/slow.log

CMS 기반 사이트의 경우 느린 요청 로그는 호출 스택을 표시하므로 큰 도움이 되지 않을 수 있지만, 요청 시작과 종료의 시간 간격에 대한 유용한 정보를 제공할 수 있습니다.

/fpm-status 를 모니터링하려면 nginx 서버 블록에 다음을 추가합니다:

    location = /fpm-status {
        allow 127.0.0.1;    # 로컬 액세스만 허용
        allow 192.168.10.100; # 또는 신뢰할 수 있는 네트워크
        deny all;          # 나머지 모두 차단

        include /etc/nginx/fastcgi_params;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_param SCRIPT_FILENAME $request_filename;
    }

출력 내용은 다음과 같습니다:

pool:                 www
process manager:      dynamic
start time:           04/Jun/2025:18:16:50 +0000
start since:          814
accepted conn:        239
listen queue:         0
max listen queue:     0
listen queue len:     128
idle processes:       9
active processes:     1
total processes:      10
max active processes: 3
max children reached: 0
slow requests:        0

4. 새 구성 적용

구성 파일에 오류가 있는지 확인합니다:

php-fpm8.3 -t

오류가 없으면 서비스를 재시작합니다:

systemctl restart php8.3-fpm

5. 재테스트

새 구성으로 비슷한 테스트를 진행했을 때 CPU 부하가 눈에 띄게 증가했지만, 성능은 몇 분 후 20%만 감소(초당 9개 요청에서 7개로)하고 안정화되었습니다. 모든 요청(25분 동안 약 10,000개 요청, 즉 분당 400개 요청 또는 초당 약 7개 요청)은 상태 코드 200으로 성공적으로 처리되었습니다.

동시에 테스트하며 웹사이트 페이지를 탐색했을 때 시각적으로 성능이 눈에 띄게 빨라졌습니다. 이제 이 웹 서비스 구성으로 서버 리소스가 이전처럼 유휴 상태로 남아 있지 않고 완전히 활용됩니다.





No Comments Yet