GoogleCloudを使用したサーバーレスNode.js関数の実装

公開: 2022-03-11

ソフトウェアの作成は、優れたコードを書くことだけでは終わりません。 ソフトウェアが展開され、要求を適切に処理できるようになり、パフォーマンスと実行コストを損なうことなく拡張できるようになると、完了します。

あなたはおそらく、これらすべてのことを処理するためのクラウドコンピューティングをどのように持っているかについて考えているでしょう。 「では、この新しいサーバーレスのものは何ですか、Vignes?」

GoogleCloudを使用したサーバーレスNode.js関数

サーバーレスコンピューティングは、ハードウェアとソフトウェアのセットアップ、セキュリティ、パフォーマンス、およびCPUアイドル時間のコストについて心配する必要がないクラウドプラットフォームでコードが実行されるアーキテクチャスタイルです。 これは、ソフトウェア環境を抽象化するインフラストラクチャを超えたクラウドコンピューティングの進歩です。 これは、コードを実行するために構成が必要ないことを意味します。

サーバーレスを使用すると、次の作業スタイルになります。

  1. コードを開発します。

  2. コードをサービスプロバイダーにアップロードします。

  3. トリガー(この場合はHTTPリクエスト)を構成します。

私たちの仕事は終わりました! これで、プラットフォームプロバイダーが着信要求とスケーリングを処理します。

サーバーレスマイクロサービスの概要

サーバーレスアーキテクチャは、多くの場合、マイクロサービススタイルの設計と組み合わされています。 マイクロサービスは、1つの特定のモジュールのリクエストを処理する大きなソフトウェアのスタンドアロン部分です。 サーバーレス環境で実行できるマイクロサービスを作成することで、コードの保守と展開の高速化が容易になります。

AWS LambdaとGCFの概要、比較

サーバーレス機能は、「サービスとしてのバックエンド」または「サービスとしての機能」と呼ばれることがよくあります。 サーバーレスコンピューティングプロバイダーの数は増え始めています。 ただし、AmazonWebServicesのAWSLambdaFunctionsやGoogleCloudのGoogleCloudFunctions (GCF)など、従来の大手企業の一部はサーバーレスオプションも提供しています。後者は現在ベータ版ですが、私が使用しているものです。 それらは同じように機能しますが、それらの間にはいくつかの重要な違いがあります。

AWS Lambda Google CloudFunctions
言語サポートNode.js、Python、C#、Java Node.js
トリガーDynamoDB、Kinesis、S3、SNS、APIゲートウェイ(HTTP)、CloudFront、その他HTTP、Cloud PubSub、クラウドストレージバケット
最大実行時間300秒540秒

この記事では、GCFを使用してサーバーレスコードのデプロイを実装するプロセスについて説明します。 Google Cloud Functionsは、軽量のイベントベースの非同期コンピューティングソリューションであり、サーバーやランタイム環境を管理しなくても、クラウドイベントに応答する小さな単一目的の関数を作成できます。

GCFには、トリガーに基づいて分離された3つの可能な実装があります。

  1. HTTPトリガーHTTPリクエストをクラウド機能にルーティングします

  2. 内部のGooglepub/ subトリガーは、クラウド機能へのパブリッシュおよびサブスクリプションリクエストをルーティングします

  3. クラウドストレージバケットトリガーストレージバケットに加えられた変更をクラウド機能にルーティングします

GoogleCloudFunctionsを使用してHTTPトリガーベースのセットアップを作成しましょう

Google Cloud Functionsには、特別なセットアップやインストールは必要ありません。 GCFは、デフォルトのノード環境がセットアップされ、実行できる状態になっていることを確認します。 HTTPをトリガーとしてクラウド関数を作成すると、関数をトリガーするためのURLが提供されます。 APIゲートウェイを媒体として使用して通信するprojectIDと比較すると、GoogleCloudFunctionsはprojectIDとリージョンに基づいてURLをすぐに提供します。

GoogleCloudPlatformの図-クラウド機能とAWSLambda

サーバーレスNode.jsアプリケーションの作成

コードをGCFで実行可能にするには、コードを1つの関数内にラップする必要があります。 GCFは、トリガーが発生するたびにその特定の関数を呼び出します。 これを行うための可能な方法は、アップロードです。

  1. 単一ファイル:要求に基づいて他の関数を呼び出すデフォルトの関数をエクスポートします。

  2. 複数のファイル:他のすべてのファイルを必要とし、デフォルトの関数を開始点としてエクスポートするindex.jsファイルを用意します。

  3. 複数のファイル: "main": "main.js"を開始点として使用して、 package.jsonで1つのメインファイルを構成します。

上記の方法のいずれかが機能します。

GCFでは、特定のノードランタイムバージョンがサポートされています。 その特定のバージョンをサポートするようにコードが記述されていることを確認してください。 この投稿を作成する時点で、GCFはノードバージョンv6.11.1をサポートしています。

関数を作成するには、考慮すべきオプションがいくつかあります。

  1. メモリこれは、1回の実行時に要求を処理するために必要なメモリの量を示します。 MBで定義されます。 小さなアプリケーションの場合、128MBで十分ですが、最大2GBまで増やすことができます。

  2. タイムアウトタイムアウトは、その名前が示すように、予想されるコード実行タイムアウトを定義します。 この後、コードは強制終了されて停止します。 この時点以降の実行は突然停止します。 最大タイムアウトは540秒です。

  3. 実行する関数メインハンドラーファイルから複数の関数をエクスポートできますが、要求を処理するためにトリガーする必要がある1つの関数を構成する必要があります。 これにより、開発者はHTTPメソッド/URLに基​​づいて複数のエントリポイントを持つことができます。

