• SELECT MENU

2018.09.20

サーバーレスの説明と、「AWS Lambda」でPythonを使用した、ちょっとしたサーバーレス関数の作り方

YUJI OIKE
[ENGINEER]
カレー好き。
来世は印度に生まれたい。

初めに

IT関係の仕事をしていると、サーバーレスもしくはサーバーレスアーキテクチャって単語を耳にする事が増えてきたかと思います。「なんとか + レス」って言葉、よく聞きますね。例えば、ダイエット流行りの昨今、「シュガーレス(砂糖なし)」とか、日本は遅れていますが「キャッシュレス化社会(現金使用しない)」など。枚挙に暇がないですね。サーバーレスもシュガーレスやキャッシュレスのようにServer + Lessなので、サーバーのないシステム?どうやって動くの?ともやもやしてる人が多いでしょう。

私も疑問に思っていたので、今更ながら、実際にサーバーレスを触ってみました。触ってみたところ、今までのWebシステムの考え方をひっくり返すくらい、システム構成が異なるのものでした。さて、この記事を読んでもらうことで、ひとまず「サーバーレスって何?」、サーバーレスとは「何を目的としているか?」のもやもやが解消されればいいなと考えています。対象は、社内の企画や制作の人向けです。バリバリのWebやサーバーの技術屋には向けてませんのでご容赦下さい。

というわけで、サーバーレスに関して以下の順で説明します。

  1. 1.サーバーレスが登場した背景
  2. 2.サーバーレスとは何か
  3. 3.サーバーレスアーキテクチャのメリット・デメリット
  4. 4.サーバーレスアーキテクチャの導入事例
  5. 5.サーバーレスアーキテクチャの「AWS Lambda」を使用したTwilio電話サンプル
  6. 6.サーバーレスの疑問
  7. 7.最後に

1.サーバーレスが登場した背景

1.1 今までの仕組み

現在、ホームページを見たり、インターネットのサービスを利用する為の仕組みとして、フロントエンドと言われるWebブラウザやアプリ、バックエンドと言われるWebサーバーやデーターベースなどが挙げられます。それらを使用した一般的な仕組みとして以下のような流れとなっています。まず、ユーザーがブラウザやアプリなどのフロントエンドからHTTPリクエストを行い、Webサーバーがリクエストを処理します。次に、バックエンドのWebサーバーやアプリケーションサーバーでは、フロントから送られてきたデータをデータベースに保存し、HTMLやJSONなどの形式でWebブラウザなどのフロントにレスポンスを返します。

また、多くのシステムで、ロードバランサー、キャッシュ機能、データの冗長化などの仕組みが用いられています。この仕組みは、自前、データーセンターなどにかかわらず、必ずOSや各種アプリケーションを実行するための、サーバー、ネットワーク、その他の機器を必要とします。

そして、システムを稼働・運用する為の作業が発生します。例えば、ネットワークの管理、サーバーの用意、OSのインストール、メンテナンス、バックアップなどです。その作業には専任の技術者が必要とされます。システムの目的はクライアントが要求することの実現ですが、それ以外のところで問題が発生することもしばしばとなります。

1.2 ここでの問題

●自前でサーバーやインフラを用意、管理、運用すると色々大変
●管理・運用するためにリソース(人的、物理的、時間等)を割く必要があるので、プログラム開発に全力を注げない
●管理する範囲が増えると問題も増える

この頭の痛い問題を解決するために、幾つかのサービスが登場しました。次にそのサービスを紹介します。

2.サーバーレスとは何か

2.1 マネージドサービス(IaaS、PaaS、SaaSなど)

さて、IaaS、PaaS、SaaSって言葉は聞いたことありますか?
前述の問題を解決するため、自前サーバーや、ハウジング、ホスティング等と異なる形態で、類似機能やそれまでに無い機能を提供するサービスが登場しました。それがIaaS、PaaS、SaaSです。

