きり丸アドベントカレンダー2020の21記事目です。
弊社の試験環境のシステムには、月跨ぎや年跨ぎのテストを行いやすいように業務日付という概念があります。処理日等の項目を業務日付に合わせて連携しないと、対向システムのバリデーション等にひっかかってしまいます。他にも面倒な点として、月跨ぎや年跨ぎのテストをやりやすいようにするための概念ですので、業務日付は毎日変わります。
ですので、現在のシステムでは業務日付を導き出せるように「現在日付 + X日 = 業務日付」の「X日」をDBに保存しています。
ただし、1回のリクエストで複数回の業務日付をDBから取得する必要があるので、何もしなければ無駄にパフォーマンスが悪くなってしまいます。業務日付は試験のためのロジックで、本番環境は現在日付と同じです。試験のための項目で、本番環境の性能悪化させてしまうのは悪手です。
そういう時に、データをキャッシュすることで高速化が見込めます。
今回の記事ではSpringでキャッシュする仕組みをSpring Cacheで実装します。
ゴール
- Spring Cacheで目的の値をキャッシュにする
- キャッシュをクリアする
できないこと
- キャッシュを更新する
環境
手順
Spring Cacheを依存関係に含める
Spring Cacheを依存関係に含めます。
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-cache'
}
Spring Cacheを有効にする
@SpringBootApplication
を付与しているファイルに対して、@EnableCaching
を付与します。
@SpringBootApplication @EnableCaching public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
業務日付をキャッシュにする
@Cachenable
でキャッシュを登録します。今回はパラメータが無いですが、パラメータがある場合はパラメータがキャッシュのキーになります。初回実行時はキャッシュが無いので、業務日付を導くための「X日」をDBから取得します。2回目以降はキャッシュがあるので、DBからではなくキャッシュから読み込みます。
@CacheEvict
でキャッシュを削除します。業務日付が更新されたタイミングでキャッシュを削除することで、古いキャッシュを読み込ませることはありません。
@Repository @RequiredArgsConstructor public class BusinessDateComponentImpl implements BusinessDateComponent { private final BusinessDateRepository businessDateRepository; @Cacheable("businessDate") @Override public int getBusinessDate() { return businessDateRepository.getBusinessDate(); } @CacheEvict("businessDate") @Override public void deleteCache() { } }
その他にもキャッシュを更新するためのCachePutがあります。
ただし、今回の「業務日付をキャッシュ化する」という目的では、パラメータが無いせいかうまく更新できませんでした。他の記事で参考にしていただけると助かります。
アノテーション | 説明 |
---|---|
Cacheable | キャッシュを登録する |
CacheEvict | キャッシュをクリアする |
CachePut | キャッシュを更新する |
動作確認用
今回の記事とは直接関係がありませんが、キャッシュが効いていることの確認するためのロジックをGitHubのソースに含めています。今回の記事で検証した結果を次に記します。
// 業務日付の確認 curl -X GET http://localhost:8080/v1/businessDate/ -u admin:pass // 業務日付のキャッシュ削除 curl -X GET http://localhost:8080/v1/businessDate/clear -u admin:pass
結果:
curl -X GET http://localhost:8080/v1/businessDate/ -u admin:pass 3000 # DBの値 # DBを更新して300にする curl -X GET http://localhost:8080/v1/businessDate/ -u admin:pass 3000 # キャッシュの値 # 業務日付のキャッシュ削除 curl -X GET http://localhost:8080/v1/businessDate/clear -u admin:pass curl -X GET http://localhost:8080/v1/businessDate/ -u admin:pass 300
ソースコード
アドベントカレンダー21日目。
github.com
終わりに
正直なところ、キャッシュは最終手段だととらえているのであまり使いたくはありません。万が一にでもキャッシュが更新されていないと古いデータを参照してしまいますからね…。
フロントエンドではキャッシュのデータを参照しているせいでABテストができない、障害が発生した等の苦労話もありますし。
致命的な性能悪化が起きた、または最悪古いデータを参照してもあまり影響が出ない今回のような要件でのみ、Spring Cacheを活かして活用したいです。
この記事がお役に立ちましたら、各種SNSでのシェアや、今後も情報発信しますのでフォローよろしくお願いします。
参考記事
敬称略
4.2. キャッシュの抽象化(Cache Abstraction macchinetta.github.io
公式リファレンス:キャッシュ spring.pleiades.io
類似記事
きり丸アドベントカレンダー2020 adventar.org
きり丸のHerokuページ
https://kirimaru-todoapp.herokuapp.com/
22日目のアドベントカレンダーの記事 https://nainaistar.hatenablog.com/entry/2020/12/22/083000nainaistar.hatenablog.com