【问题标题】:Determine the current number of backlogged connections in TCP listen() queue确定 TCP listen() 队列中的当前积压连接数
【发布时间】:2012-06-22 23:48:25
【问题描述】:

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

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

我试图大致了解高性能非阻塞网络服务器上的负载,我认为这个数字将是一个很好的表征。平均负载/CPU 统计数据没有多大帮助,因为我在并发工作进程中执行了大量磁盘 I/O。 Linux 上的这些统计数据中的大多数都将等待磁盘 I/O 所花费的时间计算为负载的一部分(对于我的特定服务器架构,它不是)。接受()和响应之间的延迟也不是一个好的衡量标准,因为一旦服务器处理每个请求,通常会很快得到处理。我只是想知道我离服务器无法以比它们进来的速度更快的速度发送请求的临界点有多近。

【问题讨论】:

    标签: python linux sockets tcp twisted


    【解决方案1】:

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

    【讨论】:

    【解决方案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
    

    【讨论】:

    • 这不会满足他的要求。 listen(2) 积压队列中的连接已完成 (SYN-SYN/ACK-ACK),而不是处于 SYN_RECV 状态。这些人还有另一个队列。
    • 一旦监听积压被填满,它们仍然在我的 Linux 服务器上列为 SYN_RECV - 至少,这是我在编写一个调用 listen() 但从不调用 accept() 的小服务器后发现的 -如果我调用listen(fd, 3)并打开6个连接,我会看到3个处于ESTABLISHED状态,3个处于SYN_RECV
    • 他要求的是当前积压队列中的连接数,即accept()会立即返回而不会阻塞的连接数:在你的测试用例中, 3 个已建立的。
    • 啊是的..好点..真的没有其他价值潜伏在某个地方会有所帮助吗?感谢您抽出宝贵时间发表评论
    • 投了赞成票,因为即使它没有按照原始问题的要求做,但它确实做到了我想要的 :) 谢谢!
    【解决方案3】:

    您可以查看ss 的输出中的unacked 值,例如在检查端口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) 没有提供。

    【讨论】:

    • 链接有错字,这是正确的one:
    • @rags:已修复。谢谢!
    猜你喜欢
    • 2020-01-30
    • 2016-08-04
    • 2013-08-09
    • 2017-01-22
    • 2011-07-05
    • 2016-06-09
    • 2018-07-18
    • 1970-01-01
    • 2021-12-19
    相关资源
    最近更新 更多