久しぶりにGo言語の話題です。GoのWebフレームワークGinのパフオーマンス向上にも貢献したといわれる軽量ライブラリhttprouterを試してみました。
Gin Framework: https://github.com/gin-gonic/gin
参考) https://tech.librastudio.co.jp/entry/index.php/2018/08/24/post-1937/
テストのケースとしては、アクセスカウンタ、シェルコマンドの実行、バラメータ渡しです。
パラメータ渡しでは10秒ウェイトをかけてリクエストがマルチスレッドで実行されていることを確認しました。
アクセスカウンタは、セッション管理していないため違うクライアントと共有します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package main import ( "fmt" "net/http" "log" "os/exec" "bytes" "time" "github.com/julienschmidt/httprouter" ) func getCommandOutput(command string, arguments ...string) string { cmd := exec.Command(command, arguments...) var out bytes.Buffer var stderr bytes.Buffer cmd.Stdout = &out cmd.Stderr = &stderr err := cmd.Start() if err != nil { log.Fatal(fmt.Sprint(err) + ": " + stderr.String()) } err = cmd.Wait() if err != nil { log.Fatal(fmt.Sprint(err) + ": " + stderr.String()) } return out.String() } var cnt int func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprintf(w, "Welcome! %d", cnt) cnt += 1 } func Version(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { fmt.Fprint(w, getCommandOutput("/usr/bin/go", "version")) } func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { fmt.Fprintf(w, "hello, %s! (%s)\n", ps.ByName("name"), ps.ByName("id")) time.Sleep(10 * time.Second) } func main() { router := httprouter.New() router.GET("/", Index) router.GET("/ver", Version) router.GET("/hello/:name/:id", Hello) log.Fatal(http.ListenAndServe(":8080", router)) } |
簡易Webサーバの類は、ruby、pythonなどもありますが、実用という点では後発ということもありGoが優れている気がします。
実用というのはどういう観点かというと、古くはJavaのサービスはTomcatでつくって、フロントエンドはApacheというように、アクセス制御や耐障害性など、実際にインターネットに公開して使って大丈夫かということだと思います。
まだ根拠は示せませんが、いろいろな利用ケースから、そのように感じているところです。