unixドメインソケット

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

目次

unixドメインソケットとは

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

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

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

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

GoサーバーとNginxとの接続

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

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

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, 0777); err != nil {
	e.Logger.Fatal(err)
}

e.Listener = l
e.Logger.Fatal(e.Start(""))

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

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

本番環境では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ドメインソケット名前しか知らなかった。
使い方とその利点がわかって満足。

この記事が参考になったからコーヒーくらいおごってもいいぜという方は、以下からサポートいただけると次の記事書くモチベになりますのでよろしくお願いします

Buy Me A Coffee

参考

kasei_sanのブログ
UnicornとNginxの接続方法は、UNIXドメインソケットとリバースプロキシの2つの方法がある - kasei_sanのブ... UNIXドメインソケット 単一マシン上の高効率なプロセス間通信に用いられる機能・インターフェースの一種である UNIXドメインソケット - Wikipedia ファイルシステムを介し...
Qiita
DockerのContainer linkとUnix Domain Socket、どっちのほうが速い? - Qiita 概要Dockerのコンテナ間通信の方法としてContainer LinkVolume経由のUnix Domain Socketといった方法がありますが、どっちの方が速いのか調べてみましたT…
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次