はじめに
Microsoft Azure Tech Advent Calendar 2022 の 4 日目の記事です。本稿では、App Service で Tomcat アプリケーションをデプロイする際に陥りやすい注意点を紹介します。
概要
App Service における Tomcat アプリケーションのデプロイ方法については、公式ドキュメントのWAR、JAR、EAR パッケージをデプロイする にて解説されています。こちらのドキュメントにて言及されているとおり、サポートされている手段はAzure CLI、PowerShell、Kudu publish API となっており、FTP や WebDeploy によりデプロイされたアプリケーションの動作は保証されておりません。また、Kudu サイトの UI から手動でデプロイ資産を配置してデプロイすることもサポートされておりません。 サポートされていない方法でデプロイを実施した場合、稀に 404 エラーが発生するという事象が発生するとともに、その他にも想定外のエラーが発生する可能性があります。
サポート対象のデプロイ方法が限られている理由
前提
前提として App Service のアーキテクチャについて解説します。まず、App Service では可用性を向上させるために複数のインスタンスを用いてアプリケーションを運用することができますが、ホームディレクトリ(Windows: C or D\home\、Linux: /home)配下のディスク領域は、各インスタンス間で共有されるストレージがマウントされています。共有ストレージに関しては公開ドキュメントの複数のインスタンス間でのファイル アクセスでも解説されております。
サポート外のデプロイ方法によって発生し得る事象
以上のアーキテクチャを受けて本題に入りますと、サポートされていない方法でファイルを共有ストレージ上に配置した場合で App Service が再起動した場合は、各インスタンスの Tomcat が起動する際に稀に同時に同じ Java 資産(class ファイル等)にアクセスしてしまう問題が発生します。こちらの事象が何故問題になるかというと、一方のインスタンス上にある Tomcat が特定のファイルを処理している最中にファイルロックを掛けることで他のインスタンスが同一のファイルにアクセスした際にファイルをオープンできず、404 エラーが発生してしまいます。
正しいデプロイ方法の場合は Java の資産が D:\DWASFiles\Sites<App Service のリソース名>\Temp\tomcatFiles\XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\site\wwwroot のような、インスタンスのホームディレクトリ外のローカル領域に展開されます。このように Java の資産が展開される詳細な動作については App Service における Tomcat アプリケーションへの war ファイルのデプロイについて の記事でも解説されております。
最後に
App Service にて Java アプリケーションを Tomcat にて複数インスタンスで運用しており、App Service の再起動時に 404 エラーが発生している場合は、デプロイ方法がサポートされている方法なっているかを確認しましょう。Tomcat の catalina ログに FileNotFoundException が記録されているような場合は、今回解説したようなファイルロックの問題が発生している可能性が考えられます。(ロック中のファイルにアクセスした場合、FileNotFoundException が発生し得ます。)そのため、原因の調査にあたっては catalina ログも同時に確認すると原因の切り分けに繋がるでしょう。