我正在使用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)
和apache一样:
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)
作为参考,我使用的是stream_select,套接字是非阻塞的。
这是使用select()调用的常见效果吗?
我应该担心有哪些性能方面的考虑因素?
更新
当使用并发值< = 6时,最长的请求是“正常”(大约是平均值的2倍或3倍),但是6以上的任何内容都会变得疯狂(例如,7个并发请求可能会以20为基准进行基准测试,或大约200ms)。
UPDATE2:
在用等效的套接字函数替换流函数和一些正确的测试/基准测试之后,问题不再发生 - 所以我将这个行为归结为关于流的PHP实现的一些模糊细节。
答案 0 :(得分:1)
您可以使用wireshark或其他嗅探器来跟踪tcp-ip流量。通过这种方式,您可以查看问题是否与低级别问题(重新传输,数据包丢失等)有关。
答案 1 :(得分:1)
200ms听起来像是一个调度时间量。
为了确保您选择使用NULL或非零超时?您是在写入仅准备读取的套接字,反之亦然?您是否在再次调用select之前处理每个选择返回的fd?看到一些代码会很高兴......
如果您正在测试localhost,我认为它不会是网络。但是,如果有一些TCP重传(200ms是一个相当现代的Linux中最小的TCP重传超时),它看起来很像你所看到的。
答案 2 :(得分:0)
由于99%的请求仅在4毫秒内完成,这往往会影响一次性成本,例如DNS查找或从磁盘交换大量代码。