IaaS、PaaS、SaaSは、クラウドのサービスであり、インターネットを通じて以下を提供します。

  • 1.インフラ(ネットワーク、サーバー機器など)
  • 2.プラットフォーム(MySQLやWordPressなどが動くOSの載ったサーバーくらいに思っておいて下さい)
  • 3.ソフトウエア(例えばメールやブログなど)

これらはサーバーの運用、管理、保守、障害時対応などのシステム管理を全て提供してくれるので、マネージドサービスやクラウドマネージドサービス等と呼ばれています。なお、クラウドサービスの形態によってカバーする範囲は異なります。

※クラウドサービス
インターネットを通じて提供されるコンピュータのハードウェアとソフトウェアの機能くらいに考えておいて下さい。自前でPCやサーバーにインストールしてたものが必要無くなるところが、単なるインターネットを使用する場合との違いです。

以下、IaaS、PaaS、SaaSの説明です。

2.1.1 IaaS

「IaaS」は「Infrastructure as a Service」の頭文字の略で「イァース」と読みます。OSやその上のソフトウエアを動かすための、インフラをインターネット上で提供するサービスです。インフラとは言え、AWS EC2に見られるようにOSまで提供しているケースが一般的です。
●AWS、Google Compute Engine、Microsoft Azureが相当します。
●サーバーをすぐ立てられる、サーバーの数を簡単に増やせる(スケールアウト)、メモリや保存容量などスペックをすぐ上げられる(スケールアップ)点がメリットです。

2.1.2 PaaS

「PaaS」は「Platform as a Service」の頭文字の略で「パース」と読みます。ソフトウエアを可動させるためのOSとミドルウエアの載ったサーバーをインターネット上で提供するサービスです。
●Google App Engine、Heroku、Cloud9など、が相当します。
●プログラムの実行環境、例えばPHP、MySQLなどが実装されていて、インストールが不必要なのがメリットです。
WordPressでブログを立ち上げたい、ECサイトをEC-CUBE で立ち上げたいなどと考えたときも、必要な実行環境がそろっているPaaSさえあればすぐ立ち上げられます。

2.1.3 SaaS

「SaaS」は「Software as a Service」の頭文字の略で「サース」と読みます。ソフトウエアのみインターネット上で提供するサービスです。
●Creative CloudやGMAIL、cacooなど、が相当します。
●導入コストが低い、専用のハードウェアが必要ない、場所を選ばず使用出来るなどのメリットがあります。利用停止も簡単にできます。

以下に比較の図を示します。ベンダーが提供する範囲が以下画像の△の部分です。

ここまでは、まだサーバーレスとは呼ばれていません。

2.2 サーバーレスと言われるサービスの登場

2.2.1 FaaS

IaaS、PaaS、SaaSをざっと紹介しましたが、これらを更に進めたテクノロジーの一つがサーバーレスと呼ばれるものです。サーバーレスの一つの形態に、FaaSがあります。FaaSは「Function as a Service」の略で、実行したいこと(プログラムの機能=関数)のみを、クラウドに置いてそれを実行させるサービスです。サーバーやプラットフォーム、ソフトウエアを用意する必要はありません。動くコードを置けばそれが実行出来ます。(同義ではありませんが、サーバーレスと言うと毎回説明が必要となるので、FaaSという言葉を好んで使う人も多いようです。)

以下に比較の図を示します。クラウドベンダーが提供する範囲が以下画像の△の部分です。

2.3 従来型とFaaSの実行イメージ

2.3.1 従来型

実行したいこと(プログラムの機能=関数)と言われても、イメージが付きにくいと思いますので、少し乱暴になりますが「OKOS」を例に補足したいと思います。
※OKOSについて
弊社で開発・リリースしているモーニングコールアプリです。OKOSはフロントエンドにiPhone/Androidのネイティブアプリ、バックエンドにサーバーアプリケーションの構成をとっています。

