新たなアプローチ！サーバーレスアーキテクチャ

![23407690_m.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633992/5d23fbe8-b9cf-4d6c-1e2c-9fb70b0dbbbf.jpeg)

非常に人気がでている「サーバーレス」によるシステム開発。
もちろんエスプリフォートでも「サーバーレス」によるシステム開発を行っています。
「サーバーレス」での開発は、通常のシステム開発とは異なるため、トータル的にこれら技術が顧客のためになるかを見極めた上で取り組んでいっています。

本稿では、エスプリフォートで「サーバーレス」についてや開発における注意点などを少しご紹介いたします。


## サーバーレスとは

サーバーレスとは、文字通りに「サーバーがなし」との意味があります。
サーバー構築や保守などの管理作業を行うことなく、クラウド上でプログラムを実行できる仕組みであり、サーバーレスは非常に人気のある技術であり、世界中の多くの大企業や会社によって使用されています。

普通、多くの場合システムを開発・運用するためには、ネットワークやサーバ等のインフラが必要ですが、サーバレスではインフラを自身で用意することなくシステムの開発・運用が可能です。
サービス事業者がすでに用意している実行環境にプログラムをアップロードし、実行条件等を設定するだけで、プログラムを実行することができます。
利用者はサーバを管理する必要がないため、運用、保守、サーバ自体のコストの削減効果があります。

## Function as a Service（FaaS）について
サーバーレス・コンピューティングにはいくつか種類がありますが、代表的なものはFunction as a Service（FaaS）です。
Function as a Service（FaaS）はイベント駆動型のコンピューティングサービスになります。
開発者は関数を定義することでアプリケーションを開発し、イベント、またはHTTPリクエストがトリガーとなって関数を実行します。
FaaSは必要な実行環境を自動的に作成され、関数を実行させます。

このFaaSとして大手クラウド各社が提供しているサービスをご紹介します。

| 大手クラウドサービス社名 | 大手クラウドサービス |
|:-----------|:------------|
| AWS| AWS Lambda（ラムダ）|
| Google | Google Cloud Functions|
| Microsoft| Azure Functions|
| IBM| IBM Cloud Functions|

## サーバーレスのメリット
:::note info
**リクエスト数が少ないのであれば、料金が安くなる**
通常はサーバーの管理と運用にコストはかかりますが、サーバーレスアプリケーションを実装する場合、関数が呼び出されるたびのリクエスト数と実行時間、および使用容量に基づいて課金されるため、リクエスト数が少ない場合は、通常の常時稼働によるサーバー運用より料金は安くなります。
また、最初のスタートアップ時などの場合、サイトへの訪問数やAPIのリクエスト数が少なく見積もれる場合は、サーバーレスを選択するのも一つの選択肢となります。
:::
:::note info
**サーバ運用の負荷軽減が出来る**
サーバレスではOSやミドルウェアのアップデートやパッチ適用はサービス事業者が実施するため、ソフトウェアをインストールしたり、セキュリティを設定したり、ハードウェアをメンテナンスしたりする必要もなく、サーバーの管理や運用の工数を減らすことが出来ます。
:::
:::note info
**インフラ設計をあまり考える必要がない**
多くのサーバーレスサービスでは、オートスケール機能というものがあるので、アクセス数や負荷に合わせて自動で設定したスケーリングを行ってくれます。
これによりネットワークまで含むサーバ管理をサービス事業者が担うため、負荷分散などネットワークの知識がなくてもプログラムを実装できます。
:::
:::note info
**前にリソースやキャパシティを考慮する必要がない**
サーバーレスの場合、関数の実行時にサービスが自動的に実行環境を割り当てることができるため、常に最適なリソースで実行できます。
また、リクエスト数に応じて自動的にスケーリング（リソースの拡張・縮退）を行える為、通常のサーバー準備と異なり、事前にリソースやキャパシティを考慮する必要がありません。
:::
:::note info
**マイクロサービスアーキテクチャを実現できる**
マイクロサービスとは、機能を分解して複数の小さなコンポーネントを組み合わせてアプリケーションを構築し、他のコンポーネントに影響を与えることなく拡張性の高いシステムの開発や保守ができます。
サーバーレスでは関数単位で開発を行うため、マイクロサービスアーキテクチャーと相性がよく、他のコンポーネントに影響することなく拡張性の高いシステムの開発や保守を行うことができます。
:::

