BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ アーティクル サーバレスファンクションはマイクロサービスのためですか? おそらくそうですが柔軟に変更できるようしてください

サーバレスファンクションはマイクロサービスのためですか? おそらくそうですが柔軟に変更できるようしてください

キーポイント

  • Serverless Functions can be a great deployment model for (Micro)services since they offer the fastest path to production, the lowest entry cost, and high elasticity.
  • When speed to reach production with a new service is important, when we want to minimise upfront investments, when load curves are unknown, Serverless Functions are the deployment model to choose.
  • But things can change over time, loads can become predictable and stable, and if this happens then Serverless Functions can turn out to be much more expensive than traditional deployment models based on dedicated resources.
  • It is therefore important to design our applications so that switching deployment models is as cheap as possible and this can be achieved by enforcing strict separation between what is dependent on the actual target platform from what is common and independent.
  • If we enforce such separation, not only in the application code but also in the DevSecOps part, we can keep the required flexibility and we can improve the overall efficiency of the development cycle.
     

原文(投稿日:2021/03/05)へのリンク

 

新しい (マイクロ) サービスベースのアーキテクチャを設計および計画している時、アーキテクトがデプロイメント戦略について考え、そのため自問しなければならない瞬間があります。「この (マイクロ) サービスをサーバレスファンクションとしてデプロイするのか、それともコンテナに配置する方がよいのか? それとも、専用の仮想マシン (VM) にするのがよいのか?」

このようなことは最近ではよくあることですが、答えは「それは時と場合による」という1つだけです。しかし「それは時と場合による」だけでなく、「それはまた変えることもできる」ということです。今日の最適なソリューションは、数か月後にはまったく適さないものになる可能性があります。新しいアプリのリリース時には、サーバレスファンクションを選択すると便利な場合があります。それらはセットアップが速く、先行投資がほとんど必要ないためです。

さらに、アプリが維持しなければならない負荷について確信がない場合には「従量制」モデルは非常に魅力的です。後で、サービスが成熟し、負荷が予測可能になったときに、コンテナや専用サーバに基づいたより伝統的なデプロイメントトポロジに移行すると便利な場合があります。

したがって、クラウド時代の新しいシステムを設計するときは、さまざまな (マイクロ) サービスのデプロイメント戦略を最小限のコストで自由に変更できるようにすることが重要です。適切なインフラストラクチャを適切なタイミングで利用することで、クラウド請求額を大幅に節約できます。

サーバレスファンクション

サーバレスファンクション (FaaSとも呼ばれる function as a service) は、HTTPリクエストやKafkaトピックで受信したメッセージなどの構成されたイベントに応答してインスタンス化および実行されるロジックの単位です。実行が完了すると、そのようなファンクションは (少なくとも論理的には) 消え、コストはゼロになります。

HTTPイベントへのFaaSの応答: 並列処理と従量制モデル

すべての主要なパブリッククラウドにはFaaSの提供 (AWS LambdaAzure FunctionsGoogle FunctionsOracle Cloud Functions) があり、Apache OpenWhiskなどのフレームワークを使用してオンプレミスでFaaSを利用することもできます。リソースに関してはいくつかの制限があります (たとえば、AWSでは、最大10GBのメモリと15分の実行時間)、しかし、最新のアプリケーションの多くのユースケースをサポートできます。

サーバレスファンクションの粒度はさまざまです。注文が確認されたときにSMSメッセージを生成するなど、単一の責務に焦点を非常に絞ったものから、コンテナに実装されたり、仮想マシンで実行する他のマイクロサービスと共存できる完全なマイクロサービスまでです (Sam Newman氏はFaaSとマイクロサービスの関係についての興味深い講演で詳しく述べています)。

異なるデプロイメントモデルで実装されたマイクロサービスによって提供されるフロントエンドアプリケーション

FaaSの利点

サーバーレスファンクションがアイドル状態であれば費用はかかりません (「従量制」モデル)。サーバーレスファンクションが同時に10のクライアントによって呼び出された場合、その10のインスタンスがほぼ即座にスピンアップされます (少なくともほとんどの場合)。インフラストラクチャ全体の提供、管理、高可用性 (少なくとも特定のレベルまで)、およびスケーリング (0からクライアントによって定義された制限まで) は、舞台裏で働くスペシャリストのチームによってすぐに使える状態で提供されます。

サーバーレスファンクションは強化された弾力性を提供し、ビジネスの差別化要因に集中できるようにします。

したがって、FaaSは2つの大きな利点を意味します

  • 強化された弾力性: 必要に応じたスケールアップおよびダウンと支払いは使用した分だけです。
  • ビジネスの差別化要因に集中: 最も重要なアプリケーションの開発に力を集中できるように、最新のインフラストラクチャなどの複雑な分野に貴重なエネルギーを分散させることがないように、商品としてFaaSを提供しています。

弾力性とコスト

「優れたサービス」とは、とりわけ、一貫した優れた応答時間を意味します。ここで重要なのは一貫性です。アプリケーションが通常の負荷の下にあるときとピーク時のときに優れている必要があります。

