代码之家  ›  专栏  ›  技术社区  ›  J.C. Inacio

简单的TCP服务器使用select(),为什么“最长请求”这么高?

  •  3
  • J.C. Inacio  · 技术社区  · 16 年前

    我正在使用select()方法实现一个简单的TCP服务器-一切都很好,性能也很好,但是当与ab(apachebench)进行基准测试时,“最长请求”比平均时间高得离谱:

    我正在使用: ab -n 5000 -c 20 http://localhost:8000/

    片段:

    Requests per second:    4262.49 [#/sec] (mean)
    Time per request:       4.692 [ms] (mean)
    Time per request:       0.235 [ms] (mean, across all concurrent requests)
    
    Percentage of the requests served within a certain time (ms)
      50%      2
      66%      2
      75%      2
      80%      2
      90%      2
      95%      3
      98%      3
      99%      4
     100%    203 (longest request)
    

    对阿帕奇也是如此:

    Requests per second:    5452.66 [#/sec] (mean)
    Time per request:       1.834 [ms] (mean)
    Time per request:       0.183 [ms] (mean, across all concurrent requests)
    
    Percentage of the requests served within a certain time (ms)
      50%      1
      66%      2
      75%      2
      80%      2
      90%      3
      95%      3
      98%      4
      99%      4
     100%      8 (longest request)
    

    作为参考,我使用流选择,并且套接字是非阻塞的。

    这是使用select()调用的常见效果吗?
    我有什么需要考虑的性能因素吗?

    更新:

    当使用并发值<=6时,最长的请求是“正常”的(大约是平均值的2倍或3倍),但高于6的任何请求都会变得疯狂(例如,7个并发请求可能以20为基准,或大约200毫秒)。

    更新2:

    将流函数替换为等效的套接字函数,并进行适当的测试/基准测试之后,问题就不再出现了——因此,我将把这种行为归因于流的PHP实现中一些模糊的细节。

    3 回复  |  直到 16 年前
        1
  •  1
  •   Keith Randall    16 年前

    200毫秒听起来像是一个时间量表。

    只是要确定一下,您使用的是空或非零的选择超时?您是否正在写入只准备读取的套接字,或者相反?在再次调用select之前,是否处理select返回的每个fd?很高兴看到一些代码…

    我认为如果您在测试本地主机,它就不会是网络。但是Reinier是对的,它看起来很像你会看到是否有一些TCP重传(在相当现代的Linux中,200毫秒是最小的TCP重传超时)。

        2
  •  1
  •   Toad    16 年前

    您可以使用wireshark或其他嗅探器来跟踪TCP IP流量。这样,您就可以看到问题是否与低级问题有关(重传、数据包丢失等)

        3
  •  0
  •   caf    16 年前

    由于99%的请求只在4ms内完成,这可能会涉及一次性成本,例如DNS查找或从磁盘交换大量代码。

    推荐文章