Azure Functionsの基本的な話


Microservices Advent Calendar 2016 の10日目です。ちきさんです。

僕にとってマイクロサービスと言えばサーバーレス。
サーバーレスと言えばAWS Lambda。
そしてAWS Lambdaと言えば Azure Functions!!

今月Gotanda.jsでLTした 「Azure Functionsでサーバーサイドアプリを動かす」 も併せてどうぞ。

Azure Functions

Azure Functions (公式)

要するにで言ったらAWS LambdaのAzure版なんですけど、起動にえらい時間がかかるという特徴があります。なのでConsumption(従量課金)プランでHTTPエンドポイントの運用をすることは止めておいた方がいいでしょう。バッチ処理ぐらいに留めておいた方が無難です。

どれくらい起動時間がかかるかというと、まともなExpressアプリを書いてバンドルしないで運用したら100秒くらいです。本当です。

Azure Functionsの料金プラン

Azure Functions のスケーリング方法 に書いてあるのですがわかりにくいのでざっくり話すと2種類あります。

  • 従量課金プラン(Consumption Plan)
  • 固定料金プラン(Azure App Service Plan)

前者はAWS Lambdaのように実行回数と実行時間による従量課金です。この場合の料金体系はLambdaとほぼ同等かと思います。ただしAzure Functionsは起動が激遅ですが。
後者は起動時間をチャラにした反則プランで、早い話がインスタンスを借り切って起動させっぱなしにしてそこでFunctionsを動かす、つまりEC2でAWS Lambdaを動かすみたいなイメージです。

後者はこのように説明されています。

App Service プランでは、関数は現在動いている Web Apps (Basic、Standard、Premium SKU) と同じように、専用の VM 上で実行します。この専用 VM はアプリと関数に割り当てられ、コードがアクティブに実行されているかどうかに関係なく、常に使用できます。このプランは、他のコードを既に実行している既存の VM があるが使用率が低い場合、または (ほぼ) 継続的に関数を実行する予定がある場合に適したオプションです。VM を使用すると、コストが実行時間とメモリ サイズの両方から切り離されます。その結果、長時間実行される多数の関数のコストを、それらを実行する 1 つ以上の VM のコストに制限できます。

なるほどスケールアウトを犠牲にしたことで得られるメリットもあるわけですね。

Azure Functionsの基本

内容が重複してしまうので 「Azure Functionsでサーバーサイドアプリを動かす」 を見てください。

  • プロジェクトのサブフォルダがエンドポイントになる。
  • function.jsonがないとそのフォルダはファンクションと見なされない。
  • contextを引数に取る関数をexportしなければならない。

等々いくつかのルールがあります。

最もシンプルなファンクション

考えうる限り最もシンプルなファンクションを書こうとするとこうなります。

root
|--function1
   |--function.json
   |--main.ts
main.ts
export function azureFunction(context, req) {
  context.res = {
    status: 200,
    body: {
      message: 'Hello world.'
    }
  };
  context.done();
}
  • /api/function1を叩くと
  • {"message": "Hello world."}というJSONが返ってくる。

Web APIサーバーを作る分には特に苦労しない

そもそも起動が遅いのでバッチ処理以外の用途には向かないAzure Functionsですが、インスタンス借り切りプランであればWeb APIサーバーとしての使い道もありです。

JSONを返すだけのサーバーを作るなら既存のExpressやHapiをほぼそのままの形で持ち込むこともできます。
そのへんも冒頭で紹介したスライドの中で解説しています。

一般的なWebサーバーとしては使えない

実はAzure Functionsの中でExpressを動かして Client --> Azure Functions --> Express みたいな仕組みもできてしまうので、Expressで作った既存のWeb APIサーバーを持ち込むのは簡単です。

でもこれだけは無理というのが、静的ファイルの配信です。

  • ...../api/hoge/index.html
  • ...../api/foo/bundle.js
  • ...../api/bar/style.css

とかが軒並みエラーになります。レスポンスのヘッダーでContent-Typeを指定してもダメです。実際にそこにファイルがあるにもかかわらず。理由はよくわかりません。


今回はここまでです。

次回はどうやってその問題を乗り越えるかについて書こうと思います。

明日は @nabuchi さんです。