Hello!
2014-04-19 1:02 GMT-07:00 Pahud Hsieh:
> 所以ngx.eof()之後,如果還有一些工作還沒處理完,此時http client會收到last chunk, 再加上nginx set
> keepalive不為0的話,這樣server/client會保持這個僵持的狀態一段時間,這期間client完全無法re-use這個HTTP
> conn,最後server會收到client發起的TCP
> close請求,於是server就會變成CLOSE_WAIT狀態,但server卻不會發起ACK給client,這樣情況連續發生的適合就可能就會有大量的CLOSE_WAIT佔用socket,是否可以這樣理解?
>
这取决于你在 ngx.eof() 之后执行的任务的耗时。当此耗时超过客户端的读取超时时,会带来 CLOSE_WAIT
状态的连接,直到你的任务完成,nginx 尝试读取当前连接上的下一个请求时才会注意到客户端已经关闭连接,从而清理这个 CLOSE_WAIT
状态的连接。
> 如果是的話,把keepalive設為0,是否表示即便ngx.eof()之後還沒處理完後台工作,也會立即active
> close主動對client斷開,避免大量TCP的佔用?
>
这依赖于客户端主动关闭连接。如果客户端实现得不好或者是故意不主动关闭连接,这也会造成连接不必要地长时间的保持着,造成服务器端的资源浪费。
> 自己異步進行buffering/aggregate的設計很不錯,但我還是好奇想知道,ngx.timer.at()
> 丟給timer處理的時候,是否有辦法設定timeout? 例如這個func執行超過30s不管有沒有執行完必須立刻被terminate,並且產生error
> log?
你为什么不对你的任务本身的 IO 操作设置合理的超时保护?比如 cosocket API 就提供了 settimeout()
方法设置超时。我先前给你参考的 lua-resty-logger-socket 库也提供了超时选项。
> 否則感覺丟給timer之後這些running timer幾乎無法控制了,
> 只能等待lua_max_running_timers滿造成後續的error。或者有什麼更好的設計思路可以防範這問題發生?
>
我已经给了 lua-resty-logger-socket
库作为参考。你可以查看它是如何作并发控制的。lua-resty-logger-socket 库并不会对每个请求都不加区别地创建新的
timer,只有在它的批处理任务积累到一定阈值时才会创建 timer 尝试进行操作。同时它也会确保一个时间只有一个批处理任务在实际执行。
Regards,
-agentzh