- upstream资源释放(ngx_http_upstream_finalize_request)
- 调用u->peer.free释放上游TCP连接,详见upstream文档;
- 删除上游响应的文件缓存;
- 发送r->out中缓存的内容。
无论是non_buffer或pipe进行上游响应的发送,都使用r->pool分配的内存(u->buffer/u->pipe->free_raw_bufs)保存上游响应,所以,虽然开始已经对上游进行了释放,但仍可以对响应进行发送。
- 请求完成回调(ngx_http_finalize_request)
该函数不代表请求的结束和释放,更合适的解释是,根据参数类型,决定对请求如何做进一步处理。参数类型有三种:
- 正常的nginx返回值类型,如NGX_OK、NGX_DONE、NGX_DECLINED。
- 下游连接异常类型,如NGX_ERROR、NGX_HTTP_REQUEST_TIME_OUT、NGX_HTTP_CLIENT_CLOSED_REQUEST,此时强制释放连接;
- HTTP响应码,如NGX_HTTP_SPECIAL_RESPONSE、NGX_HTTP_CREATED、NGX_HTTP_NO_CONTENT,此时需发送特定的响应类型给客户端。
关于r中的count计数:
第一个作用,当产生子请求时,增加该引用计数,保证子请求未完成的情况下r不会被释放。当不存在子请求时,该计数用来表示请求还存在其它模块需要对其进行处理,不能释放,当其它模块处理完成后,需要调用ngx_http_finalize_request,并传递NGX_DONE,使引用计数减少,这时当主请求处理结束后,r才会被真正释放。可以这样理解,count初始化为1代表主请求处理流程的引用,一般正常结束后返回NGX_OK;后续各模块对引用的增加代表各模块处理流程对主请求的引用,一般正常结束后返回NGX_DONE。
当请求包体正在读取,或者请求包体需要丢弃(ngx_http_discard_request_body)时,将count++,代表读取请求包体需要使用主请求,主请求不可释放。当请求包体读取结束后,会调用ngx_http_finalize_request(r,
NGX_DONE)已减少引用计数,使得r可以被释放。c->buffered: 当因某些原因造成响应未完全发送,即r->out还有缓存时,设置c->buffered |=
NGX_HTTP_WRITE_BUFFERED,并将下游写事件重新加入epoll。因为当上游接收结束后,就会调用ngx_http_upstream_finalize_request进行释放工作,而此时并不能保证下游没有未发送的缓存。r->buffered: 当某些模块如sub_filter仍缓存部分报文未发送时,设置r->buffered |=
NGX_HTTP_SUB_BUFFERED。
- 连接处理回调(ngx_http_finalize_connection)
根据请求状态,对请求资源和连接资源进行释放。
- 请求为长连接:
(1)对请求资源进行释放ngx_http_free_request(r, 0);
(2)对连接资源的c->buffer进行释放;
(3)对连接其它资源进行保留,设置读回调ngx_http_keepalive_handler,并重新加入epoll。 - 请求非长连接(ngx_http_close_request):
(1)对请求资源进行释放ngx_http_free_request;
(2)对连接资源进行释放ngx_http_close_connection。