さて、アプリケーションは処理の集まりです。処理を小分けにしたものを関数と呼びます。OKOSのサーバー側アプリケーションで言えば、「キャンペーンを予約する関数」、「コールする関数」「コール予約一覧」を表示する関数などがあります。そのような小分けにされた関数が統合されて一つのサーバーアプリケーションが出来ています。自前サーバーでも、PaaSでも、一つのアプリケーション全体をサーバー側に置かないと動きません。また、特定の言語で書かれたアプリケーションを動かすための実行環境が必要です。アプリケーションがPHPで出来ているならばPHPの実行環境、Pythonで出来ていればPythonの実行環境などが必要となります。

2.3.2 FaaSの実行イメージ

一方、FaaSですが、関数をクラウドに置くだけで動きます。特定の言語の実行環境を用意する必要もありません。下の図のようにサーバーと言う概念がありません。

なお、FaaSで実行される機能は「マイクロサービス」とも呼ばれており、それが連携してシステムを作ることとなります。

2.4 サーバーレスって何?

さて、ここで「サーバーレスって何?」サーバーレスとは「何を目的としているか?」まとめます。

サーバーレスって何?
●関数を置けば、クラウドサービスが関数を実行してくれる
●各関数がマネージドサービスによって連携して動く
仕組みです。

何を目的とするか?
●サーバーやインフラを気にせずに、開発者がプログラミングに全力を注げるようにする
ことを目的としていると言えるでしょう。

説明してきたように、関数を動かすクラウド環境を利用しているので、サーバーがない、必要ないと言うわけではありません。自分でサーバーを管理しないということです。そうすれば、今までのようにOSやミドルウエアをインストールしたり、メモリ使い切ってないかとか、ダウンしてないか等を気にしたりすることが少なくて済みます。

因みにサーバーレスという言葉が初めて使われたのは2012年と言われます。
「Why The Future Of Software And Apps Is Serverless」
そして2014年にAWS Lambdaを皮切りに、その後はGoogle Cloud Functions、Cloud Functions for Firebase、Azure Functions、IBM Cloud Functionsなど各社が提供しています。

目的が素晴らしいので、ホントにそう出来ればなと思います、しかし、サーバーレスはどんな強敵も撃退出来るの?という疑問も湧きますよね。というわけで、次にサーバーレスアーキテクチャのメリット、デメリットを見ていきます。

3.サーバーレスアーキテクチャのメリット・デメリット

3.1 メリット

●サーバー不要
●インフラの保守が要らない
●環境構築に時間がかからない
サーバーの運用、管理、保守、障害時対応などのシステム管理を全て提供してくれるので、そこにリソースを割く必要が無くなります。
●料金がお得
常駐プロセスを持たず、実行時にのみ課金するというモデルなので、例えば、EC2のように起動している限り課金され続けるわけではありません。コストダウンに繋がります。
●高い可用性(継続して稼働できる能力が高い)と高いスケーラビリティ(拡張性が高い)
リクエスト数が増えた場合、一定程度までならマネージドサービスが自動でスケールしてくれます。24時365日稼働などミッションクリティカルなシステムでない限り大丈夫です。
●マネージドサービス間での連携が簡単
AWS、GCP、Azureなどに見られるように、他にもサービスを提供しており、それとの連携が容易です
●ソースコード量の削減ができます。
●組み合わせの柔軟性
既存のシステムの問題の一部のみ解決するために使うことも出来ます。

3.2 デメリット

●ベンダーロックイン
特定のサードパーティが用意したAPIやサービスを使うので、乗り換えたいと考えた時に容易に出来ない場合があります。
●クラウドサービスごとの制限
例えばLambdaには同時実行数の制限があります。ベンダーによって申し込めば制限は変更できるようです。
●ステートレス
状態を保存する場合は他のサービスを利用する必要があります。
●実行時間に制約
バッチ処理など処理時間がかかる仕組みには向きません。
●サーバーが触れないことが逆にデメリットになる場合もあります。
マネージドサービス自体が落ちたり、不具合があると手の出しようがありません。
●全てのシステムに向いているわけではありません
ミッションクリティカルなアプリケーションには向きません。

