[原创]nginx写日志时机与tcp write写成功是否送达对端疑问解析

  • 时间:
  • 浏览:8

意味直接调用-->

前些天和另内外部门的同事在排查还还有一个网络什么的疑问, 问到nginx日志中成功记录了http 150响应码可不里都都能能 证明响应数据就达到了对端? 你这一 什么的疑问涉及nginx在做server功能时写日志是在什么时机? 是client端收到响应数据后才生成, 还是nginx丢出数据就生成了而不管与否 client端收到数据?

** 在tcp_write_xmit()中会逐步检查本端的拥塞窗口(拥塞控制算法不断的在调整)设置与否 有配额cwnd_quota可不里都都能能 发送报文? 配额缺陷则经常老出;

协议栈缓存数据的发送通过以下十多少 函数负责:

通过ngx_http_output_filter()发送响应数据给client

ngx_http_write_filter()会调用c->send_chain()往客户端发送数据,c->send_chain()的取值

在不同操作系统,编译选项以及协议下(https下用的是

ngx_ssl_send_chain)会取不同的函数,典型的Linux操作系统下,它的取值为ngx_linux_sendfile_chain(),你这一 函数中使用rc = writev(c->fd, header.elts, header.nelts);发送数据;

-->ngx_http_free_request()

应用层发送数据时调用TCP数据发送函数可不里都都能能 是write、send、sendmsg 你这一 个函数参数中携带可不里都都能能 发送的数据,最终在内核层面全是通过调用__sock_sendmsg()实现,对TCP数据来说__sock_sendmsg()函数中会再调用tcp_sendmsg(); 而tcp_sendmsg()函数中根据现有的TCP缓存与否 足够会选着将应用层的数据克隆qq好友好友到sk_buff中,克隆qq好友好友完成的sk_buff挂入到sk_write_queue 队列尾部停留发送; 你这一 流程的代码中用copied变量代表了真实从应用层意味拷贝到sk_buff中的数据量,下边会走真正的TCP发送流程。但不管下边的流程可不里都都能能 真正的发送出去数据,会返回你这一 copied到应用层代表写入成功的数量; 而协议栈缓存数据的发送就由大家所熟知的TCP可靠传输机制去保证到达对端了。

这里定义为数据拷贝到协议栈缓存和缓存数据发送还还有一个阶段。

原创文章:来自nginx写日志时机与tcp write写成功与否 送达对端什么的疑问解析

做上层应用的人员一般对底层网络偏离 研究的较少,另外针对应用层调用write写TCP数据并返回写入的字节数就认为成功到达了对端你这一 什么的疑问什么都人趋于稳定误解。涉及的nginx发出响应防止流程和linux系统TCP的防止过程,,简要解释如下:

意味能通过以上等的限制则调用tcp_transmit_skb()真正的执行发送数据。

-->tcp_push()

-->tcp_write_xmit()

-->ngx_http_close_request()

-->ngx_http_terminate_request()强制开使英文请求

综合所述TCP数据的发送觉得是个异步的执行过程,应用层负责把数据写入到TCP缓存中,而缓存中的数据可不里都都能能 靠TCP的可靠传输机制去保证发送到对端,意味TCP的可靠传输机制执行过程中会考虑拥塞窗口、对端接收窗口、MSS、nagle算法等因素,执行完成后返回的copied字节量暂且一定就代表对端接收成功了。

-->ngx_http_log_request(r);//记录日志

** 进行发送窗口snd_wnd 检测, 若发送的MSS超过了发送窗口则经常老出;

响应的字节完整版发送完成后调用 ngx_http_finalize_request(r, rc);

** 若开启了Nagle算法不到立即发送此报文则经常老出;

ngx_http_finalize_request()

-->__tcp_push_pending_frames()