1. 개요

2.2 버전 기준으로 http://httpd.apache.org/docs/2.2/mod/mod_expires.html 문서를 읽어봅니다.


2. 설정

관련 모듈은 다음과 같습니다. httpd.conf 에 포함되어 있는지 확인합니다.

LoadModule expires_module modules/mod_expires.so

웹 서버 구성 방법에 따라 적당한 위치에 설정을 삽입합니다. 아래는 별도로 가상 호스트 설정을 사용하는 사이트에 적용한 예입니다.

ExpiresActive On

ExpiresByType image/gif "access plus 9 hours"
ExpiresByType image/jpeg "access plus 9 hours"
ExpiresByType image/png "access plus 9 hours"

Type은 mime.types 에 설정되어 있는 타입을 의미합니다. 예를 들어 css 파일은 test/css, js 파일은 application/javascript입니다.

access plus 이후의 시간은 다음과 같은 단위로 정의할 수 있습니다.

  • years
  • months
  • weeks
  • days
  • hours
  • minutes
  • seconds

3. 확인

이제 HTTP Response 헤더 값 내에 Expire가 추가되었는지 확인합니다.

3-1. 아무런 설정을 하지 않았을 때

HTTP/1.1 200 OK
Date: Fri, 20 Mar 2015 01:22:15 GMT
Server: Apache
Last-Modified: Mon, 16 Mar 2015 09:24:38 GMT
ETag: "260837-19d44-511646b4cea3f"
Accept-Ranges: bytes
Content-Length: 105796
Content-Type: text/css

 3-2. css 파일을 1주로 설정하였을 때

HTTP/1.1 200 OK
Date: Fri, 20 Mar 2015 01:27:25 GMT
Server: Apache
Last-Modified: Mon, 16 Mar 2015 09:24:38 GMT
ETag: "260837-19d44-511646b4cea3f"
Accept-Ranges: bytes
Content-Length: 105796
Cache-Control: max-age=604800
Expires: Fri, 27 Mar 2015 01:27:25 GMT
Content-Type: text/css

 3-3. js 파일을 하루로 설정하였을 때

HTTP/1.1 200 OK
Date: Fri, 20 Mar 2015 01:27:08 GMT
Server: Apache
Last-Modified: Tue, 17 Mar 2015 00:50:11 GMT
ETag: "262259-20c1-511715959cbac"
Accept-Ranges: bytes
Content-Length: 8385
Cache-Control: max-age=86400
Expires: Sat, 21 Mar 2015 01:27:08 GMT
Content-Type: application/java-script

4. 브라우저 캐시

  • 사용자가 Static Contents를 요청하면 웹 서버는 Last-Modified 속성에 Contents 변경 일자를 담아 응답한다.
  • 사용자가 동일 Contents에 대해 요청할 때는 If-Modified-SInce 속성에 브라우저 캐시에 저장된 Contents 변경 일자를 담아 요청한다.
    웹 서버에게 이 Contents를 캐시에 가지고 있으며 변경 일자는 언제라고 알려주는 것이다.
  • 웹 서버는 사용자가 보낸 변경 일자와 Contents의 변경 일자를 비교하고, 만약 동일 Contents라면 계속 쓰라고 304로 응답한다.
    하지만 변경 일자가 다르다면 200으로 응답하고 Contents와 함께 새로운 Last-Modified 속성을 전달한다.

5. Etag

5-1. 매커니즘

  • HTTP/1.1에서 추가된 기능 (옵션사항으로 Etag를 사용하지 않으면 기존 방식) 
  • Etag는 특정 버전의 리소스를 식별하는 식별자로 지문과 같은 역할을 한다.
  • 웹 서버는 요청 응답 시 Etag 값을 생성하여 헤더의 Etag 속성에 담아 보낸다. 
  • 사용자가 동일 Contents에 대해 요청할 때는 If-None-Match 속성에 Etag 값을 담아 요청한다.
  • 웹 서버는 사용자가 보낸 Etag와 Contents의 Etag를 비교하고, 만약 동일 Etag라면 계속 쓰라고 304로 응답한다.

5-2.  Apache HTTP Server Etag (2.2 기준)

아파치 웹 서버 2.2는 FileETag 속성을 통해 Etag 값을 설정한다. 기본 값은 FileETag INode MTime Size 이다. (이 기본 값은 All과 같음)

  • INode : The file's i-node number will be included in the calculation
  • MTime : The date and time the file was last modified will be included
  • Size : The number of bytes in the file will be included
  • All : All available fields will be used. This is equivalent to: FileETag INode MTime Size

주의할 점이 있는데, RR 방식의 L4를 사용하고, 뒷단의 웹 서버가 Static Contents를 보관하는 파일 시스템을 각각 가지고 있다면, 동일 Contents라고 inode 값이 상이할 수 있다. 이러면 계속 캐시가 되지 않고 200으로 처리된다.

이때는 설정에서 INode를 제거하여 문제를 해결한다.

5-3. Apache HTTP Server 2.4

Apache HTTP Server 2.4 버전의 경우 2.2 버전과 달리 기본(default) 값에 inode가 포함되어 있지 않다. (기본 값과 All 값이 다름)


6. Resource 관리 방안

애플리케이션 변경 시에 캐시된 기존 리소스를 계속 읽을 수 있으므로 새로운 리소스를 내려받을 수 있도록 리소스 파일명에 버전 혹은 지문을 포함하는 것이 좋다.

예: style.abcde.css