CloudFront + Tomcat構成でキャッシュ保持期間を制御するExpiresFilter

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

渡辺です。 本日はCloudFront + Tomcatの小ネタをお送りします。
ちなみに、週末はイベントで東京ですが、20℃超えって本気ですか?

CloudFrontとキャッシュの制御

AWSのCloudFrontは、一言で言えば、CDC(キャッシュサービス)です。 ウェブサーバやアプリケーションサーバの前段にプロキシサーバとして設定しておくことで、クライアントからのアクセスはCloudFront経由となります。 CloudFrontにキャッシュがある場合、後段のウェブサーバなどにアクセスすることなく、クライアントにレスポンスを返します。 大量のアクセスに対し、静的コンテンツ(画像など)を効率良く処理したい場合に有効なソリューションです。

CloudFrontを利用する時に注意したいのは、キャッシュされるオブジェクトのキャッシュ時間です。 アプリケーションの要件にあわせ、ファイルの種別毎に24時間、1ヶ月といったキャッシュ期間を設定します。 このためには、レスポンスのCache-ControlヘッダまたはExpiresヘッダに適切な値を指定します。 詳細は、CloudFrontのキャッシュ時間(TTL)はどの程度なのかを参照してください。

コンテンツを返すオリジンサーバがApacheの場合、これらの設定はmod_expiresやmod_headersを利用するのが定番です。 今回は、オリジンサーバにTomcatを利用している場合の設定方法を紹介します。

CloudFront___Tomcat_CloudFront___Tomcat_-_Cacoo

Expires Filter

Tomcatでは、mod_expiresの代替手段として、Expires Filterを提供しています。 Expires Filterは名前の通り、Servlet Filterであり、各ウェブアプリケーションのweb.xmlで設定を行います。 Expires FilterはTomcat7で導入されているので、それ以前のバージョンのTomcatでは利用できません。

基本設定

通常のServlet Filterと同様にweb.xmlで設定を行います。 すなわち、filterでServlet Filterの設定を行い、filter-mappingでリクエストパスに適用します。
例えば、次の設定では、画像ファイルとCSSファイルにアクセス日時から1時間、JavaScriptファイルにアクセス日時から10分のキャッシュ期間を、全てのパスに対して適用しています。

<filter>
 <filter-name>ExpiresFilter</filter-name>
 <filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
 <init-param>
    <param-name>ExpiresByType image</param-name>
    <param-value>access plus 1 hour</param-value>
 </init-param>
 <init-param>
    <param-name>ExpiresByType text/css</param-name>
    <param-value>access plus 1 hour</param-value>
 </init-param>
 <init-param>
    <param-name>ExpiresByType application/javascript</param-name>
    <param-value>access plus 10 minutes</param-value>
 </init-param>
</filter>
<filter-mapping>
 <filter-name>ExpiresFilter</filter-name>
 <url-pattern>/*</url-pattern>
 <dispatcher>REQUEST</dispatcher>
</filter-mapping>

書式

init-paramで指定するファイルタイプと期間について、文字列ベースのフォーマットで指定します。 なお、スペルミスなどに注意してください。 パースに失敗するとウェブアプリケーションの起動に失敗します。

param-name

param-nameにはファイルタイプについて指定します。 指定できるパターンは3つです。

  • ExpiresDefault
  • ExpiresByType type
  • ExpiresByType type;encoding

param-value

param-valueは、「<base> [plus] {<num> <type>}*」というフォーマットで指定します。 <base>に指定できるのは、3種類ですが、nowとaccessは同じ意味となります。

  • access
  • now
  • modification

plus以下はオプションです。 アクセス日時または修正日時から何日(時間・分)のキャッシュ期間を指定するかを記述します。 plusの後に整数値、最後に単位を指定します。 単位に利用できるのはyear(s), month(s), week(s), day(s), hour(s), minute(s), second(s) です。

CloudFrontを利用しない場合

補足となりますが、CloudFrontを利用しない場合は、静的コンテンツをApacheやnginxなどの前段のウェブサーバで返し、動的コンテンツはTomcatなどのアプリケーションサーバで返すと良いでしょう。 Tomcatなどアプリケーションサーバは静的コンテンツを返すには処理が割高になってしまいます。 CloudFrontを利用する場合ならば、すべてTomcatで処理しても良いかと思います。

Apache___Tomcat_CloudFront___Tomcat_-_Cacoo

※ApacheとTomcatは同一インスタンスに配置しても構いません。