このようにメリットだけではなくデメリットもあるので、構築するシステムによって向き不向きが考えられます。ですので、サーバーレスのメリットとデメリットを考慮して利用するかどうかを決定する必要があります。

4.サーバーレスアーキテクチャの導入事例

さて「サーバーは放っといて、コードに注力!」なんて良いことばっかり言って、デメリットもあるし、ホントに使われてるのって思いませんか?事例を調べてみたら、今ではかなり使われています。

4.1 AWS Lambdaの事例

スクエニ
朝日新聞
日経新聞
JINS MEME
Cookpad

4.2 Cloud Functions for Firebaseの事例

Firebaseの事例

この様に、有名な会社が大規模システムで使っている事例も沢山あります。スクエニや、日経新聞の画像処理のように直ぐに威力を発揮するようです。

それでは、サーバーレスの老舗AWS Lambdaを使った、すぐ出来るFaaSのサンプルを示します。

5. AWS Lambdaを使用したTwilio電話サンプル

5.1 AWS Lambda関数の作成

5.1.1 AWS Lambdaについて

AWS LambdaはAWS(Amazonのクラウドサービス)で利用できるサーバーレス環境です。関数を置く(デプロイ)と、実行できます。使える言語は、Node.js、Java、C#、Python、Goです。今回はPyhtonを使用します。電話をかけるプログラムを書いて、Lambdaに実行させる流れとなります。
●APIGatewayを使用した実行方法
●他のAWSのサービスの状態が変わった時のイベントで実行方法
などあります。

5.1.2 関数の作成

1.AWSコンソールにサインイン。[サービス] > [AWS Lambda]を選択します。

 

2.関数一覧画面が表示されます。右上の「関数の作成」ボタンをクリックします。

3.一から作成をクリックします

5.1.3 一から作成

1.以下のように入力し・選択し、画面下部の「関数の作成」ボタンをクリックします。

  1. ●名前:twilio-test-python
  2. ●ランタイム:Python 3.6
  3. ●ロール:テンプレートから新しいロールを作成
  4. ●ロール名:role-twilio-test-python
  5. ●ポリシーテンプレート:テストハーネスのアクセス権限

5.1.4 Lambda関数作成成功

1. 画面が関数の画面に切り替わります

2. 画面を下にスクロールし、関数コードを表示します。以下のようにZIPファイルを選択します。

  1. ● コードエントリタイプ:.ZIPファイルをアップロード
    Pythonの関数をZIPで固めたものをアップロードします。PythonファイルのZIPの方法は後述。

4. 以下のように入力し、右上の保存ボタンをクリックします。

  1. ● ハンドラ:lambda_functions.call_handler
     lambda_functions.pyがファイル名、call_handlerが関数名としてPythonで作成しています。

5. 関数の保存に成功すると、以下のように関数名のところに「保存されました」と表示されます。

5.1.5 Pythonで関数を作成する

1. 上記でアップロードしたプログラムの作成手順を説明します。開発マシンにPythonはインストールされている前提です。Python自体はLambdaで実行出来るのですが、今回はPythonに含まれないTwilioを使うので、Python用のTwilioライブラリを取得します。まず関数を書くスクリプトを置いているフォルダで、以下実行します。

$ pip install twilio -t .

2. DLされるものから必要なもの以外を省くと以下のようになります。

3. lambda_functions.pyを作成し、call_handler関数を実装する
相手先の電話番号と、伝えたいメッセージを入れれば電話がかかる簡単なプログラムです。Webの画面から呼び出します。
lambda_functions.pyという名前で、ファイルを作成してください。今回TwiMLは別サーバーに用意しています。本来はAWSのLambdaでTwiMLを返すことが出来るので、AWS内で全て完結できます。(TwilioからTwiMLのURLが呼び出されるのですが、デフォルトではないSSLの設定をする必要があるので、今回は元々SSLを設定している別サーバーとしました)

from twilio.rest import Client
import urllib.parse

# Twilioのアカウントsidとトークンをセットする
account_sid = 'ACxxxxx'
auth_token = 'xxxxxx'

