确定TCP listen()队列中当前的积压连接数

时间:2012-06-20 19:00:39

标签: python linux sockets tcp twisted

有没有办法找出在Linux上的TCP套接字上等待accept()的当前连接尝试次数?

我想我可以计算在每个事件循环上点击EWOULDBLOCK之前成功的accepted()的数量,但是我使用的是隐藏这些细节的高级库(Python / Twisted)。它也使用epoll()而不是老式的select()/ poll()循环。

我试图了解高性能无阻塞网络服务器的负载情况,我认为这个数字很好。负载平均值/ CPU统计数据没有多大帮助,因为我在并发工作进程中执行了大量磁盘I / O. Linux上的大多数这些统计数据都计算在磁盘I / O上等待加载的一部分时间(对于我的特定服务器体系结构,它不是这样)。 accept()和响应之间的延迟也不是一个好的措施,因为一旦服务器到达它,每个请求通常会很快得到处理。我只是想弄清楚我是多么接近一个突破点,服务器无法以比进入更快的速度发送请求。

3 个答案:

答案 0 :(得分:2)

在我见过的BSD套接字API中没有这个功能。我怀疑它是否真的是一个有用的负载量度。您假设客户端没有连接池,一方面,您也假设延迟完全表现为挂起连接。但是,无论如何你都无法得到这个数字,这一点是没有意义的。

答案 1 :(得分:2)

假设SYN cookie没有启用(或者由于音量没有被触发),我认为你应该能够通过检查netstat的输出并查看针对你的端口的连接数量来获得一个近似的数字。一个SYN_RECV状态。

这是一个小的Python黑客,它会为你提供给定侦听端口的数字:

!/usr/bin/python

import sys

STATE_SYN_RECV = '03'

def count_state(find_port, find_state):
    count = 0
    with open('/proc/net/tcp', 'r') as f:
        first = True
        for line in f:
            if first:
                first = False
                continue
            entries = line.split()
            local_addr, local_port = entries[1].split(':')
            local_port = int(local_port, 16)
            if local_port != find_port:
                continue
            state = entries[3]
            if state == find_state:
                count += 1
    return count


if __name__ == '__main__':
    if len(sys.argv) != 2:
        print "Usage: count_syn_recv.py <port>"
        sys.exit(1)

    port = int(sys.argv[1])

    count = count_state(port, STATE_SYN_RECV)
    print "syn_recv_count=%d" % count

答案 2 :(得分:2)

您可以查看unacked输出中的ss值,例如在检查端口80时:

ss -lti '( sport = :http )'

输出可能如下所示:

State  Recv-Q  Send-Q  Local Address:Port  Peer Address:Port   
LISTEN    123      0              :::http               :::*
    rto:0.99 mss:536 cwnd:10 unacked:123

有关unacked确实是TCP连接积压的详细证明(包含内核源和所有内容),请参阅详细文章"Apache TCP Backlog" by Ryan Frantz。请注意,您可能需要一个全新版本的ss才能包含unacked输出。至少我的(iproute2-ss131122)没有提供它。