コードをアップロードするには、コードをコピーして貼り付け、関数ポータルを作成します。 複数のファイルの場合は、コンテンツを圧縮してファイルをアップロードします。 ZIPファイルの場合は、 index.jsファイルまたはpackage.jsonファイルのいずれかがメインファイルに記載されていることを確認してください。

NPMモジュールの依存関係は、 package.jsonに記載する必要があります。 GCFは、初回セットアップ時にpackage.jsonファイルに記載されているモジュールをインストールしようとします。

200のステータスといくつかのメッセージを返す簡単なハンドラーを作成しましょう。 関数を作成し、次のコードをソースに追加します。

 exports.httpServer = function httpServer(req, res) { console.log(req); res.status(200).send('Server is working'); } 

作成中の関数のスクリーンショット

関数が作成されたら、関数をトリガーするために提供されたURLを開きます。 次のように応答するはずです。

ブラウザ出力のスクリーンショット「サーバーは機能しています」

それでは、ログのreqオブジェクトを調べてみましょう。 ログを表示するために、GCFはコンソールから直接オプションを提供します。 縦のドットをクリックして、ログオプションを開きます。

ログオプションを開くスクリーンショット

それでは、 /usersの単純なルートを処理するようにコードを更新しましょう。

次のコードは、 /usersルートの単純なGETPOSTリクエストを処理するために使用されます。

 exports.httpServer = function httpServer(req, res) { const path = req.path; switch(path) { case '/users': handleUsers(req, res); break; default: res.status(200).send('Server is working'); } }; const handleUsers = (req, res) => { if (req.method === 'GET') { res.status(200).send('Listing users...'); } else if (req.method === 'POST') { res.status(201).send('Creating User...') } else { res.status(404); } }

更新したら、ブラウザでテストしてみましょう。ただし、今回は最後に/usersを使用します。

ブラウザ出力のスクリーンショット「ユーザーの一覧表示...」

カッコいい。 ルーティングを使用して基本的なHTTPサーバーを作成しました。

操作とデバッグ

コードがストーリーの終わりである場合、サーバーレスNode.jsアプリケーションのようなインフラストラクチャオプションを調査することはありません。 これは、デプロイメントやデバッグなどの一般的なタスクを処理する方法の簡単な要約です。 Node.js開発者が他のアプリケーションに対してすでに行っていること。

展開:

関数のコードは、4つの方法でデプロイできます。

  • コンソールにコードをコピーして貼り付ける

  • ZIPファイルをアップロードする

  • クラウドストレージバケットからZIPファイルとしてデプロイする

  • クラウドソースリポジトリからのデプロイ

最も便利なオプションは、明らかに、ソースリポジトリからデプロイすることです。

呼び出し:

関数の作成中に、コンソールは次の形式の関数をトリガーするHTTP URLを提供します: https://<region>-<project-id>.cloudfunctions.net/<function-name>

AWS Lambdaの関数にはコールドスタートの問題があり、関数の実行に起動に追加の時間がかかります。 開始すると、次の実行は正常に応答します。 この最初の追加の起動時間は、コールドスタートと呼ばれます。 このトピックに関連するGCFの公式ドキュメントはありませんが、テスト中にコールドスタートの問題は発生しませんでした。

デバッグ:

GCFは、GoogleCloudのStackdriverLoggingサービスと統合されています。 すべてのコンソールログとエラーはここに記録され、すでにデプロイされているコードのデバッグに役立ちます。

テスト:

コンソールには、入力としてJSONを渡すことで関数をテストするためのオプションが用意されています。 関数は入力としてJSONを使用して呼び出され、出力はコンソールに表示されます。 リクエスト(入力)とレスポンスはExpress.jsフレームワークに似ており、開発プロセス自体で単体テストを行うことができます。 Node.jsテストの復習が必要な場合は、統合テストを実際に行うためのNode.jsガイドをご覧ください。

制限と次のステップ

サーバーレス機能の使用には独自の利点があり、制限もあります

  • ベンダーロックイン:特定のサービスプロバイダーに書き込むコードを制限します。 コードを別のプロバイダーに移動するには、移行に向けて多大な労力を費やしてコードを書き直す必要があります。 これは大きな問題になる可能性があるため、サービスプロバイダーを選択する際には十分に注意する必要があります。

  • リクエストとハードウェアリソースの数の制限:プロバイダーは、関数が一度に処理する並列リクエストの数を制限することがよくあります。 メモリ制限もあります。 これらのタイプの制限は、プロバイダーと話すことでさらに高くすることができますが、それでも存在します。

Google Cloud Functionsは成熟し、大幅に改善されています。 特にサポートできる言語では、まだ頻繁に改善および更新されています。 Google Cloudの機能を使用することを計画している場合は、変更ログに注意して、実装に重大な変更が加えられないようにしてください。


Toptal Engineeringブログでさらに読む:

  • TypeScriptとJestサポートの操作:AWSSAMチュートリアル