nginx: too many open files

模块快开发完了,日志中出现了这个东东,看样子是文件描述符耗尽了,

但是奇怪的是,nginx一直halt在sigsuspend上,并且简单的返回静态页面是木有问题的,

看来是模块有bug,

从表现上看,像是建立的连接没有得到及时的释放,所以accept报告打开文件过多。

应该是在返回结果的部分,先加上ngx_http_finalize_request(r,NGX_OK)试试,

搞定。

 

 

做了点实验看了些源码,印证了自己的猜想。

对于get方法,send header+output_filter 就可以结束一次请求,因为GET方法是同步的,nginx会在handler返回之后的步骤中关闭链接,但对于post方法,由于nginx是使用异步的方式处理post数据,因此必须显式的关闭链接。

 

nginx的content handler同步返回后会调用ngx_http_finalize_request,在这个函数里,如果handler返回值为ngx_done则会直接ngx_http_finalize_connection,但后者并非如其名字那样结束一个连接,如果开启了keepalive,那么这个函数结束的是这次请求,而并非关闭连接。何时启用keepalive由客户端决定,如果客户端的版本大于1.0或者在header中指定只用keepalive,则r的keepalive标记位置为1,表明启用keepalive,如果nginx也开启了keepalive支持,则在此次请求结束后,客户端未关闭连接的情况下,此连接依然存在。

 

对于异步调用的post方法而言,post_handler是实际生成并返回http content的最后一步,如果返回码不是属于NGX_HTTP_SPECIAL_RESPONSE,那么,finalize_request的责任在posthandler自身,nginx不会在post_handler之后调用ngx_http_finalize_request结束请求关闭连接,所以如果你的content handler在post方法中处理请求,那么一定要记得ngx_http_finalize_request,否则,就会出现 accept too man open files。

posted @ 2012-10-08 18:28  donj  阅读(654)  评论(0编辑  收藏  举报