Computer >> 컴퓨터 >  >> 시스템 >> Linux

고트래픽 웹사이트를 위한 리눅스 서버 Apache·PHP 최적화 설정 방법 (MPM Event + PHP-FPM)

고트래픽 웹사이트를 위한 리눅스 서버 Apache·PHP 최적화 설정 방법 (MPM Event + PHP-FPM)

LAMP 스택의 숨은 함정: mpm_prefork의 한계

거의 모든 LAMP 스택(Linux, Apache, MySQL, PHP) 설치 튜토리얼은 PHP 스크립트를 처리할 때 아파치에 내장된 모듈을 사용하도록 안내합니다. 예를 들어 우분투(Ubuntu)에서는 sudo apt install libapache2-mod-php 명령으로 패키지를 설치하는 방식입니다. 그런데 이 패키지를 설치하면 아파치가 강제로 mpm_prefork 방식을 사용하게 됩니다. 이 방식에서는 방문자가 사이트에 접속할 때마다 새로운 프로세스가 생성되어 해당 연결을 처리하는데, 트래픽이 적을 때는 큰 문제가 없습니다.

그러나 트래픽이 갑자기 폭주하면 심각한 문제가 발생합니다. 예컨대 레딧(Reddit)에 여러분의 웹사이트가 소개되었는데 해당 게시물이 인기를 끌면, 단 몇 분 만에 수천 명의 방문자가 몰려들 수 있습니다.

최선의 경우, 아파치가 트래픽 폭증을 버텨낸다 하더라도 일부 방문자들은 페이지가 로드될 때까지 30초에서 60초 가까이 기다려야 할 수 있습니다. 오늘날의 인터넷 환경에서 이는 용납하기 어려운 상황입니다. 최악의 경우 서버가 심하게 느려지고, 리소스 부족으로 일부 연결은 아예 끊겨서 방문자의 브라우저에 에러 화면만 보이게 됩니다.

어느 쪽이든 좋은 결과는 아닙니다. 수백, 수천 명의 관심 있는 독자나 고객, 팬들의 주목을 잃을 수 있기 때문입니다.

안타깝게도 PHP는 어느 쪽이든 상당히 많은 리소스를 소모하는 언어입니다. 하지만 mpm_event를 사용하면 아파치가 갑작스러운 트래픽 폭증을 훨씬 효율적으로 처리할 수 있습니다. 다만 서버에 최소 2GB의 RAM과 2개 이상의 CPU 코어(실제 또는 가상)가 장착되어 있어야 하며, 초당 방문자가 10명을 넘는 극심한 트래픽 급증이 예상된다면 그 이상의 사양을 권장합니다. VPS(가상 전용 서버)를 사용 중이라면 가상 CPU 코어를 추가하고 SSD 저장장치를 사용하는 것이 좋습니다. RAM은 그다음 문제입니다.

데비안 계열 배포판에서 Apache MPM Event와 PHP-FPM 사용하기

데비안, 우분투 또는 이 계열의 다른 배포판에서는 "libapache2-mod-php" 패키지만 설치하지 않으면 됩니다. 아파치를 설치하면 기본적으로 MPM event가 활성화됩니다. 하지만 앞서 언급한 패키지를 설치하는 순간, 스크립트가 MPM event를 비활성화하고 MPM prefork를 활성화합니다. 아파치의 PHP 모듈은 (안전하게) mpm_prefork 환경에서만 동작하기 때문입니다. 물론 "libapache2-mod-php" 없이는 PHP 파일을 처리할 수 없으므로, 대신 PHP-FPM을 사용해야 합니다. 다음은 깨끗한 서버에 LAMP 스택을 설치하는 과정이며, 여러분의 웹 애플리케이션 요구 사항에 맞게 조정하면 됩니다.

먼저 root로 로그인한 후 아파치를 설치합니다.

apt update && apt install apache2

이 시점에서 아파치가 기본적으로 MPM event가 활성화된 상태인지 확인할 수 있습니다.

apachectl -V

고트래픽 웹사이트를 위한 리눅스 서버 Apache·PHP 최적화 설정 방법 (MPM Event + PHP-FPM)

PHP-FPM을 설치합니다.

apt install php-fpm

설치 과정에서 아파치에서 PHP 프로세서를 활성화하는 방법에 대한 안내가 출력됩니다.

고트래픽 웹사이트를 위한 리눅스 서버 Apache·PHP 최적화 설정 방법 (MPM Event + PHP-FPM)

FastCGI 프로토콜을 활성화합니다.

a2enmod proxy_fcgi

아파치용 PHP-FPM 기본 설정을 활성화합니다.

a2enconf php7.0-fpm

참고: 향후 데비안/우분투 버전에서는 PHP-FPM 버전이 달라짐에 따라 이 명령어도 a2enconf php7.6-fpm처럼 변경될 수 있습니다.

아파치를 재시작합니다.

systemctl restart apache2

PHP 애플리케이션에 필요한 나머지 구성 요소를 설치합니다. 예를 들면 다음과 같습니다.

apt install mariadb-server php-mysql

