我们有一个使用select()设计的网络服务器,直到上周才真正看到很多负载,并且总是习惯于500-1000 conn / s负载正常工作。然而,我们最近开始看到更高的负载(和尖峰)并且在看到套接字句柄>之后遇到了select()疯狂的问题。 FD_SETSIZE。这只会冻结服务器,选择进入一个牢不可破的循环,如果它有任何>重复超时后。 FD_SET中的FD_SETSIZE。切换到民意调查(或epoll)的选项现在不存在,我们必须坚持选择。我现在修复它的方法是增加监听队列并停止接受新连接,当我看到一个新的连接返回accept()为> = FD_SETSIZE并返回到侦听套接字上的select()。这是有效的,因为os会回收文件句柄并始终尝试提供最小的文件句柄。但缺点是,如果套接字句柄是> = FD_SETSIZE,我在调用accept()时最终会向某些连接发送RST。现在这仍然是可以接受的,因为它使服务器保持运行并且连接下降约为5%。有没有办法,我可以做到这一点,而不会删除这些连接。我不想保留所有使用过的手柄和使它太复杂的东西的数量。创建一个伪造的套接字,在调用accept之前检查它的句柄并关闭它将相当准确地估计下一步将给我的句柄。
while(max_conn_to_accept--){
SOCKET a_s = accept(..);
if(a_s >= FD_SETSIZE){
close(a_s);
return;
}
答案 0 :(得分:1)
举起FD_SETSIZE
。在编译器命令行上指定-DFD_SETSIZE=16384
。
我认为您的版本已经足够新,没有其他问题。如果在头文件中出现错误,则可能需要调整一两行。
例如,如果您看到类似这样的内容:
#undef __FD_SETSIZE
#define __FD_SETSIZE 1024
将其更改为:
#undef __FD_SETSIZE
#ifndef FD_SETSIZE
#define __FD_SETSIZE 1024
#else
#define __FD_SETSIZE FD_SETSIZE
#endif
或者如果你看到:
#define FD_SETSIZE 1024
将其更改为:
#ifndef FD_SETSIZE
#define FD_SETSIZE 1024
#endif
但是,再次,我认为你不需要改变任何东西。