nginx加载lua模块log resp_body过大导致的问题

nginx在输出log的时候默认是不支持输出response body的,但是在开发的过程中,为了快速定位问题原因,需要将该字段输出,目前网络上可以搜到的方法就是使用lua模块获取response body字段输出到nginx log当中去,在实际使用过程中发现,当传送数据过大时,例如response数据有10M+时,直接请求server或者nginx直接proxy到server的情况下,速度非常快不足1s就返回了。但是如果在打开配置获取response body的情况下nginx在传输时会变得异常缓慢,nginx的io被卡住了!!并且在传输到6s的时候会断开连接,当时大家都以为是lua模块的限制,因为之前有开发nginx anti模块的经验,于是就让看看这块儿,当时以为又要写c代码了还有一些小激动呢,但是得先定位原因吗,于是直接将nginx的日志leverl配置成debug,结果一个请求输出了2w行。。。没办法于是将lua配置关闭记录了同样的一段请求,然后两个error_log 比较着看,最后发现最后请求关闭的时候,打开lua的情况下是502状态码,上有断开了,但是关闭lua的情况下是0正常结束,于是定位了原因是由于传输时间过长导致的异常断开,需要上游server将自己的超时时间重新配置一下,将默认的5s修改为60s之后问题解决。

这次问题的根本原因是上游server的超时时间设置过段,因此当传输速度有限的情况下超过了配置中的时间之后就会主动断开连接,而nginx本身速度不存在问题,但是由于开启了lua模块获取response body导致卡住了io,触发了这个问题。

nginx lua配置如下:

<span class="pln">lua_need_request_body on</span><span class="pun">;</span>
    <span class="kwd">set</span><span class="pln"> $resp_body </span><span class="str">""</span><span class="pun">;</span><span class="pln">
    body_filter_by_lua </span><span class="str">'
        local resp_body = string.sub(ngx.arg[1], 1, 1000)
        ngx.ctx.buffered = (ngx.ctx.buffered or "") .. resp_body
        if ngx.arg[2] then
             ngx.var.resp_body = ngx.ctx.buffered
        end
    '</span><span class="pun">;</span>

ps:官方文档显示 nginx log等级总共有如下几种:debug, info, notice, warn, error (default), crit, alert, emerg