# Lambdaが呼び出す関数
def call_handler(event, context):
    # APIGatewayから呼ばれるパラメータをセットする
    return call_exec(event)

# Lambdaが呼び出す関数から呼ばれる処理
def call_exec(params):
    # 基本のTwimlのURL
    twimlUrl = 'https://xxxxxxxxxxxxxxxxx/twiml.php'
    # 引数にメッセージがあれば、それをTwimlのメッセージとする
    if 'message' in params:
        if params['message'] != '':
            twimlUrl = twimlUrl + '?message=' + urllib.parse.quote(params['message'])

    # コールする電話番号初期化
    toTelNo = '+81xxxxxxxxxxx'
    # 電話番号をURLから取得
    if  'telno' in params:
        if params['telno'] != '':
            toTelNo = '+81' + params['telno']

    # オブジェクト生成
    client = Client(account_sid, auth_token)
    call = client.calls.create(
                        url=twimlUrl,
                        to=toTelNo,
                        from_='Twilioで取得した番号'
                    )

    return call.sid

4. 作成したPythonスクリプトをZIPにする。
間違いやすのですが、カレントディレクトリは含めません。Lambdaで実行するファイルを置いているディレクトリ直下以降のファイルとディレクトリのみ含めます。このcall.zipが上記でアップロードしたものとなります。

$ zip -r call.zip .

5.1.6 AWS Lambda関数のテスト

それでは、再びAWSコンソールに戻り、アップロードした関数に問題がないかテストします。
画面の右上の「保存」ボタンの左隣の「テスト」ボタンをクリックします。「テストイベントの設定」画面が開きます。

1. 以下のように選択・入力して画面下部の作成ボタンをクリックして下さい。

  1. ●[新しいテストイベントの作成]を選択
  2. ●イベントテンプレート:API Gateway AWS Proxy
  3. ●イベント名:APIGatewayTwCall

2. 右上の「テスト」ボタンの左隣でテストが選択出来るようになりました。作成した「APIGatewayTwCall」を実行します。「テスト」ボタンをクリックして下さい。

3. 成功すると以下のような表示がされます。

5.2 Amazon API Gatewayの設定

5.2.1 Amazon API Gateway

Lambda関数は直接呼び出せません。今回はAmazon API Gatewayをインターフェイスにして呼び出します。API Gatewayがインターフェイスになることで、統一的なインターフェイスが設計、構築できます。また、セキュリティ的に問題があってもLambdaを呼び出したり出来ません。API GatewayはHTTPSリクエストを受け取り、Lambda関数を呼び出すことが出来ます。

5.2.2 トリガーの追加

1. 左側のトリガーメニューからAPI Gatewayを選択します。

2. 追加されたAPI Gatewayをクリックして下さい。「トリガーの設定」画面が下部に表示されます。以下のように設定して下さい。

  1. ●API:[新規 APIの作成]を選択
  2. ●セキュリテイ:オープン
  3. ●API名:twilio-test-python-API
  4. ●デプロイされるステージ:co-lab

3. 画面下部の「追加」ボタンをクリックして下さい。以下の画面のようになります。

4. 画面右上の「保存」ボタンをクリックして下さい。APIのエンドポイントが作成されます。

5.2.3 GETメソッドの作成

1. API名「twilio-test-python-API」をクリックして下さい。API Gatewayの設定画面が表示されます。実際はこの画面から、リクエスト⇒API⇒Lambda関数へ渡すGETパラメータ等を設定しますが、ここでは割愛します。

2. 「アクション」ボタンをクリックし「メソッドの削除」クリックでANYを削除します。

3. 再度「アクション」ボタンをクリックし「メソッドの作成」をクリックします。GETを選択し、右のチェックをクリックします。

4. GETメソッドの設定を行います。以下のように設定して下さい。

  1. ●統合タイプ:[Lambda関数]を選択
  2. ●Lambdaプロキシ統合:チェックを外す
  3. ●Lambdaリージョン:そのまま
  4. ●Lambda関数:[twilil-test-python]を選択