「新サービス」は、市場に迅速に投入する必要があり、それは先行投資を最小限に抑える必要があり、また開始時から「優れたサービス」である必要があります。

新しいサービスを開始したいとき、FaaSモデルはおそらく最良の選択です。サーバーレスファンクションは迅速にセットアップでき、インフラストラクチャの作業を最小限に抑えることができます。「従量制」モデルは、先行投資がないことを意味します。スケーリング機能は、さまざまな負荷条件下で優れた一貫した応答時間を提供します。

しばらくして、負荷がより安定して予測可能になると、ストーリーが変わる可能性があり、KubernetesクラスタでもVMでも専用リソースに基づく従来のモデルがFaaSよりも都合がよくなる可能性があります。

負荷プロファイルが異なると、FaaSと専用リソースに基づくソリューションを比較して、クラウドの請求額に劇的な変動が生じる可能性があります。

しかし、コストの違いはどのくらい大きくなる可能性があるのでしょうか? いつものように、特定のシナリオに依存しますが、確かなことは、間違った選択がクラウドの請求に大きな影響を与える可能性があるということです。

サーバレスファンクションは大きなお金を節約できますが、大きなお金を費やすこともまたできます

クラウドのコストを見積もること自体が科学になりつつありますが、執筆時点のAWSの価格表を使用すると、あるモデルが他のモデルよりも優れている可能性を感じることができます。

サンプルアプリケーション。 1か月あたり3,000,000件のリクエストを受信するアプリケーションについて考えてみましょう。各リクエストは、4GBのメモリを搭載したLambdaによって処理されるのに500ミリ秒かかります (CPUはメモリに基づいて自動的に割り当てられます)。

FaaSは「従量制」モデルのため、負荷曲線 (ピーク、フラットのどちらでも) に関係なく、1か月あたりのコストは100.60USドルに固定されます。

一方、専用VMに基づくモデルを検討する場合、状況は異なり、コストは負荷曲線の形状に大きく依存します。

負荷にピークがあるシナリオ。負荷がピークによって特徴付けられ、クライアントに一貫して優れた応答時間を保証したい場合は、ピークを維持するためにインフラストラクチャのサイズを決定する必要があります。ピーク時に1秒あたり10の同時リクエストがある場合 (3,000,000リクエストが1日の特定の時間帯または月末などの特定の日に集中している場合は可能性が高い)、VM (AWS EC2) には8CPUと32GBのメモリを搭載することでLambdaと同じパフォーマンスを提供します。この場合、月額費用は197.22USドルに跳ね上がります (複数年のコミットメントで節約を得ることができますが、これにより財務上の柔軟性は低下します)。コストは基本的に2倍になりました。この違いは、負荷に応じてEC2インスタンスのオンとオフを動的に切り替えることで軽減できますが、これには負荷が予測可能である必要があり、ソリューションの複雑さとコストが増加します。

負荷がフラットなシナリオ。負荷が基本的にフラットである場合には、別の領域になります。ピークがない場合は、はるかに小さなマシンで簡単に負荷を維持できます。おそらく、2CPUと8MBのメモリを備えたVMで十分であり、この場合の月額費用は31.73USドルで、Lambdaの費用の3分の1未満です。

現実的なビジネスケースははるかに複雑で、徹底的な分析が必要ですが、これらの単純化されたシナリオを見ると、FaaSモデルが非常に魅力的な場合もありますが、制約が変更されると実際の負担になる可能性があることが明らかです。したがって、それに応じたデプロイメントモデルに変更する柔軟性を持つことが重要です。

問題は: どうすればそのような柔軟性を実現できるのでしょうか? そうするのはどのくらい難しいのでしょうか?

最新アプリケーションのコードベースの構造

最新の開発手法を使用するとき、アプリケーションのコードベースは通常、論理領域に分割されます。

  • アプリケーションロジック。アプリケーションが実行する必要があることを実装する (通常はJava、TypeScript、Goなどの言語で記述される) コード
  • DevSecOps (CI/CD)。通常、アプリケーションのビルド、テスト、セキュリティチェック、およびデプロイメントを自動化するスクリプトと構成ファイル

アプリケーションロジック

バックエンドサービスのアプリケーションロジックを論理的なパーツにさらに分割できます

  • ビジネスロジック。サービスの動作を実装するコードです。ロジックAPI (メソッドまたは関数) の形式で表現されます。通常、JSONなどの入力としてデータを期待し、出力としてデータを返します。このコードは、リンクされている、いかなる技術的なメカニズムにも依存しません。実行される実際の環境のリンクは、コンテナ、サーバレスファンクション、またはアプリケーションサーバです。コンテナの場合、これらのロジックAPIは、Spring Boot (Java言語の場合)、Express (Nodeの場合)、Gorilla (Goの場合) などによって呼び出すことができます。サーバレスファンクションで呼び出されるときは、特定のクラウドプロバイダによって実装された特定のFaaSメカニズムが使用されます。
  • デプロイメントに関連したコード。実行環境のメカニズムを扱うコードです。複数のデプロイメントモデルをサポートする必要がある場合は、この部分の実装が異なることになります (ただし、この部分のみ)。コンテナベースのデプロイの場合、これはSpring Boot、Express、Gorillaなどへの依存関係が集中している部分になります。FaaSの場合、この部分には、特定のクラウドプロバイダ (ビジネスロジックを呼び出すための独自のライブラリを持つAWS Lambda、Azure Functions、またはGoogle Cloud Functions) によって定義されたメカニズムを実装するコードが含まれます。

