关于listen的backlog

1.  Listen的backlog是为了限制服务端半连接队列和全连接队列的长度。在系统中有三个地方可调节:

  1)  listen(fd, backlog)

  2)  /proc/sys/net/core/somaxconn

  3)  /proc/sys/net/ipv4/tcp_max_syn_backlog

  内核文档中的解释:

  a) somaxconn:  Limit of socket listen() backlog。

  b) tcp_max_syn_backlog:      Maximal number of remembered connection requests, which have not received an acknowledgment from connecting client.

  简而言之, somaxconn限定了listen中backlog的参数, 而tcp_max_syn_backlog决定了半连接队列的最大值。

2. 实验。 使用systemtap编写:

kinwin@tencent-king:/data2/linux-3.4$ cat /data/systemtap/listen.stp

 

probe begin {

  printf("inet listen Monitoring Started...\n")

}

 

probe kernel.function("inet_listen").return

{

    accept_backlog = $backlog

    recvq_backlog = @cast($sock->sk, "inet_connection_sock")->icsk_accept_queue->

            listen_opt->nr_table_entries

    printf("%-20s:accept backlog is %d, syn backlog is %d.\n", execname(),accept_backlog, recvq_backlog)

}

 1)       listen(128), somaxconn 128, tcp_max_syn_backlog 128

   listen              :accept backlog is 128, syn backlog is 256.

2)       listen(127), somaxconn 128 tcp_max_syn_backlog 128

  listen              :accept backlog is 127, syn backlog is 128.

3)       listen(256), somaxconn 128 tcp_max_syn_backlog 128

listen              :accept backlog is 128, syn backlog is 256.

4)       listen(1024), somaxconn 1024, tcp_max_syn_backlog 256

  listen              :accept backlog is 1024, syn backlog is 512.

问题? 实际syn backlog值都超过了设定的tcp_max_syn_backlog. why?

在实际决定半连接队列长度的代码逻辑中:

  nr_table_entries = min_t(u32, nr_table_entries, sysctl_max_syn_backlog);

  nr_table_entries = max_t(u32, nr_table_entries, 8);

  nr_table_entries = roundup_pow_of_two(nr_table_entries + 1);

     会对原始值进行加一,并向上取二的次幂的操作。因此即使是max_syn_backlog,也会被操纵为2*max_syn_backlog。但这里逻辑显然是和内核文档中“Maximal number of remembered connection requests”不符的。

posted on 2012-10-17 15:56  FengK  阅读(857)  评论(0编辑  收藏  举报

导航