afnf.net

Spring Boot 1.2.5ではcache bustingを使わない方が良い

Spring Boot 2015/09/06 22:44

現象

Spring Boot 1.2.5のcache bustingを有効にすると、html生成のパフォーマンスがかなり劣化します。

具体的には以下の環境です。

  • Spring Boot 1.2.5(Spring Framework 4.1.7)
  • ResourceUrlEncodingFilterを使用する場合
  • FixedVersionStrategyで確認、ContentVersionStrategyでも起きるはず
  • viewはThymeleafで確認、Velocityでも起きるはず
  • executable JARだとより顕著に劣化する

再現方法

小さめのコードをGitHubに挙げました。

https://github.com/af-not-found/SpringUrlEncPrefIssue

Thymeleafで5000個のリンクを生成しています。jvisualvmによるプロファイル結果を以下に掲載します。

executable JARでないオリジナル実装

20150906_slow-direct

赤枠の約1000msが劣化分です。

executable JARのオリジナル実装

20150906_slow-jar

executable JARの場合、6秒以上も余計にかかっています。めっちゃ遅い。

原因

プロファイル結果の通り、リンク毎に以下の処理が実行されるためです。

  1. ResourceUrlEncodingFilter$ResourceUrlEncodingResponseWrapper.encodeURL
  2. ResourceUrlProvider.getForLookupPath
  3. DefaultResourceResolverChain.resolveUrlPath

対処

Spring Boot 1.3.0 M5(Spring Framework 4.2.0)では再現しませんでした。色々調べたんですが、何がきっかけで修正されたのかは分かりませんでした。


2015/11/18 追記

Spring Boot 1.3.0 の正式版で、パフォーマンスの劣化が再現しました。状況確認中です。


1.3がリリースされるまでは、GitHubにあげたCachingResourceUrlEncodingFilterのように、フィルタリングとキャッシュの仕組みを導入して対処する方法があります。

WebConfig.javaでは、javaコマンドラインに -Dfast=true を追加するとCachingResourceUrlEncodingFilterが有効になるよう実装しました。

// my implementation
String fast = System.getProperty("fast");
if (fast != null && fast.equals("true")) {
  logger.info("using CachingResourceUrlEncodingFilter");
  return new CachingResourceUrlEncodingFilter("/static/");
}
// original implementation
else {
  logger.info("using ResourceUrlEncodingFilter");
  return new ResourceUrlEncodingFilter();
}

コンストラクタにresolve対象URLのprefixを設定しています。

20150906_fast-direct

はい。改善されました。

Spring Boot 2015/09/06 22:44
comments (0)

blog-java2 engine (build:2017-08-10 17:37 JST)