Open karszawa opened 6 years ago
nginxとアプリケーションの間の通信をTCP/IP通信からUnix Domain Socketに置き換える
Unix Domain Socketは同一ホスト内での通信を高速に行うことができる。 Webサービスの場合は、Webサーバーとアプリケーションの間の通信を高速化するために利用できる。 (nginxの場合はTCP/IP通信を用いてWebサーバー/アプリケーション間の通信を行っている場合がある)
http { upstream app { server unix:/tmp/nginx.sock; } }
ハンドラ登録後、unixソケットを介してリッスンする
func main() { mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("<h1>It works!</h1>\n")) }) listener, err := net.Listen("unix", "/tmp/nginx.sock") if err != nil { log.Fatalf("error: %v", err) } defer func() { if err := listener.Close(); err != nil { log.Printf("error: %v", err) } }() shutdown(listener) if err := http.Serve(listener, mux); err != nil { log.Fatalf("error: %v", err) } } // 割り込み終了処理 func shutdown(listener net.Listener) { c := make(chan os.Signal, 2) signal.Notify(c, os.Interrupt, syscall.SIGTERM) go func() { s := <-c if err := listener.Close(); err != nil { log.Printf("error: %v", err) } os.Exit(1) }() }
サーバーにGorillaを採用している場合は、mux.NewRouter()の返り値をhttp.Serveのmuxの値に突っ込む。
現在/tmp以下に作成したunix domain socketを使用するのは出来ないらしいので適当に/var/lib/appディレクトリみたいなのを作ってそこにunix domain socketを配置する。
goのapp起動時に使用するunix domain socketが既に存在すると起動できない -> systemdによってテンポラリなディレクトリを作成する。 方法は、まずtmpfilesを作成するための設定を追加する。
cat /etc/tmpfiles.d/webapp.conf d /var/run/webapp 0777 [UID] [GID] -
ほんで、以下のコマンドで起動時のtmpディレクトリの作成を設定する。
$ systemd-tmpfiles --create /etc/tmpfiles.d/webapp.conf $ systemctl daemon-reload
作成されるunix domain socketにデフォルトだとnginxがアクセス出来ないため、アクセス権の変更を行ってやる必要がある。 -> どうしようか.... わからないからとりあえず、サーバーの起動時にchmodして対処するか...って感じ... どうやるのが正解なんだろう?
listener, err := net.Listen("unix", "/var/run/webapp/webapp.sock") os.Chmod("/var/run/webapp/webapp.sock", 0666) http.Serve(listener, r)
みたいに、socketのListenをして、http.Serveがはじまる前にパーミッションを変更すればいけるみたい。
あとはnginx.confのいっちばん上に
user isucon;
と記述するという手もある(ここでisuconはunix domain socketを生成するユーザー名)
gojiについては実行時引数の--bindに/var/run/webapp/webapp.sockを設定してあげればunix domain socketを用いることができる。
なにをやるか
nginxとアプリケーションの間の通信をTCP/IP通信からUnix Domain Socketに置き換える
なぜやるか
Unix Domain Socketは同一ホスト内での通信を高速に行うことができる。 Webサービスの場合は、Webサーバーとアプリケーションの間の通信を高速化するために利用できる。 (nginxの場合はTCP/IP通信を用いてWebサーバー/アプリケーション間の通信を行っている場合がある)
どうやるか
/etc/nginx/nginx.conf
Application
ハンドラ登録後、unixソケットを介してリッスンする
注意点
サーバーにGorillaを採用している場合は、mux.NewRouter()の返り値をhttp.Serveのmuxの値に突っ込む。
現在/tmp以下に作成したunix domain socketを使用するのは出来ないらしいので適当に/var/lib/appディレクトリみたいなのを作ってそこにunix domain socketを配置する。
goのapp起動時に使用するunix domain socketが既に存在すると起動できない -> systemdによってテンポラリなディレクトリを作成する。 方法は、まずtmpfilesを作成するための設定を追加する。
ほんで、以下のコマンドで起動時のtmpディレクトリの作成を設定する。
作成されるunix domain socketにデフォルトだとnginxがアクセス出来ないため、アクセス権の変更を行ってやる必要がある。 -> どうしようか.... わからないからとりあえず、サーバーの起動時にchmodして対処するか...って感じ... どうやるのが正解なんだろう?
みたいに、socketのListenをして、http.Serveがはじまる前にパーミッションを変更すればいけるみたい。
あとはnginx.confのいっちばん上に
と記述するという手もある(ここでisuconはunix domain socketを生成するユーザー名)
gojiについては実行時引数の--bindに/var/run/webapp/webapp.sockを設定してあげればunix domain socketを用いることができる。