sunabox

unixドメインソケット

Nginxとアプリケーションサーバーの接続でunixドメインソケットが使われていた。
実務でこれまでこの辺のミドルウェアは触れることがなかったのでいい勉強になったということで軽くまとめておく。

unixドメインソケットとは

通常のソケット通信はネットワークを介してプロセス間通信を行うのに対し、unixドメインソケットはファイルシステムを介してプロセス間通信を行うもの。

カーネル内部で完結するため、ネットワーク経由の場合と比較して非常に高速であるが、外部インターフェースへの接続はできない。
そのため、接続するものは同一ホスト上に存在する必要がある。

複数コンテナ間で通信する際もdockerのContainer link使うよりunixドメインソケット使った方が高速らしい。

DockerのContainer linkとUnix Domain Socket、どっちのほうが速い? - Qiita概要Dockerのコンテナ間通信の方法としてContainer LinkVolume経由のUnix Domain Socketといった方法がありますが、どっちの方が速いのか調べてみましたT…
faviconqiita.com

GoサーバーとNginxとの接続

今回はGoのサーバーとNginxをunixドメインソケットを使って接続した

詳細は省くが、nginxの設定ファイルで以下のように記述することで、接続用のファイルを/tmp/go.sockに配置する。

nginx.conf
upstream go {
  server unix:/tmp/go.sock fail_timeout=0;
}

go側の記述でこの/tmp/go.sockをlistenするように記述する。
今回はフレームワークとしてechoを使った。

socket_file := "/tmp/go.sock"
l, err := net.Listen("unix", socket_file)
if err != nil {
	e.Logger.Fatal(err)
}
 
if err := os.Chmod(socket_file, 0744); err != nil {
	e.Logger.Fatal(err)
}
 
e.Listener = l
e.Logger.Fatal(e.Start(""))

net.Listenunixとしてソケットファイルを渡してやればよい。
それをlistenerとして登録して起動させるのみ。
ファイルの実行権限を与える必要があるので744を設定している。

開発時はポートで接続する

本番環境ではnginxを使って接続をするが、開発環境では直接ポートを使って接続したい。
なので環境変数を使ってこれらを振り分けるようにした。
先程のソケット通信の処理の前に以下の処理を追加するだけ。
あとは開発時はGO_ENVにdevelopmentを渡してサーバーを起動させるだけでok

if os.Getenv("GO_ENV") == "development" {
	e.Logger.Fatal(e.Start(":1323"))
}

実際の起動の様子がこちら。

// portで接続した場合
⇨ http server started on [::]:1323
 
// unixドメインソケットで接続した場合
⇨ http server started on /tmp/go.sock

ログでもちゃんと立ち上げ方が変わっているのがわかる。

まとめ

unixドメインソケット名前しか知らなかった。
使い方とその利点がわかって満足。

参考

https://blog.kasei-san.com/entry/2020/09/02/175828
DockerのContainer linkとUnix Domain Socket、どっちのほうが速い? - Qiita概要Dockerのコンテナ間通信の方法としてContainer LinkVolume経由のUnix Domain Socketといった方法がありますが、どっちの方が速いのか調べてみましたT…
faviconqiita.com
Buy Me A Coffeeのbutton

目次