아파치 mod_expires 사용 방법은 무엇인가요?
💡 요약 정리
- mod_expires는 Apache 확장 모듈로 이미지/파일의 만료일 지정을 통해 트래픽 감소와 로딩 속도를 향상시킵니다.
- 특정 MIME-TYPE에 대한 만료일자를 지정하여 기간 경과 시에만 재전송이 발생합니다.
- httpd.conf에서 LoadModule expires_module 확인 후 httpd-vhosts.conf에서 ExpiresByType으로 설정합니다.
- "month", "weeks", "days", "hours" 등 다양한 기간 단위로 캐시 만료 시간을 설정할 수 있습니다.
설치환경
- CentOS 5.x (64bit)
- Apache 2.2.23
1. mod_expires란?
정의
mod_expires는 Apache의 확장 모듈로, 이미지나 파일에 만료일을 지정함으로써 트래픽 감소와 로딩 속도 향상을 달성할 수 있습니다.
동작 원리
특정 MIME-TYPE에 대한 만료일자를 지정하면, 브라우저는 지정된 기간 동안 캐시된 파일을 사용하고, 기간이 경과했을 때만 서버에서 재전송을 요청합니다.
주요 효과
- 트래픽 절감: 정적 파일의 반복 전송 방지
- 로딩 속도 향상: 브라우저 캐시 활용으로 페이지 로딩 시간 단축
- 서버 부하 감소: 불필요한 파일 전송 요청 감소
2. mod_expires 모듈 확인 및 설치
모듈 확인
httpd.conf 파일에서 mod_expires 항목을 확인합니다. 컴파일 시 --enable-expires 옵션을 넣었다면 모듈이 이미 있을 것입니다.
[root@cafe24 ~]# vi /home/APM/apache/conf/httpd.conf
확인할 내용:
LoadModule include_module modules/mod_include.so
LoadModule filter_module modules/mod_filter.so
LoadModule substitute_module modules/mod_substitute.so
LoadModule deflate_module modules/mod_deflate.so
LoadModule log_config_module modules/mod_log_config.so
LoadModule logio_module modules/mod_logio.so
LoadModule env_module modules/mod_env.so
LoadModule expires_module modules/mod_expires.so # 이 라인 확인
LoadModule headers_module modules/mod_headers.so
LoadModule ident_module modules/mod_ident.so
LoadModule setenvif_module modules/mod_setenvif.so
LoadModule version_module modules/mod_version.so
LoadModule ssl_module modules/mod_ssl.so
LoadModule mime_module modules/mod_mime.so
LoadModule dav_module modules/mod_dav.so
apxs를 이용한 모듈 설치 (DSO 방식)
모듈이 없을 경우 apxs를 이용하여 추가 컴파일할 수 있습니다. (단, DSO로 설치된 경우에 한함)
Apache 소스 디렉토리에 있는 mod_expires.c 파일을 이용합니다:
[root@cafe24 metadata]# /home/APM/apache/bin/apxs -i -a -c /root/src/httpd-2.2.23/modules/metadata/mod_expires.c
설치 과정 출력:
/home/APM/apache/build/libtool --silent --mode=compile gcc -prefer-pic -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -g -O2 -pthread -I/home/APM/apache/include -I/home/APM/apache/include -I/home/APM/apache/include -c -o /root/src/httpd-2.2.23/modules/metadata/mod_expires.lo /root/src/httpd-2.2.23/modules/metadata/mod_expires.c && touch /root/src/httpd-2.2.23/modules/metadata/mod_expires.slo
/home/APM/apache/build/libtool --silent --mode=link gcc -o /root/src/httpd-2.2.23/modules/metadata/mod_expires.la -rpath /home/APM/apache/modules -module -avoid-version /root/src/httpd-2.2.23/modules/metadata/mod_expires.lo
/home/APM/apache/build/instdso.sh SH_LIBTOOL='/home/APM/apache/build/libtool' /root/src/httpd-2.2.23/modules/metadata/mod_expires.la /home/APM/apache/modules
/home/APM/apache/build/libtool --mode=install cp /root/src/httpd-2.2.23/modules/metadata/mod_expires.la /home/APM/apache/modules/
cp /root/src/httpd-2.2.23/modules/metadata/.libs/mod_expires.so /home/APM/apache/modules/mod_expires.so
cp /root/src/httpd-2.2.23/modules/metadata/.libs/mod_expires.lai /home/APM/apache/modules/mod_expires.la
cp /root/src/httpd-2.2.23/modules/metadata/.libs/mod_expires.a /home/APM/apache/modules/mod_expires.a
chmod 644 /home/APM/apache/modules/mod_expires.a
ranlib /home/APM/apache/modules/mod_expires.a
PATH="$PATH:/sbin" ldconfig -n /home/APM/apache/modules
----------------------------------------------------------------------
Libraries have been installed in:
/home/APM/apache/modules
chmod 755 /home/APM/apache/modules/mod_expires.so
[activating module `expires' in /home/APM/apache/conf/httpd.conf]
설치 성공 확인:
Libraries have been installed in: /home/APM/apache/moduleschmod 755 /home/APM/apache/modules/mod_expires.so[activating module 'expires' in /home/APM/apache/conf/httpd.conf]
3. mod_expires 적용하기
httpd-vhosts.conf 파일 수정
가상 호스트 설정 파일에 expires 설정을 추가합니다:
[root@cafe24 ~]# vi /home/APM/apache/conf/extra/httpd-vhosts.conf
기본 설정 예시
NameVirtualHost *:80
#
# VirtualHost example:
# Almost any Apache directive may go into a VirtualHost container.
# The first VirtualHost section is used for all requests that do not
# match a ServerName or ServerAlias in any <VirtualHost> block.
<VirtualHost *:80>
DocumentRoot "/home/APM/apache/htdocs"
ServerName xxx.xxx.xxx.xxx
ErrorLog "logs/dummy-host.example.com-error_log"
CustomLog "logs/dummy-host.example.com-access_log" common
# mod_expires 설정
ExpiresActive On # <--- expires 설정 활성화
ExpiresByType image/jpeg "access plus 1 month" # <--- MIME 타입 image/jpeg는 1개월 캐시
ExpiresByType image/gif "access plus 1 month" # <--- MIME 타입 image/gif는 1개월 캐시
</VirtualHost>
<VirtualHost *:80>
ServerAdmin webmaster@dummy-host2.example.com
DocumentRoot "/home/APM/apache/docs/dummy-host2.example.com"
ServerName dummy-host2.example.com
ErrorLog "logs/dummy-host2.example.com-error_log"
CustomLog "logs/dummy-host2.example.com-access_log" common
</VirtualHost>
설정 지시자 설명
ExpiresActive On
- mod_expires 기능을 활성화합니다.
- 이 지시자가 없으면 ExpiresByType 설정이 동작하지 않습니다.
ExpiresByType [MIME-TYPE] "[기준] [기간]"
- 특정 MIME 타입에 대한 캐시 만료 시간을 설정합니다.
- 기준:
access(파일 접근 시점 기준) - 기간:
plus 1 month(1개월 후 만료)
4. 다양한 Expires 기간 설정
기간 단위
expires 기간은 다양한 시간 단위로 설정할 수 있습니다:
months또는month: 월weeks또는week: 주days또는day: 일hours또는hour: 시간minutes또는minute: 분seconds또는second: 초
설정 예시
ExpiresByType image/jpeg "access plus 1 month" # 1개월
ExpiresByType text/css "access plus 1 week" # 1주일
ExpiresByType application/javascript "access plus 7 days" # 7일
ExpiresByType text/html "access plus 2 hours" # 2시간
5. 다양한 MIME 타입에 대한 Expires 설정
이미지뿐만 아니라 다음과 같이 다양한 MIME 타입에 expires를 추가할 수 있습니다:
스크립트 및 스타일시트
ExpiresByType application/x-javascript "access plus 1 month"
ExpiresByType text/css "access plus 1 month"
이미지 파일
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/bmp "access plus 1 month"
ExpiresByType image/cgm "access plus 1 month"
ExpiresByType image/tiff "access plus 1 month"
비디오 파일
ExpiresByType video/mpeg "access plus 1 month"
ExpiresByType video/quicktime "access plus 1 month"
ExpiresByType video/x-msvideo "access plus 1 month"
오디오 파일
ExpiresByType audio/basic "access plus 1 month"
ExpiresByType audio/midi "access plus 1 month"
ExpiresByType audio/mpeg "access plus 1 month"
ExpiresByType audio/x-aiff "access plus 1 month"
ExpiresByType audio/x-mpegurl "access plus 1 month"
ExpiresByType audio/x-pn-realaudio "access plus 1 month"
ExpiresByType audio/x-wav "access plus 1 month"
6. 완전한 설정 예시
프로덕션 환경 권장 설정
<VirtualHost *:80>
DocumentRoot "/home/APM/apache/htdocs"
ServerName example.com
ErrorLog "logs/example.com-error_log"
CustomLog "logs/example.com-access_log" common
# mod_expires 활성화
ExpiresActive On
# 정적 리소스 캐싱 (1년)
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/svg+xml "access plus 1 year"
# CSS/JS 파일 (1개월)
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType application/x-javascript "access plus 1 month"
# 폰트 파일 (1년)
ExpiresByType font/woff "access plus 1 year"
ExpiresByType font/woff2 "access plus 1 year"
ExpiresByType application/font-woff "access plus 1 year"
ExpiresByType application/font-woff2 "access plus 1 year"
# HTML/XML (1시간)
ExpiresByType text/html "access plus 1 hour"
ExpiresByType text/xml "access plus 1 hour"
ExpiresByType application/xml "access plus 1 hour"
# 기본 만료 시간 (1일)
ExpiresDefault "access plus 1 day"
</VirtualHost>
7. Apache 재시작
설정 변경 후 Apache를 재시작하여 적용합니다.
[root@cafe24 ~]# /home/APM/apache/bin/apachectl restart
또는
[root@cafe24 ~]# service httpd restart
8. 설정 확인
curl로 HTTP 헤더 확인
curl -I http://example.com/images/logo.png
응답 예시:
HTTP/1.1 200 OK
Date: Mon, 15 Jan 2025 12:00:00 GMT
Server: Apache/2.2.23
Last-Modified: Mon, 15 Jan 2025 10:00:00 GMT
ETag: "400-20250115100000"
Accept-Ranges: bytes
Content-Length: 1024
Cache-Control: max-age=2592000
Expires: Wed, 14 Feb 2025 12:00:00 GMT
Content-Type: image/png
확인 사항:
Cache-Control: max-age=2592000(30일 = 2,592,000초)Expires: Wed, 14 Feb 2025 12:00:00 GMT(만료 날짜)
브라우저 개발자 도구 확인
- Chrome/Firefox 개발자 도구 열기 (F12)
- Network 탭 선택
- 페이지 새로고침
- 이미지/CSS/JS 파일 선택
- Headers 탭에서
Cache-Control,Expires헤더 확인
9. 캐시 전략 가이드
파일 타입별 권장 캐시 기간
| 파일 타입 | 권장 기간 | 이유 |
|---|---|---|
| 이미지 (jpg, png, gif) | 1년 | 변경 빈도 낮음 |
| CSS/JS | 1개월 ~ 1년 | 버전 관리 필요 |
| 폰트 파일 | 1년 | 거의 변경 없음 |
| HTML | 1시간 ~ 1일 | 자주 업데이트됨 |
| 동적 콘텐츠 | 캐싱 안 함 | 실시간 데이터 |
주의사항
캐시 기간이 너무 길면:
- 파일 업데이트 시 사용자에게 즉시 반영되지 않음
- 해결: 파일명에 버전 번호 추가 (예:
style.v2.css)
캐시 기간이 너무 짧으면:
- 트래픽 절감 효과 감소
- 로딩 속도 개선 효과 미미
10. 문제 해결
Expires 헤더가 나타나지 않는 경우
원인 1: mod_expires 모듈이 로드되지 않음
# httpd.conf 확인
grep "LoadModule expires_module" /home/APM/apache/conf/httpd.conf
원인 2: ExpiresActive On이 설정되지 않음
# httpd-vhosts.conf 확인
<VirtualHost *:80>
ExpiresActive On # 이 라인 확인
...
</VirtualHost>
원인 3: MIME 타입 오류
# 올바른 MIME 타입 사용
ExpiresByType image/jpeg "access plus 1 month" # 올바름
ExpiresByType image/jpg "access plus 1 month" # 잘못됨 (MIME 타입은 jpeg)
Apache 재시작 실패
원인: 설정 파일 문법 오류
해결 방법:
# 설정 파일 문법 검사
/home/APM/apache/bin/apachectl configtest
# 또는
apachectl -t
11. 성능 최적화 팁
mod_headers와 함께 사용
<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 year"
</IfModule>
<IfModule mod_headers.c>
# ETag 제거 (선택사항)
Header unset ETag
FileETag None
# Cache-Control 추가
<FilesMatch "\.(jpg|jpeg|png|gif|css|js)$">
Header set Cache-Control "public, max-age=31536000"
</FilesMatch>
</IfModule>
.htaccess에서 설정 (AllowOverride 필요)
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/gif "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
</IfModule>
12. 호환성
- Apache 1.3.23+
- Apache 2.0+
- Apache 2.2+
- Apache 2.4+
참고 자료
- Apache 공식 문서: https://httpd.apache.org/docs/current/mod/mod_expires.html
- HTTP 캐싱 가이드: RFC 7234 - Hypertext Transfer Protocol (HTTP/1.1): Caching
- MIME 타입 목록: https://www.iana.org/assignments/media-types/media-types.xhtml