Goフレームワーク Echoを触る

担当するプロジェクトでGoでAPIを実装予定で、
利用するフレームワークの検証した際のメモです。
以下候補ですが、APIなのでシンプルで高速なもの&開発も活発なEchoを試してみました。

フレームワーク 最終コミット日 Latest release スター その他メモ
Martini 2016/2/15 2014/5/20 8,248 ・モジュール形式のウェブアプリケーション/サービスを作成するパッケージ
・パフォーマンスはあまり良くない
・今後の開発が怪しい?
Revel 2015/9/12 2015/03/25 6,457 RailsやPlayのようなfull stack web framework
Gin 2016/1/30 2015/5/23 5,842 ・Martiniライクでパフォーマンスが良い
・今後の開発が怪しい?
Negroni 2015/3/20 2014/3/31 3,417 ・小さくでしゃばりでないフレームワーク
・Martiniは良いけど魔術的なものが多すぎると考えている人にオススメ
・最近更新されていない
Echo 2016/3/9 2015/12/2
もうすぐ最新版リリースされそう
3,077 ・高速で小さいフレームワーク
・開発が活発
Goji 2016/3/4 2015/2/1 2,983 ・ミニマムなフレームワーク
・既存で利用もうひと機能欲しい
・今後の開発が怪しい?

環境

Goインストール

goのバージョン管理用にgvmをインストール
最新のgo1.6を使う

$ sudo yum install curl
$ sudo yum install git
$ sudo yum install make
$ sudo yum install bison
$ sudo yum install gcc
$ sudo yum install glibc-devel

$ wget 'https://www.mercurial-scm.org/release/centos7/RPMS/x86_64/mercurial-3.7.1-1.x86_64.rpm'
$ sudo rpm -Uvh mercurial-3.7.1-1.x86_64.rpm
$ wget 'https://storage.googleapis.com/golang/go1.4.linux-amd64.tar.gz'
$ tar -zxvf go1.4.linux-amd64.tar.gz
$ mv go ~/go1.4/

$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
$ source ~/.bashrc

$ gvm listall
   gvm gos (available)

   go1
   go1.0.1
   go1.0.2
   ・
   ・
   ・
$ gvm install go1.6
$ gvm use go1.6
$ go version
go version go1.6 linux/amd64

Echoインストール

go get github.com/labstack/echo

テスト用ソースコード

簡単なJSONを返却するコード

package main

import (
    "net/http"
    "time"

    "github.com/labstack/echo"
    mw "github.com/labstack/echo/middleware"
)

// 現在時刻を取得
func getNow() string {
    var loc, _ = time.LoadLocation("Asia/Tokyo")
    var now = time.Now().In(loc).Format("2006-01-02 15:04:05")
    return now
}

// Handler
func hello(c *echo.Context) error {
    var content struct {
        Response  string `json:"response"`
        Timestamp string `json:"timestamp"`
    }
    content.Response = "Hello, World!"
    content.Timestamp = getNow()
    return c.JSON(http.StatusOK, &content)
}

func main() {
    // Echo instance
    e := echo.New()

    // Middleware
    e.Use(mw.Logger())
    e.Use(mw.Recover())

    // Routes
    e.Get("/", hello)

    // Start server
    e.Run(":1323")
}

レスポンス

Macのコンソールからcurlで叩いてみる
簡単ですね!

$ curl --dump-header - {host}:1323
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Thu, 10 Mar 2016 06:51:08 GMT
Content-Length: 62

{"response":"Hello, World!","timestamp":"2016-03-10 15:51:08"}

パフォーマンス

Requests per secondが1573となかなかの結果

$ ab -n 1000 -c 100 http://{host}:1323/
Document Path:          /
Document Length:        62 bytes

Concurrency Level:      100
Time taken for tests:   0.636 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      185000 bytes
HTML transferred:       62000 bytes
Requests per second:    1573.00 [#/sec] (mean)
Time per request:       63.573 [ms] (mean)
Time per request:       0.636 [ms] (mean, across all concurrent requests)
Transfer rate:          284.18 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.9      0       4
Processing:     0   58  16.9     60     195
Waiting:        0   56  13.1     60     159
Total:          1   58  16.5     61     195

Percentage of the requests served within a certain time (ms)
  50%     61
  66%     63
  75%     63
  80%     64
  90%     66
  95%     68
  98%     71
  99%    134
 100%    195 (longest request)

まとめ

既存サービスではgojiを使っているのですが機能があっさりしているので、 そこそこ機能もあって高速なEcho使ってみても良いなという感想でした。