1時間で作れる！かんたん自宅Serverless環境！　～はじめてのServerless Application入門～

#Serverless環境って？

**追記:
以下の記事で紹介したサーバーレス環境で，サムネイルサーバーを作ってみました！！**

**[サーバーレスの入門に！自宅サーバーレス+自宅S3環境で作るサーバーレス・サムネイルサーバー！](http://qiita.com/kotauchisunsun/items/856e7ecb65bb06f85ffa)**

現在，Amazon Lambda等に代表されるようなServerlessというアーキテクチャに注目が集まっています．このServerlessという概念は実はまだ確固たる定義が無いようなので，ある程度Serverlessとして言われている性質について3つ挙げたいと思います．

**「リクエスト毎にシステムの再起動を行う」**

今までのサーバーのアーキテクチャはデーモンと呼ばれるプロセスが常に立っており，それがリクエストを受けると，それぞれのアプリに処理を委譲していました．しかし，Serverlessの場合，一次受けのサーバー（プロセス）が存在し，そのサーバーがリクエストを認識することで，アプリケーションサーバーを再起動し，処理する．といったアーキテクチャになっています．

**「稼働時間にのみ課金が行われる」**

サーバーは基本的に月額で一定額を払うか，サーバーの稼働時間により従量課金をします．Serverlessの場合は，前述のとおり，処理している時間のときのみ，アプリケーションサーバーの起動を行うため，サーバーの稼働時間を最小化することが可能で，コストが非常に安いメリットがあります．

**「容易にスケーリング出来る」**

これはServerlessの性質として，リクエストが来ない場合は，サーバーが終了した状態にあることが特徴であると思います．そのため，稼働していないアプリケーションのコンテナ環境は，ホストマシンに依存せず自由に移動させたり，増設することが可能です．したがって，そのコンテナが動くホストマシンを多く用意し，リクエストの一次受けサーバーが増設を認識すれば，簡単にスケーリングすることが出来ると考えられます．一般的な仮想マシンであれば，ホットマイグレーションやライブマイグレーション等の技術で，仮想マシンを稼働したまま行うことが出来ますが，それすら不要になります．


こういった強いスケーリング性能や，サーバー自体のコストを非常に下げられることがから注目を集めている技術になっています．また，このようなServerlessのアーキテクチャを動かすプラットフォームはFaaS(Function as a Service)とも呼ばれています．


参考：[FaaS、PaaS、サーバーレスアーキテクチャのメリット](https://www.infoq.com/jp/news/2016/06/faas-serverless-architecture)

参考：[Serverless Anti-Patterns](https://www.slideshare.net/keisuke69/serverless-antipatterns)


GoogleTrendsを見る限り，Serverlessという分野自体は，2015年の末から順調に伸びているようです．
Serverless環境は各大企業がサービスを展開しています．AmazonのAmazon　Lambda，MicrosoftのAzure Functions，GoogleのCloud Functionsの3つが有名なところです．このGoogleTrendsの結果を見る限りは，ほぼ横並びのようです．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/139643/90776106-8688-e037-4ecb-00f1b91d0240.png)

有名な導入事例として「一休」があります．Wikipediaによると，高級ホテル・高級旅館専門予約サイト「一休.com」を運営する会社で，最近では[Yahoo! JAPANにより，1000億円で買収された](http://toyokeizai.net/articles/-/97244)ことが話題に上がりました．そのCTOであり，元はてなCTOの伊東直也さんのServelessの導入記事が話題になりました．

[伊藤直也氏が語る、サーバーレスアーキテクチャの性質を解剖する（前編）。QCon Tokyo 2016](http://www.publickey1.jp/blog/16/qcon_tokyo_2016.html)

[伊藤直也氏が語る、サーバーレスアーキテクチャの性質を解剖する（中編）。QCon Tokyo 2016](http://www.publickey1.jp/blog/16/qcon_tokyo_2016_1.html)

[伊藤直也氏が語る、サーバーレスアーキテクチャの性質を解剖する（後編）。QCon Tokyo 2016](http://www.publickey1.jp/blog/16/qcon_tokyo_2016_2.html)

そんな久々にワクワクするServerless環境ですが，**自宅の環境に簡単に導入することができた**ので，**ちょっと触ってみようかな**と感じた方は，是非導入してその感触を試してみてください．


#必要環境

基本的には，
- Docker 1.12以上

のみです．すごく簡単！あとはFaaSのアプリケーション用にgolangやnodejsの実行環境があると便利です．


#IronFunctions

![image.png](https://qiita-image-store.s3.amazonaws.com/0/139643/febe8031-8bab-e7d1-9a9e-acbc3d0500e1.png)

今回，導入するServerless環境は，IronFuntionsというものです．
以下の図は[公式サイト](https://www.iron.io/)からの引用です．図にあるように，Amazon Lambdaや,その他Serverless環境と比較して，オンプレミスで設置できるプロダクトであることが分かると思います．本記事では，このオンプレミスでの設置をUbuntu上でやってみようと思います．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/139643/ef8a39b0-26bb-4b90-a45f-457f884e867e.png)


##導入

とても簡単です．以下のコマンドを順に実行してください．

```bash
#ソースコードをクローンしてきます
$ git clone https://github.com/iron-io/functions.git
$ cd function
#IronFunctions用のCLIツール(fn)をインストールします
$ curl -LSs https://goo.gl/VZrL8t | sudo sh
#IronFunctionswを起動します
$ sudo docker run --rm -it --name functions -v ${PWD}/data:/app/data \
                   -v /var/run/docker.sock:/var/run/docker.sock \
                   -p 8080:8080 iron/functions
```

**これだけで導入完了です！**
localhost:8080でIronFunctionsの環境が整っています！


##はじめてのServerless Application

ここではチュートリアル通り，非常に簡単なアプリケーションを作ります．
最初に作業フォルダを用意します．

```shell-session
$ mkdir hello
$ cd hello
```
そのあと，以下のソースをfunc.goとして作成してください．

```go:func.go
package main

import (
	"encoding/json"
	"fmt"
	"os"
)

type Person struct {
	Name string
}

func main() {
	p := &Person{Name: "World"}
	json.NewDecoder(os.Stdin).Decode(p)
	fmt.Printf("Hello %v!", p.Name)
}
```

そして以下のコマンドを実行してください．

```bash
# アプリ(hello)用の設定ファイルfunc.yamlの作成(testapp部分はDockerhubアカウントとの連携用なので今回は割愛,特に何の値でも良い)
$ fn init testapp/hello
# アプリをビルド
$ fn build
# 先ほど建てたIronFunctionsの環境にアプリをmyappとして登録
$ fn apps create myapp
# myappをサーバー上のURLの/helloのパスに設定する
$ fn routes create myapp /hello
```

以上で，IronFunctionsの環境にアプリを登録できました．実際に実行してみましょう．

```bash
$ curl -H "Content-Type: application/json" -X POST -d '{
    "name":"Johnny"
}' http://localhost:8080/r/myapp/hello
> Hello Jonny!
```

やった！

ソースコードを見ると分かりますが，基本的に標準入力と標準出力しか扱っていません．HTTPリクエストのボディがそのまま標準入力として流し込まれ，プログラムの標準出力が，そのままレスポンスボディに出力される．という非常に分かりやすい作りになっています．


#使ってみて分かったServerlessのメリット・デメリット
##メリット
**「Webアプリの構築が　かんたん」**

上記の手順のように非常にアプリの構築が簡単です．Webアプリを作るときに，Apacheやnginxでサーバーを立て，設定を書き，プラグインを入れ・・・という手順を踏まなくて良く，圧倒的に速く作ることが出来ます．今となってはDockerで，この手順が簡略化されたとはいえ，いまだにhtdocsの下にファイルを置くだの，専用ユーザーを作って，ログのパスは・・・のようなWebアプリの設置のお作法も少なからずあると思います．そのようなしがらみから解放され，アプリのロジックに集中できると思います．

**「プログラムが　かんたん」**

すごくプログラムが簡単です．これはプログラミング初心者にもいいんじゃないかな．と思います．Webアプリを作るにあたって，HTTPリクエストのお作法を知らなければならないと思います．しかし，このIronFunctionsでは一般的な標準入力，標準出力のプログラムと大差ありません．そのため，サーバーサイドアプリを書く練習だったり，初心者がちょろっとWebAPI作ってみたい．といった要求には簡単でよいと思います．

##デメリット

**「複雑なルーティングができない」**

きちんとドキュメントを読んでいるわけではありませんが，1つのURLの固定のPathに対し，1つのアプリしか設定できないようです．例えば，/usr/UserID/infoのような,UserID部分が可変になるようなPathを持つAPIが組めないようです．どうしてもそういうことがしたい場合は，POSTのボディに情報を載せ，Pathを/user_infoにする．といった工夫が必要があるようです．

**「動作が遅い」**

これはGoの標準ライブラリでサーバーで組んだ場合，10ms程度で終わっていた処理が，IronFunctionsの場合はレスポンスに1000ms程度かかります．これは動作原理として，HTTPリクエストを受けるたびに，Dockerのコンテナを起動し，レスポンスを返した後は終了することに起因していると思います．そのため，レスポンスに時間がかかることを前提としたシステムを構築する必要があり，アプリケーションにより向き不向きの強い環境だと感じました．


#感想

　遅さだけに目をつむれば，悪くないなと思いました．個人的にはいろいろなサーバー設定の周りが苦手なので，それを無視できる環境が一発で手に入るのは非常にうれしいです．
　まだ試していませんが，ライブラリの導入とは難しいのではないか？と思っています．RestAPIがコールされた際に，どのようなDockerのコンテナが作られるか，きちんと見ていないため，ひとたびライブラリのインストールにはまると，デバッグにかなりの時間がかかる気がします．
　結構簡単なので，自分としてはハッカソン等でminimalなAPIを作る．とか，IoT機器などで叩く簡単なAPIを作るのであれば十二分に使える代物ではないかと思いました．
　みなさんもぜひ使ってみてください！