아파치(Apache) 서버 설정 꿀팁: 성능 최적화 방법

아파치(Apache HTTP Server)는 안정성과 호환성 측면에서 매우 신뢰받는 웹 서버이지만, 기본값만으로는 트래픽 급증 상황에서 성능이 급격히 저하될 수 있다. 고성능을 목표로 한다면 프로세싱 모델, 연결 유지, 압축·캐싱, TLS, PHP 실행 방식 등 핵심 영역을 체계적으로 손봐야 한다. 아래 체크리스트 순서로 적용하면 병목을 빠르게 제거하고 응답 시간을 단축할 수 있다.

1) 최신 버전과 모듈 점검

아파치 2.4 최신 브랜치는 HTTP/2, 이벤트 기반 MPM, 최신 OpenSSL과의 호환을 제공한다. 배포판 저장소 기준 최신 패키지를 적용하고, 사용하지 않는 모듈은 비활성화해 메모리 사용량을 줄인다.

sudo apt update && sudo apt install apache2 -ysudo a2query -m            # 활성 모듈 점검sudo a2dismod cgi dav_*    # 불필요 모듈 예시sudo systemctl restart apache2

모듈을 최소화하면 컨텍스트 스위칭과 초기화 비용이 줄어들어 동시 접속에서 유리하다.

2) MPM(event)로 전환하고 스레드 파라미터 튜닝

MPM은 요청 처리 모델을 결정한다. 2.4 계열에서는 event MPM이 Keep-Alive 연결을 효율적으로 처리해 고동시성 환경에서 유리하다. 기존 prefork를 쓰고 있다면 전환한다.

sudo a2dismod mpm_preforksudo a2enmod mpm_eventsudo systemctl restart apache2

스레드·프로세스 수는 CPU 코어와 메모리 기준으로 산정한다. 기본 템플릿:

<IfModule mpm_event_module>
  StartServers             2
  ServerLimit              16
  ThreadsPerChild          25
  MaxRequestWorkers        400
  MinSpareThreads          50
  MaxSpareThreads          200
  ThreadLimit              64
</IfModule>

동시 접속 피크 × 평균 메모리 사용량이 시스템 메모리를 넘지 않도록 MaxRequestWorkers를 조정한다. 과대 설정은 스래싱을, 과소 설정은 503을 초래한다.

3) PHP는 mod_php 대신 PHP‑FPM + proxy_fcgi

event MPM과 mod_php는 궁합이 좋지 않다. PHP‑FPM을 별도 프로세스로 띄우고 Apache는 리버스 프록시로 연결한다.

sudo apt install php-fpm -ysudo a2enmod proxy proxy_fcgi setenvifsudo a2enconf php*-fpmsudo systemctl reload apache2

수동 설정 예:

<FilesMatch "\.php$">
  SetHandler "proxy:unix:/run/php/php8.2-fpm.sock|fcgi://localhost/"
</FilesMatch>

PHP‑FPM의 pm.max_children, pm.max_requests를 트래픽 패턴과 메모리에 맞게 조정해 워커 재사용성과 안정성을 높인다.

4) KeepAlive와 커넥션 관리

지속 연결은 TLS 핸드셰이크 비용과 3‑way handshake를 줄여준다. 단, 타임아웃이 길면 워커를 점유한다.

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 3
Timeout 60

짧은 KeepAliveTimeout(2~5초)과 적절한 MaxRequestWorkers 조합이 고동시성에서 가장 안정적이다.

5) 전송 압축: Brotli(권장)와 Gzip

텍스트 자원은 압축으로 대역폭을 크게 절약한다. 가능한 경우 Brotli가 Gzip보다 압축률이 높다.

# Brotli
LoadModule brotli_module modules/mod_brotli.so
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css text/javascript application/javascript application/json image/svg+xml
BrotliCompressionQuality 5

# Gzip (fallback)
<IfModule mod_deflate.c>
  AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css application/javascript application/json image/svg+xml
</IfModule>

품질은 4~6이 속도와 압축률 균형이 좋다. 이중 압축을 피하기 위해 이미지, PDF 등 이미 압축된 포맷은 제외한다.

6) 캐싱: 서버 캐시 + 브라우저 캐시

원본 처리 비용을 줄이려면 디스크 캐시와 브라우저 캐시를 모두 설정한다.

# 서버 캐시
LoadModule cache_module modules/mod_cache.so
LoadModule cache_disk_module modules/mod_cache_disk.so
CacheQuickHandler On
CacheLock On
CacheIgnoreNoLastMod On
CacheEnable disk /
CacheDefaultExpire 3600
CacheMaxFileSize 10485760

# 브라우저 캐시
<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType text/css "access plus 7 days"
  ExpiresByType application/javascript "access plus 7 days"
  ExpiresByType image/jpeg "access plus 30 days"
  ExpiresDefault "access plus 1 hour"
</IfModule>
<IfModule mod_headers.c>
  Header set Cache-Control "public, max-age=604800"
</IfModule>

