2015年10月22日木曜日

Go lang Goji + Einhorn provides "graceful restart"


Goji aka WAF of Golang.
Says.
Automatic support for Einhorn, systemd, and more
Graceful shutdown, and zero-downtime graceful reload when combined with Einhorn.
Looks very pritty.
So, Let's try Goji, and graceful restart by Einhorn.

Make Goji app.
Get Goji.
$ go get github.com/zenazn/goji
Make sample goji app.
$ mkdir ~/gocode/src/goji_sample/
$ cd ~/gocode/src/goji_sample/
$ emacs sample1.go
package main

import (
 "fmt"
 "net/http"

 "github.com/zenazn/goji"
 "github.com/zenazn/goji/web"
)

func hello(c web.C, w http.ResponseWriter, r *http.Request) {
 fmt.Fprintf(w, "Hello?, %s!", c.URLParams["name"])
}

func main() {
 goji.Get("/hello/:name", hello)
 goji.Serve()
}
$ go install

Set up Einhorn and run app.
Install Einhorn with gem.
$ sudo gem install einhorn
Start Goji app with Einhorn.
$ nohup einhorn -b 0.0.0.0:8001 -c einhorn_with_goji_sample -m manual $GOPATH/bin/goji_sample >> /tmp/app.log&

It works?
Chak HTTP result via curl.
$ curl 0.0.0.0:8001/hello/aaa
Hello?, aaa!
It warks!
Check app log.
$ tail -f /tmp/app.log
[MASTER 26118] INFO: Writing PID to /var/folders/6_/n62p97qx08x53ncc8hqn5fvm0000gp/T/einhorn-einhorn_with_sample_goji.pid
[MASTER 26118] INFO: Binding to 0.0.0.0:8001 with flags []
[MASTER 26118] INFO: Launching 1 new workers
[MASTER 26118] INFO: ===> Launched 26122 (index: 0)
[WORKER 26122] INFO: About to exec ["/Users/yako/gocode/bin/goji_sample"]
2015/10/21 18:11:35.258055 Starting Goji on 0.0.0.0:8001
2015/10/21 18:11:35.258153 bind: ACKing to einhorn
[MASTER 26118] INFO: [client 2:11] client connected
[MASTER 26118] INFO: Received a manual ACK from 26122
[MASTER 26118] INFO: Up to 1 / 1 manual ACKs
[MASTER 26118] INFO: [client 2:11] client disconnected
2015/10/21 18:11:49.985358 [ore-no-MacBook-2.local/zVchqfLPzY-000001] Started GET "/hello/aaa" from 127.0.0.1:61537
2015/10/21 18:11:49.986692 [ore-no-MacBook-2.local/zVchqfLPzY-000001] Returning 200 in 367.506µs
Check process.
$ ps | grep goji
26197 ttys000    0:00.22 einhorn: ruby einhorn_with_goji_sample
26201 ttys000    0:00.01 /Users/yako/gocode/bin/goji_sample

Graceful restart Goji with Einhorn
Modify current sample app.
$ emacs sample1.go
        fmt.Fprintf(w, "Hello?, %s!", c.URLParams["name"])
->
        fmt.Fprintf(w, "Hello!!!, %s!", c.URLParams["name"])
$ go install
Run Einhorn upgrade command. this command do graceful restart Goji app.
$ einhornsh -c einhorn_with_goji_sample -e upgrade
Welcome, yako! You are speaking to Einhorn Master Process 26197 (einhorn_with_goji_sample).
This is Einhorn 0.6.4.
Upgrading smoothly, as commanded
Starting smooth upgrade from version 0...
===> Launched 26273 (index: 1)
Upgraded successfully to version 1 (Einhorn 0.6.4).
Upgrade done
$ curl 0.0.0.0:8001/hello/aaa
Hello!!!, aaa!

No error with graceful restart?
Run long time ab(Apache Bench) and then run graceful result.
$ ab -c 1 -n 10000 http://0.0.0.0:8001/hello/aaa
$ einhornsh -c einhorn_with_goji_sample -e upgrade
Chcek result of ab.
Failed requests:        0
looks fine.

Tips
How to shotdown Einhorn worker.
$  einhornsh -c einhorn_with_goji_sample -e die
Welcome, yako! You are speaking to Einhorn Master Process 26529 (einhorn_with_goji_sample).
This is Einhorn 0.6.4.
Einhorn is going down! Successfully sent USR2s to 1 processes: [26586]
$ tail -f /tmp/app.log
[MASTER 26529] INFO: [client 4:11] client connected
[MASTER 26529] INFO: Sending USR2 to [26586]
2015/10/21 19:24:57.165737 Goji received signal, gracefully stopping
2015/10/21 19:24:57.165790 Goji stopped
[MASTER 26529] INFO: ===> Exited worker 26586
[MASTER 26529] INFO: [client 4:11] client disconnected

See also.
Build and Deploy to production · Issue #105 · zenazn/goji
https://github.com/zenazn/goji/issues/105
Meet Einhorn
https://stripe.com/blog/meet-einhorn
lestrrat/go-server-starter Go port of start_server utility (Server::Starter)
https://github.com/lestrrat/go-server-starter
fvbock/endless Zero downtime restarts for golang HTTP and HTTPS servers.
https://github.com/fvbock/endless
guregu/kami web "framework" using x/net/context
https://github.com/guregu/kami
facebookgo/grace Graceful restart for Go servers.
https://github.com/facebookgo/grace
dcu/http-einhorn
https://github.com/dcu/http-einhorn
Top image form Panagiotis Giannakopoulos