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セッションはソケットキューから削除され、ファイルディスクリタに登録される(関連づけられる)

f:id:ukinau:20150101000726p:plain

maxconn

ソケットキューの長さの最大値を定義するカーネルパラメーター、128がデフォルトで定義されている。backlogでmaxconnより大きな数字を定義しても、maxconnの値が優先されます。

まとめ