동적 페이지는 Cache-Control: no-store 또는 private로 구분해 오캐시로 인한 이슈를 방지한다.

7) HTTP/2 활성화와 TLS 최적화

HTTP/2는 멀티플렉싱과 헤더 압축으로 체감 속도를 크게 개선한다. HTTPS가 전제다.

sudo a2enmod http2 ssl headers

가상호스트 예시:

<VirtualHost *:443>
  Protocols h2 http/1.1
  SSLEngine on
  SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
  SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

  SSLProtocol             all -SSLv3 -TLSv1 -TLSv1.1
  SSLCipherSuite          TLSv1.2+HIGH:!aNULL:!MD5:!3DES
  SSLHonorCipherOrder     off
  SSLCompression          off
  SSLUseStapling          on
  Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>

TLS 1.2/1.3만 허용하고, OCSP Stapling과 HSTS로 초회 연결과 중간자 공격 위험을 낮춘다. 인증서는 certbot으로 자동 갱신한다.

sudo apt install certbot python3-certbot-apache -ysudo certbot –apache -d example.com -d www.example.com

8) 정적 파일 경로 최적화와 파일 전송 옵션

정적 자산을 전용 디렉터리로 분리하고 Alias로 노출하면 접근 제어와 캐싱 정책을 분리 관리하기 쉽다.

Alias /static/ "/var/www/static/"
<Directory "/var/www/static/">
  Require all granted
  Options FollowSymLinks
</Directory>

커널 I/O 도움 옵션:

EnableSendfile On
EnableMMAP On

가상화·네트워크 스토리지 환경에서 파일 깨짐이 보이면 Sendfile을 Off로 전환해 진단한다.

9) 보안과 노이즈 감소: 토큰, 디렉터리 리스팅, 요청 크기

불필요한 정보 노출과 과도한 요청으로 인한 낭비를 줄인다.

ServerTokens Prod
ServerSignature Off
<Directory "/var/www/html">
  Options -Indexes
</Directory>
LimitRequestBody 10485760
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500

대용량 업로드가 필요한 API는 가상호스트·로케이션 단위로 예외값을 둔다.

10) 로그 전략과 로테이션

과도한 디버그 로그는 디스크 I/O 병목을 만든다. 운영 구간에서는 warn 수준을 기본으로 하고, 액세스 로그는 압축 로테이션을 켠다.

LogLevel warn
CustomLog ${APACHE_LOG_DIR}/access.log combined
ErrorLog  ${APACHE_LOG_DIR}/error.log

리눅스 배포판에는 logrotate 설정이 기본 포함되어 있으므로 보존 주기와 압축 여부만 점검한다. 대규모 환경에서는 중앙집중 수집(예: Filebeat → Elasticsearch/OpenSearch)으로 분석과 보관을 분리한다.

11) 프록시와 로드밸런싱

여러 앱 인스턴스를 뒤에 두고 아파치를 L7 로드밸런서로 사용할 수 있다.

LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule lbmethod_byrequests_module modules/mod_lbmethod_byrequests.so

<Proxy "balancer://appcluster">
  BalancerMember http://127.0.0.1:8081
  BalancerMember http://127.0.0.1:8082
  ProxySet lbmethod=byrequests
</Proxy>

ProxyPass        /api/ balancer://appcluster/
ProxyPassReverse /api/ balancer://appcluster/

헬스체크, 스티키 세션이 필요하면 응용 레벨 쿠키 또는 헤더 기반 정책을 병행한다.

12) 운영 점검 체크리스트

  • htop/atop으로 CPU, 런큐, 메모리 사용률 모니터링
  • ab, wrk, hey로 부하 테스트 후 병목 포인트 측정
  • MaxRequestWorkers, PHP‑FPM pm.max_children 상관 조정
  • 정적 자산은 CDN으로 오프로딩, 원서버는 오리진 역할 집중
  • 배포 자동화(Ansible/CI)로 설정 표준화 및 재현성 확보

13) 문제 해결 힌트

  • 499/504 증가: 백엔드 응답 지연, 프록시 타임아웃 상향 및 앱 최적화
  • 502/503: 백엔드 다운 또는 워커 부족, 앱 재시작과 MaxRequestWorkers 재조정
  • CPU 100% 고정: PHP‑FPM 워커 과다 혹은 쿼리 병목, 쿼리 캐시·인덱스 점검
  • 디스크 I/O 스파이크: 로그 레벨 과다, 캐시 디렉터리 백업 충돌 점검

위 설정을 단계별로 적용하면 CPU·메모리 효율이 개선되고, 대기 시간과 오류율이 가시적으로 감소한다. 특히 event MPM + PHP‑FPM 구조, HTTP/2, Brotli/캐싱, HSTS·OCSP 조합은 대부분의 웹 워크로드에서 체감 성능 향상과 안정성을 동시에 확보하는 안전한 기본기다. 지속적인 부하 테스트와 관측(로그·메트릭·트레이스)을 통해 자신의 트래픽 패턴에 맞게 수치를 미세 조정하면 최적의 TTFB, p95 응답 시간을 달성할 수 있다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다