Backlogってなんぞや
はじめに
サーバソフトウェアの設定ファイル等でよく見かける項目であるBacklogってどういう意味なんだろうと、少し調べたのでメモを残します。
Backlog
apacheやnginx、memchachedなどのサーバ系ソフトウェアの設定ファイルの中で設定することが多い、このBacklogとは何なのかをここでは言及する。
サーバアプリケーションがlistenしているソケットがacceptしていない、確立済TCPセッションを何個までOS側で保持するかを定義したもの。
例えば、下記のようなサーバーアプリケーションがあるとする。
server.py
import evenlet server_sock = eventlet.listen(('0.0.0.0', 6001),backlog = 1) new_sock, address = server_sock.accept() new_sock1, address = server_sock.accept() while True: a = 1 print("ここは到達しないコード")
上記のサーバアプリケーションに、5個の接続要求(telnetとかを使って)を出すと。3個目までTCPコネクションが確立され、4,5個目の接続要求は無視される。
netstatで確認してみると、下記のようになる。
$netstat -an | grep 6001 tcp4 0 0 127.0.0.1.52608 127.0.0.1.6001 SYN_SENT tcp4 0 0 127.0.0.1.52607 127.0.0.1.6001 SYN_SENT tcp4 0 0 127.0.0.1.6001 127.0.0.1.52601 ESTABLISHED tcp4 0 0 127.0.0.1.52601 127.0.0.1.6001 ESTABLISHED tcp4 0 0 127.0.0.1.6001 127.0.0.1.52600 ESTABLISHED tcp4 0 0 127.0.0.1.52600 127.0.0.1.6001 ESTABLISHED tcp4 0 0 127.0.0.1.6001 127.0.0.1.52599 ESTABLISHED tcp4 0 0 127.0.0.1.52599 127.0.0.1.6001 ESTABLISHED tcp4 0 0 *.6001 *.* LISTEN
コードを見てもらうと分かる通り、サーバ(server.py)では2回しかacceptされていないが、netstatでは下記の3つセッションが確立できていることが分かる(ESTABLISHED)
これは、server.pyからは2つのコネクションしか見えていないが、残りの1つのセッションはOS側で保持してくれていることが分かる、この何個のセッションをOS側で面倒見るかを定義したものがbacklogである。
今回は、backlog=1でサーバソケットをlistenしているため3個目のリクエストはセッションが確立されたが4、5個目のリクエストはクライアントからSYNパケットを送っているが、サーバに無視されている。
これらの挙動を図にまとめるとこんな感じになる。注目していただきたいのは下記の点
- ソケットキューの大きさがbacklog数
- ソケットキューは、サーバソケットごと(=port)ごとに作成される
- accept()システムコールが呼ばれると、確立済のTCPセッションはソケットキューから削除され、ファイルディスクリタに登録される(関連づけられる)
maxconn
ソケットキューの長さの最大値を定義するカーネルパラメーター、128がデフォルトで定義されている。backlogでmaxconnより大きな数字を定義しても、maxconnの値が優先されます。