しばやん雑記

ASP.NET Core とメイドさんが大好きなフリーランスのプログラマーのブログ

そろそろ Azure Cloud Services の移行先についてひとこと言っておくか

最近はまあまあ Cloud Services (Web Role / Worker Role) からの移行という話を聞くようになってきましたが、大体のケースで Service Fabric への移行を勧められているようです。

正直言ってこの提案は全くの見当外れであるケースが大半でしょう。何故なら現状 Cloud Services を使っているアプリケーションは、そもそもマイクロサービスに適した形になっていないことが多いからです。従って移行先としては最初に App Service が検討されるべきです。

1 VM に 1 アプリケーションという構造でマイクロサービスとか、難易度が高すぎるので当たり前です。提案した人は Cloud Services と Service Fabric の違いを全く理解してないのではないかと思ってしまいます。

既存サービスの Cloud Services からの移行を検討している理由としては、開発やデプロイの負荷を下げることや高速で柔軟なスケーリング、後は VNET 統合やモニタリング改善などいろいろあると思いますが、Service Fabric は最初に検討すべきサービスではありません。

Cloud Services を使う上での課題

Cloud Services はある種のプリミティブな PaaS として、非常にシンプルかつスケーリングを考慮したアーキテクチャになっています。Azure の各種基盤的な部分で使われていて、オーケストレーターやコンテナとかいう話なんて全く無かった頃のサービスです。

PaaS としての思想は非常に良かったのですが、一方で Cloud Services 向けにアプリケーションを開発する場合は専用のライブラリを参照する必要がありました。アプリケーション設定の取得すら ASP.NET の標準仕様に乗っかっていなかったり、やたらと複雑なマニフェストや専用のパッケージを作ったりと、アプリケーションのポータビリティが失われていました。*1

無制限にスケーリングは可能でしたが VM の起動コストという問題も抱えています。しかし、それらの問題は App Service を採用することで、標準機能だけでほぼ解消可能です。

Service Fabric が向いていない理由

それに比べて Service Fabric を採用するということは、既存のアプリケーションにかなりの複雑さを持ち込むという結果になるでしょう。Docker を使ったマイクロサービスを既に開発している場合は、現在では AKS などの Managed Kubernetes がデファクトスタンダードとなっていますし、Service Fabric で Docker を使うと Reliable Services / Reliable Actors が使えなくなります。

単なるオーケストレーターとして Service Fabric を使うのは、あまりにもメリットが少ないです。そもそも IIS が必要な ASP.NET Web Forms / MVC は Docker しか選択肢がないです。

Docker しか選択肢が無いということは、Windows Containers を使う必要があるということなので、Web App for Containers (Windows) と同じような課題を持つことになります。*2

普通にクラスタを本番向けに作ると、最低でも 5 インスタンスが必要なのは変わりませんし、スケーリングの際は結局 VM を新しく作成するので Cloud Services とほぼ変わらないでしょう。

Service Fabric 自体が悪いというわけではなく、単純に Cloud Services からの移行先として不適切というだけです。Azure の SQL Database や Cosmos DB などのサービス基盤として Service Fabric は使われていますし、最近は Azure Functions の Linux 向け Consumption Plan が Service Fabric Mesh 上に実装されました。

今後は App Service の基盤が Cloud Services から Service Fabric Mesh などに変わって、特に意識することなく Service Fabric を使うようになる未来になるかもしれません。そういう形で良いです。

Web Role / Worker Role の移行に必要なこと

Web Role は単純な ASP.NET アプリケーションに改善すれば良いですが、Worker Role は仕組み上無限ループで処理する形だったので、まずは処理を整理してイベントドリブンに書き換えた方が良いでしょう。なので検討する移行先は Azure Functions となります。

Worker Role でよくある処理は Storage Queue からメッセージを無限ループで取得することだと思いますが、Azure Functions では QueueTrigger を使えば終わりますし、Consumption Plan を使えば Queue の長さによって自動でスケーリングしてくれます。

複雑な処理の場合は Durable Functions を使えば、Worker Role と Storage Queue を組み合わせて作っていたような処理も、処理が分かりやすい形かつスケーラブルに実装できるはずです。

現在の App Service で実現できない処理としては GDI / GDI+ を使った画像周りです。App Service の Sandbox によって API がブロックされるので、API を使っていると失敗します。

それ以外にも細かい制約はありますが、Web アプリケーションの実行環境としては影響は小さいです。

現在 Public Preview 中の Web App for Containers (Windows) を使うと GDI / GDI+ などの制約なしに扱えるようになるので、必要な部分だけ適用するなどアーキテクチャを少し変えるだけで、Cloud Services から App Service への移行が行えるかと思います。

実際に Cloud Services からの移行で Service Fabric を勧められていて困っている場合などは、お気軽にご相談ください。App Service への移行のお手伝いとかできます。

*1:ありていに言うとベンダーロックインだった

*2:Server Core / Nano Server ベースイメージのキャッシュや更新など