共通のビジネスロジックから異なるデプロイメントモデル間の切り替えをサポートするためデプロイメント関連コードを分離

最小限のコストでデプロイメント戦略に柔軟性を与えるには、これら2つの部分を明確に分離しておくことが重要です。つまり、次のことを意味します:

  • 「デプロイメント関連コード」を「ビジネスロジック」からモジュールをインポートします
  • 「ビジネスロジック」は、特定のランタイムに依存するモジュール/パッケージをインポートしません。

これらの2つの単純なルールに従うことで、すべてのデプロイメントモデル間で共有される (ビジネスロジック) コードの量を最大化し、したがって、あるモデルから別のモデルに移動するコストを最小化します。

「ビジネスロジック」と「デプロイメント関連コード」の部分の相対的なサイズを抽象的に見積もることは不可能です。AWS LambdaとGoogle Application Engineの両方にデプロイ可能なあるシンプルなインタラクティブゲームで分析すると、「デプロイ関連コード」はコードベースの6%(合計約7,200行のコード)であることがわかりました。したがって、このサービスがLambdaで実行されているかコンテナで実行されているかに関係なく、コードベースの94%は同じです。

DevSecOps (CI/CD)

これは、アプリケーションのビルド、テスト (セキュリティゲートウェイを含む)、およびデプロイメントの自動化に責務を持つコードベースの一部です。

ビルドフェーズとデプロイフェーズは、その性質上、サービスの実行で選択された実際のランタイム環境に大きく依存します。コンテナを選択した場合、ビルドフェーズではDockerツールのようなものを使用するでしょう。FaaSプロバイダを選択した場合は、そのようなビルドフェーズはありませんが、コードをFaaSエンジンにダウンロードし、サーバレスファンクションが呼び出されるときに呼び出すにエントリポイントで指示するコマンドがあります。同様に、FaaSモデルにも固有のセキュリティチェックが存在する場合があります。

同時に、「ビジネスロジック」と「デプロイメント関連コード」をきちんと分離することで、テストに関して大きなメリットを得ることができます。「ビジネスロジック」と「デプロイメント関連コード」が分離している場合、単体 (ユニット)、そして最も重要なこととして、統合テスト (インテグレーションテスト) は最終的なデプロイメントモデルから独立して実行でき、最も単純な構成を選択して、それに対してテストスイートを実行できます。テストは開発者のワークステーションで実行することもでき、テストフィードバックの速度が大幅に向上します。

実際のデプロイメントが完了した後もいくつかのテスト手順を実行する必要がありますが、「ビジネスロジック」の正確さのテストであるテスト作業の大部分は、実際のデプロイメントから独立して実行でき、開発者の生産性を大幅に向上させます。

デプロイメントモデルに依存しないものを分離し、それを最大化するように努める

デプロイメントモデルの選択に柔軟性を持たせたい場合は、「デプロイメント関連コード」に関連するものと独立したものとの間に明確な境界を維持する必要があります。これは、前者を最小化し、後者を最大化するようにソリューションを事前に設計し、プロジェクト/プロダクトの存続期間中に、おそらく定期的な設計とコードレビューを使用して、これらのさまざまな部分の強力な分割を実施することを意味します。

最新のアプリケーションコードベースの部分間の関心事の分割

結論

サーバレスファンクションは、最新のアーキテクチャにおける優れたオプションです。それらは、市場投入までの時間の短縮、参入コストの最小化、および最高の弾力性を提供します。これらの理由から、新しいプロダクトを出荷する必要があるとき、または非常に変動する負荷に直面する必要があるときには、最良の選択です。

しかし、物事は時間とともに変化する可能性があります。負荷がより安定して予測可能になる可能性があり、そのような状況では、FaaSモデルは専用リソースに基づく従来のモデルよりもはるかに高価になる可能性があります。

したがって、アプリケーションのデプロイメントモデルを可能な限り低いコストで変更できる柔軟性を維持することが重要です。これは、実行するプラットフォームに依存しないアプリケーションロジックのコアと、選択した特定のデプロイメントモデルに依存するものを明確に分離することで実現できます。

最初からいくつかの簡単なアーキテクチャガイドラインに従い、定期的なピアレビュープロセスを組み込むことで、この柔軟性を維持できます。

著者について

Enrico Piccinin氏は、コードとIT組織で時々発生するいくつかの奇妙なことに情熱を持っている人です。IT開発の分野で長年の経験を持つ彼は「新しいIT」を従来の組織に適用するとどうなるかを知りたいと考えています。氏は、enricopiccinin.comまたはLinkedInで見つけることができます。ここでの見解や考えは私自身のものです。

 

この記事に星をつける

おすすめ度
スタイル

BT