워드프레스로 만든 우리의 홈페이지가 어느날 죽었다.
다급하게 인스턴스를 재부팅해서 살려냈지만 몇개월 뒤 또 죽어버렸다.
계속 죽으니 뭔가 원인이 있겠다 싶어 한번 파보았다
기존 우리의 ec2사양은
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만 병렬로 처리해 속도가 훨씬 빠르다
사진에서 보듯이 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
평균 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의 쿼리가 오래걸리는 부분이 있는지 확인하는것이 좋게따
sudo a2dismod php8.1
sudo a2dismod mpm_prefork
sudo a2enmod mpm_event
sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.1-fpm
이 설정은 /etc/apache2/conf-available/php8.1-fpm.conf 를 Apache에 연결
sudo systemctl restart php8.1-fpm
sudo systemctl restart apache2
확인 명령어
apache2ctl -M | grep mpm
결과: mpm_event_module (shared)
ps aux | grep php-fpm
결과: 결과값에 php-fpm이 있어야함