## サーバーレスのデメリット
:::note alert
**通常のサーバー運用よりコストが高くなる可能性がある**
サーバレスはプログラムの実行ごとに料金が加算されえるため、プログラムの実行回数が多い場合にはオンプレミスや他のクラウドサービスと比べて高くなる可能性があります。
リクエストが多く発生したり、サーバで常時稼働し続けるプログラムがある場合は、改めてコストを計算し、サーバレスで行うべきかを改めて検討することをお勧めします。
:::
:::note alert
**サービス提供事業者によってシステムに制限されることがある**
サーバーの管理をサービス提供事業者に一任にしているため、調整を自由に行うことはできない。
そのため、現在NodeJS 12.x、x版しかサポートしていないため、より新しいバージョンに更新したい場合でも、サービス提供事業者がサポートされるまで待つしかない為、システム的に制限される部分があり得るかもしれません。
:::
:::note alert
**即時の応答が必要なシステムには適さない**
「実行コンテキスト（実行する環境）」の起動から行うことをコールドスタートといい、立ち上げる際に多少の待ち時間が生じます。
そのため、要求が到着した時、関数を起動するのに少し時間（数ミリ秒から数秒）がかかるため、即時の応答が必要なシステムには適していません。
:::
:::note alert
**監視が難しい側面がある**
サーバーレスでは幾つものサービスが連動するので、一般のアプリケーションよりモニタリングなどが複雑となります。
また、ランタイムの大半がクラウドの内部に隠れているので問題の解析が簡単ではありません。
:::
:::note alert
**テストのしにくさ**
サーバーレスにおいてはローカルの開発環境でテストを完結させることが非常に難しいです。
したがって最終的にテストは実際のたとえばAWS環境を利用して、動かして確認する必要がでてきます。
:::

## サーバーレスでの開発による注意点
:::note warn
警告
**マイクロサービスではサービス間の連携部分に時間がかかる**
たとえばAWSでのAPI Gateway+Lambdaの場合、API GatewayからLambdaにデータが渡り、Lambdaから再度API Gatewayにデータが渡るのに一定時間かかる。
また、要求が到着した時、関数を起動するのに少し時間（数ミリ秒から数秒）がかかるため、これらを考慮した上での選定を行う必要があります。
:::
:::note warn
警告
**通常のWEBシステムと異なり、前の状態を一切保持できない**
サーバーレスアーキテクチャの場合は、ステートレスな構成となります。
そのため、前の状態を一切保持しない、保持できないため、通常のWEBシステムと異なり、セッションデータを保持することはできません。
もし、セッションデータを保持するのであれば、DBにデータを保持するようにするなどして自前で管理する必要があります。
:::
:::note warn
警告
**冪等性を考慮した設計が必須**
AWSのLambdaでは、非同期呼び出しの場合、デフォルトで呼び出しエラーは最大6時間再試行、関数エラーは2回リトライされます。
つまり、処理中にエラーが発生すると、メールが何度も送信されたり、注文が何度も行われたり、何度も外部APIを呼び出したりなどが行われてしまいます。
このようにならないように、冪等性（同じ操作を何度繰り返しても、同じ結果が得られること）を考慮して実装する必要があります。
:::
:::note warn
警告
**コールドスタートの対策の検討が必須**
コールドスタートの対策として、CloudWatch EventsからLambdaを定期実行することで回避できます。
これにより、インスタンスが消失する前にLambdaが再実行され、コンテナが再利用され、起動時間を省略しての実行（ウォームスタート）が可能となります。
この方法以外に対策としてProvisioned Concurrencyを設定することでコールドスタートの発生頻度を抑えることができますが、別途コストがかかる為、導入には要件等が必要です。

これら対策をどこまで対応するかは、機能要件などを考慮して、コールドスタート対策が必要かを事前に考慮することをお勧めします。
:::
:::note warn
警告
**実行順序は保証されない**
原則、サーバーレスは非同期で実行されます。
たとえば、APIが2回呼ばれた場合にリクエストXが先に呼ばれて、その後リクエストYが呼ばれたとしても、必ずリクエストXが先に完了するとは限りません。
つまり、実行順序は保証されないということを考慮して設計する必要があります。
:::
:::note warn
警告
**DBのコネクション数を再利用することはできない**
サーバーレスアーキテクチャの場合は、ステートレスな構成となります。
そのため、前の状態を一切保持しない、保持できないことで、コネクションを使いまわす仕組みであるコネクションプールが利用できないため、通常のシステムよりもコネクションが上限を超えやすいシステムとなるため、出来るだけ考慮することをお勧めします。
なお、AWSのみ「Amazon RDS Proxy」によって、この問題がクリアできるみたいです。
:::

https://www.esprit-fort.co.jp/

https://www.esprit-fort.co.jp/recruit/