地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Nginx】SO_REUSERPORTが使えた

nginx 1.9.1 からの新機能で、 SO_REUSEPORT というソケットのオプションを有効化することができるようになってたらしい。

qiita.com

この機能は複数のソケットを同じポートにバインドするという機能で443を複数プロセスでバインドして使うみたいに使える。複数プロセスで一つのポートをバインドして何が嬉しいんだって話はNginxみたいにepollでソケットを監視しているケースでSO_REUSERPORTが有効でない場合は全てのプロセスがepoll_waitから戻り早い者勝ちでaccept(2)が成功するみたいな動きになります。SO_REUSERPORTが有効だとカーネルは SO_REUSEPORT が有効なソケットに対してコネクションを一つだけに選択し通知を行うようになります。なのでepoll_wait(2)から戻るプロセスは一つになるという仕組みです。

ちなみにカーネル自体に機能が入ったのはなんとちょうど8年くらい前らしいです。

lwn.net

QUICとかの記事でも登場したるするらしい。

medium.com

とりあえずonしておけばパフォーマンス上がりそうなパラメータに見えますが副作用もあるので注意が必要。(クイズ入りのわかりやすい解説があったので貼っておきます。)

https://linuxplumbersconf.org/event/11/contributions/946/attachments/783/1472/Socket_migration_for_SO_REUSEPORT.pdf

EPOLLEXCLUSIVEが入ったカーネルじゃないとaccept-queueに入ってるコネクションが全て破棄されてしまうというものでEPOLLEXCLUSIVEはちょっと新目のカーネルが必要になる。

dsas.blog.klab.org

さらに見てたらnet.ipv4.tcp_migrate_reqというカーネルパラメータがより新目のカーネルには入るらしい。読んでみた感じ異なるリスナー間のコネクションの移行を有効にするように読めた。(他にも知らないパラメータが多く出てきたので別の機会に読んでみる)

patchwork.kernel.org