tcp/http类nginx服务器keepalive_requests数据丢失问题

简介: tcp/http基于请求/响应式交互的上层协议服务器或反向代理服务一般有一个keepalive_requests参数可以指定一条tcp连接上最多能发送的请求数量,超过keepalive_requests数量时server端会关闭tcp连接, 在使用这个指令做服务端时可能导致与其连接的client端数据丢失问题.

tcp/http基于请求/响应式交互的上层协议服务器或反向代理服务一般有一个keepalive_requests参数可以指定一条tcp连接上最多能发送的请求数量,超过keepalive_requests数量时server端会关闭tcp连接,例如nginx的指令:

Syntax: keepalive_requests number;
Default: keepalive_requests 100;
Context: http, server, location
This directive appeared in version 0.8.0.
Sets the maximum number of requests that can be served through one keep-alive connection. After the maximum number of requests are made, the connection is closed.

在使用这个指令做服务端时可能导致与其连接的client端数据丢失问题,最直接的现象就是client和server端请求数量不一致,即server端数据有缺失。一些真实的案例:多个反向代理服务器串接在一起提供服务器时,非最后一个代理服务器使用的keepalive长连接常有一些请求502状态码记录,在后端服务器上排查日志时找不到对应记录。

问题简要分析如下:
配置keepalive_requests=1000,即server端一条tcp长连接上收到第1000请求并处理返回响应时判断已经达到keepalive_requests数量,直接调用close()关闭连接,tcp交互序列描述如下:

image

示例:下边的抓包是一条长连接上多个请求传输有丢数据,server端配置了keepalive_requests=1000;使用过滤条件 tcp.stream eq 0 && tcp.len==14 过滤出1000个请求的响应报文如下:其中11.x.226.82是server端ip地址。

image

image

根据tcp协议原理可知上图红色框中部分属于server端的半关闭,即server端不再接收数据,但是不会影响client端仍接收传输链路上的数据,tcp协议交互还在链路上继续,
丢数据问题就发生在server关闭报文到达client端这段链路时间开销中;

image

上图可以看出因为client端收到第1000个response后还没有立即接收到FIN+ACK关闭报文,所以继续发送第1001个request(注意:应用层面调用send或write函数可以返回写成功),而1001 request到达server后tcp已经半关闭,不会再接收处理数据发送rst以通告对方。

因为client发送数据到tcp协议缓存即调用send或write函数返回写成功,但数据不能被server接收处理,导致发送数据丢失而应用程序没有感知,这种情况下最好有应用层保障机制(失败重传机制),即每个请求发送后都根据响应做判断数据送达。或者client端主动控制发送少于server规定keepalive_requests数量的请求。

目录
相关文章
|
5天前
|
缓存 网络协议 Java
【JavaEE】——TCP回显服务器(万字长文超详细)
ServerSocket类,Socket类,PrintWriter缓冲区问题,Socket文件释放问题,多线程问题
|
15天前
|
弹性计算 负载均衡 网络协议
ECS中实现nginx4层7层负载均衡和ALB/NLB原SLB负载均衡
通过本文的介绍,希望您能深入理解并掌握如何在ECS中实现Nginx四层和七层负载均衡,以及如何使用ALB和NLB进行高效的负载均衡配置,以提高系统的性能和可靠性。
62 9
|
28天前
|
存储 编解码 应用服务中间件
使用Nginx搭建流媒体服务器
本文介绍了流媒体服务器的特性及各种流媒体传输协议的适用场景,并详细阐述了使用 nginx-http-flv-module 扩展Nginx作为流媒体服务器的详细步骤,并提供了在VLC,flv.js,hls.js下的流媒体拉流播放示例。
129 1
|
1月前
|
负载均衡 监控 应用服务中间件
配置Nginx反向代理时如何指定后端服务器的权重?
配置Nginx反向代理时如何指定后端服务器的权重?
66 4
|
1月前
|
网络协议 安全 Go
Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
【10月更文挑战第28天】Go语言进行网络编程可以通过**使用TCP/IP协议栈、并发模型、HTTP协议等**方式
68 13
|
1月前
|
存储 监控 安全
服务器死机,数据丢失怎么办?
【10月更文挑战第27天】当服务器死机且数据丢失时,应先尝试重启服务器并检查硬件问题。随后,利用备份数据、数据恢复软件或专业服务恢复数据。为预防未来数据丢失,需定期备份数据,使用热备份和RAID技术,定期维护服务器,强化安全性,并建立监控和日志记录机制。
125 8
|
2月前
|
网络协议 Java API
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
【网络】TCP回显服务器和客户端的构造,以及相关bug解决方法
73 2
|
2月前
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
78 1
|
2月前
|
网络协议 Python
Python创建一个TCP服务器
Python创建一个TCP服务器
26 0
|
Web App开发 前端开发
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html><head><meta http-equiv="Cont
异步通信 对于BS(Browser-Server 浏览器)架构,很多情景下server的处理时间较长。 如果浏览器发送请求后,保持跟server的连接,等待server响应,那么一方面会对用户的体验有负面影响; 另一方面,很有可能会由于超时,提示用户服务请求失败。
774 0