apache 그리고 fpm-php

wony·2025년 4월 18일
0
post-thumbnail

워드프레스로 만든 우리의 홈페이지가 어느날 죽었다.
다급하게 인스턴스를 재부팅해서 살려냈지만 몇개월 뒤 또 죽어버렸다.
계속 죽으니 뭔가 원인이 있겠다 싶어 한번 파보았다

기존 우리의 ec2사양은

  • t3.small
  • vCPU 2개
  • 메모리 2GB
  • 네트워크 최대 5Gbps
  • 스왑은 2GB로 설정해둔 상태였다

jmeter로 150명의 유저가 1분동안 2번씩 접속하도록 셋팅해서 돌려보니

인스턴스가 중지되지는 않았지만 어마어마하게 느려지며 응답을 받지 못하게 되었다
원인을 찾다가 fpm-php라는것을 알게되었다

기존우리의 워드프레스 홈페이지는 mod_php로 되어 있었다
이 둘의 차이를 음식점으로 비유해보자면


mod_php는 서버가 문도 열고 손님 응대도 하고 요리도 해야하는 것이다 (손님 한명당 직원 한명 배정)
그래서 직원의 처리 속도가 느리고 부하가 온다


fpm-php는 서버는 문만 열고 요리는 전문 요리사가 병렬로 요리를 하는 방식으로 효율성이 증대된 방식이다

ssh에서 아래의 명령어를 입력하면 위처럼 볼 수 있다

top

mod_php는 apache2 내부에서 php를 처리하는 방식이고
php-fpm은 apache2와 별개로 php를 처리하는 방식이다
php-fpm은 apache와 php처리가 분리되어 php만 병렬로 처리해 속도가 훨씬 빠르다

max_children

사진에서 보듯이 mod_php에서는 수많은 프로세스가 생성된 것을 볼 수 있다
우리는 150개가 max이다

fpm-php는 20개만 생성된 것을 볼 수 있다
max_children을 20으로 설정해두었기 때문이다

max_children = 20 이 의미하는 바는

동시에 php를 처리할 수 있는 프로세스 수가 20개
예를 들어 php-fpm프로세스가 20개 있다면 (pm.max_children = 20)
php 요청을 처리하는데 0.2초가 걸린다고 가정
그렇다면 1초에 한 프로세스가 5명 처리 20*5 = 1초에 100명 가능
(실제 처리 시간은 응답시간, db, 브라우저등 여러 요소에 따라 처리 시간이 상이함)

20으로 설정한 이유는

max_children = (Total RAM - OS RAM - DB RAM) / average PHP process memory

  • 일반적인 워드프레스 기준: 25~35MB
  • 무거운 테마/플러그인: 40~50MB도 가능
  • 총 메모리: 2GB = 2048MB
  • OS + 기타 프로세스 약 500MB 사용
  • MySQL 등 백엔드 사용 약 500MB
  • PHP-FPM에 쓸 수 있는 여유 메모리: 약 1000MB

평균 PHP 프로세스 메모리 40MB라 가정 시: max_children = 1000 / 40 = 25

25는 cpu에 무리를 줄 수 있어 20으로 안정적으로 유지하기 위해 설정하였다

테스트 결과


개선전에는 150명이 1분간 2번씩 방문 했을때
10분이상이 소요되며 14분이 지났을때 요청을 중지시켜버렸다
상당한 시간이 소요된다는걸 볼 수 있었다
cpu도 49%까지 올라갔다

개선후 동일한 환경에서 테스트를 진행하였더니
1분 54초만에 모든 유저가 테스트를 완료하였다
에러율도 0%였고 cpu도 22%까지 밖에 가지 않았다

매우 큰 차이를 보였다

결론

워드프레스처럼 플러그인을 사용하고 용량이 큰 프로젝트의 경우 fpm으로 php를 실행하는것이 빠르며
메모리 누수도 줄일 수 있다
앞으로 더 개선 할 수 있는 방법은 캐시등을 도입하고 mysql의 쿼리가 오래걸리는 부분이 있는지 확인하는것이 좋게따

  1. mod_php 비활성화
sudo a2dismod php8.1
  1. prefork MPM 비활성화
sudo a2dismod mpm_prefork
  1. event MPM 활성화
sudo a2enmod mpm_event
  1. php-fpm 사용을 위한 설정 (proxy 관련)
sudo a2enmod proxy_fcgi setenvif
  1. php-fpm 모듈 활성화
sudo a2enconf php8.1-fpm

이 설정은 /etc/apache2/conf-available/php8.1-fpm.conf 를 Apache에 연결

  1. php-fpm 서비스 실행 (이미 설치돼 있으면 생략 가능)
sudo systemctl restart php8.1-fpm
  1. Apache 재시작
sudo systemctl restart apache2

확인 명령어

apache2ctl -M | grep mpm
결과: mpm_event_module (shared)

ps aux | grep php-fpm
결과: 결과값에 php-fpm이 있어야함

profile
무럭무럭 성장중🌿

0개의 댓글