5. 「保存」ボタンをクリック。権限追加の確認が表示されるので「OK」ボタンをクリックして下さい。

5.2.4 API Gatewayを通したLambda関数のテスト

1. GETメソッドのテストを行います。テストの下の稲妻マークをクリックして下さい。

2. テスト画面が表示されますでの、画面下部のテストボタンをクリックして下さい。今回はしませんが、ヘッダーパラメータやクエリーストリングを渡す場合のテストもここで出来ます。

3. テスト結果が画面に表示されます。ステータス200の場合は成功です。

5.2.4 API Gatewayのデプロイ

1. 作成したAPIをデプロイします。デプロイして初めてURLからのアクセスが可能となります。「アクション」ボタンをクリックしAPIをデプロイを選択します。

2. デプロイステージの選択が表示されるので、「デプロイ」ボタンをクリックして下さい。
以下のように設定して下さい。

  1. ● デプロイされるステージ:[co-lab]を選択

3. デプロイ後、URLが表示されます。
1.URLの末尾に作成したLambda関数名「/twilio-test-python」をつけると、Lambda関数が呼び出せます。

5.2.5 twilio-test-pythonの削除

1. いたずらされないように関数を削除しておきます。「twilio-test-python」をチェック後、「アクション」ボタンをクリックし削除を選択します。

5.2.6 電話をかけるサンプルを試したい人

Lambdaの説明は終わりです。上記の関数は削除しましたが、Lambdaで電話をかける関数と、呼び出し画面を用意しているので、興味のある方は私までご連絡下さい(「株式会社コンテンツでは随時エンジニアを募集してますので、興味のある方は一緒に働きましょう」)。

5.2.7 余談

TwilioにもTwilio Functionsというサーバーレス環境があります。Lambdaを利用したもので、node.jsしか使えません。ちょっとやってみたところ、Lambdaより簡単に出来ました。

6.サーバーレスの疑問

これまで取り上げませんでしたが、以下のような疑問を持った人がいると思います。
●認証や認可、データーベースなどはどうなるのか?
●LambdaやAWS API Gatewayなどのデプロイを毎回マニュアルでやるのは大変過ぎる!?
少しだけ紹介しておきます。

6.1 認証、認可、DBなど

サーバーがないのならログイン情報などどうするのか?、データの登録や保持はどうするのか!って気になります。それに関しては、それぞれのクラウドサービスから提供されているサービスを利用することで解決できます。または別のクラウドサービスと組み合わせることでも解決できます。
AWSでは、認証や認可にAWS Cognito、データーベースにRDSや、DynamoDBが用意されています。AWS Cognitoよりは、統合認証プラットフォームAuth0が良いという話もありますし。データーベースもFirebaseを使う場合もあります。組み合わせは色々ですが、クラウドで既に用意されているサービスを使用できます。

6.2 関数の配置(デプロイ)

前述のLambdaは手動でアップロードしました。またAPI Gatewayも手動で作成しデプロイしていました。数が増えたり、関数のメンテナンスが必要となったら、いちいち手動ではやってらんないですよね。
デプロイに関してAWS SAMを利用することで、マニュアルでのデプロイではなく、継続的にCLIでのデプロイが可能となります。

その他、セキュリテイや料金なども気になると思いますが、ここでは触れません。

7.最後に

最後ですが、サーバーレスに関してなんとなく理解していただけましたか?

サーバーレスは、サーバーがないわけではなくて、
●自前でサーバーの用意、管理が要らない
●関数を置くだけでシステムを実現する
●複雑な場合は、各マネージドサービスを連携させてシステムを実現する
クラウドのサービスです。

開発者としては、今までのWebシステムの構成と大きく異なるので、新鮮で覚えることも多いです。実際にサーバーレスでシステムを構築する機会はないかもしれませんが、やる機会があれば挑戦したいものです。

glasses

[162]

Webテクノロジー

© 2017 Contents Co.,Ltd.