이 명령은 데이터베이스 서버와 PHP MySQL 모듈을 설치하여 PHP 애플리케이션이 데이터베이스에 연결할 수 있도록 해줍니다.

레드햇 계열 배포판에서 Apache MPM Event와 PHP-FPM 사용하기

또 하나의 인기 있는 서버 배포판 선택지는 레드햇(RedHat) 또는 CentOS입니다. 위와 마찬가지로 MPM event가 활성화된 아파치와 PHP-FPM을 새로 설치하는 과정을 살펴보겠습니다.

root로 로그인한 후 아파치를 설치합니다.

yum install httpd

데비안 계열과 달리, 여기서는 아파치가 기본적으로 MPM prefork를 사용한다는 것을 확인할 수 있습니다(작성 시점 기준 최신 CentOS 7 기준).

apachectl -V

고트래픽 웹사이트를 위한 리눅스 서버 Apache·PHP 최적화 설정 방법 (MPM Event + PHP-FPM)

MPM event를 활성화하려면 설정 파일을 수정해야 합니다. 먼저 prefork 모듈을 주석 처리합니다.

sed -i '/mpm_prefork\.so$/s/^/#/' /etc/httpd/conf.modules.d/00-mpm.conf

이 명령은 # 기호를 추가하여 LoadModule mpm_prefork_module modules/mod_mpm_prefork.so 줄을 주석 처리(비활성화)합니다.

고트래픽 웹사이트를 위한 리눅스 서버 Apache·PHP 최적화 설정 방법 (MPM Event + PHP-FPM)

이번에는 반대로 #LoadModule mpm_event_module modules/mod_mpm_event.so 줄 앞의 # 기호를 제거하여 주석 해제(활성화)합니다.

sed -i '/mpm_event\.so$/s/^#//' /etc/httpd/conf.modules.d/00-mpm.conf

아파치를 시작하고 부팅 시 자동 시작되도록 설정합니다.

systemctl start httpd.service
systemctl enable httpd.service

아파치가 이제 MPM event를 사용하는지 확인합니다.

apachectl -V

고트래픽 웹사이트를 위한 리눅스 서버 Apache·PHP 최적화 설정 방법 (MPM Event + PHP-FPM)

PHP-FPM과 FastCGI 모듈을 설치합니다.

yum install php-fpm mod_fcgid

PHP 처리 설정 파일 생성

"/etc/httpd/conf.d/php.conf" 파일을 만들어 아파치가 PHP 파일을 처리하는 방법을 지정합니다. 아래 내용 전체를 복사한 뒤 터미널에 한 번에 붙여넣고 ENTER 키를 누르세요.

cat <<PASTE > /etc/httpd/conf.d/php.conf
# Redirect to local php-fpm if mod_php is not available
<IfModule !mod_php7.c>
<IfModule proxy_fcgi_module>
# Enable http authorization headers
<IfModule setenvif_module>
SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1
</IfModule>
 
<FilesMatch ".+\.ph(p[3457]?|t|tml)$">
#SetHandler "proxy:unix:/run/php/php7.0-fpm.sock|fcgi://localhost"
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>
<FilesMatch ".+\.phps$">
# Deny access to raw php sources by default
# To re-enable it's recommended to enable access to the files
# only in specific virtual host or directory
Require all denied
</FilesMatch>
# Deny access to files without filename (e.g. '.php')
<FilesMatch "^\.ph(p[3457]?|t|tml|ps)$">
Require all denied
</FilesMatch>
</IfModule>
</IfModule>
PASTE

이 훌륭한 설정의 원조는 데비안입니다. 다른 자료에서는 다음과 같이 훨씬 간단한 설정 파일을 권장하기도 합니다.

<FilesMatch \.php$>
SetHandler "proxy:fcgi://127.0.0.1:9000"
</FilesMatch>

그러나 이런 단순한 설정은 일부 공격에 취약하며, 특정 서비스에 장애가 발생하면 PHP 원본 파일이 그대로 외부에 노출될 수 있습니다. 이 경우 저장된 비밀번호, 코드, 민감한 데이터까지 유출될 위험이 있습니다. 따라서 보안이 강화된 데비안 방식의 설정을 사용하는 것이 좋습니다.

아파치를 재시작합니다.

systemctl restart httpd.service

PHP-FPM을 시작하고 부팅 시 자동 시작되도록 설정합니다.

systemctl start php-fpm.service
systemctl enable php-fpm.service

마무리: 기본 설정을 넘어서

이제 여러분의 아파치 서버는 트래픽 증가에 훨씬 유연하게 대응할 수 있게 되었습니다. 다만 현재 적용된 것은 대부분의 사람들에게 "최적"이라고 여겨지는 기본 설정일 뿐임을 기억하세요. HTTP 서버에서 진정한 성능을 끌어내고 싶다면 조정할 수 있는 다양한 변수들을 반드시 학습해야 합니다. 이 변수들의 최적값은 서버의 리소스, 예상 트래픽 패턴, PHP 애플리케이션의 특성에 따라 크게 달라지기 때문입니다.