场景:前端上传的视频文件过大,做了一个分片上传的接口, 调试接口的时候,后端EasySwoole程序接收不到请求,前端发现接口返回状态码408
遇到的问题:一个文件分三片上传,第一次请求接口正常,后面第二次请求就被nginx拦截,返回状态码400,紧接着请求又返回408,前端是App不好调试,只能从nginx和网络抓包分析问题
问题排查过程:
php程序接口日志无输出,直接打开Nginx的access .log,看日志:
第一次请求成功,状态码是200。
第二次就请求失败了,状态码是400,
然后前端进行两次重传也是失败了,返回状态码还变成了408
因为前端是App调用的接口,看不到详细请求,只能在服务器抓包,用Wireshark分析前端的请求发现:
请求成功的是一个完整的http请求,是流0,红色的标识客户端(App)发送的入参,每一个参数末尾有分隔符boundary
追踪这个流到流1,就是失败的请求,因为文件参数结尾没有boundary,服务器读取不了入参, 直接被nginx拦截了返回400, 也就没有响应数据。
前端进行重传的流2和流3,nginx还是接收不到完整的参数就返回了408
Nginx文档描述:
在设置的超时时间参数client_header_timeout和client_body_timeout的时间内,服务端没有读取到正常的请求头和请求体,就会返回408,但是这个问题说明了服务端在接收两次请求都没有读取到对应的请求体,nginx也会返回408,跟时间无关,修改时间参数解决不了问题
最后由前端手动加上了入参的boundary,就能正常上传: