1.问题描述
研发在测试环境进行测试,通过内网上传文件能正常收到nginx返回的错误信息,nginx做了30MB大小的上传限制
{
"return_code": 20010,
"returnDesc": "Request body too large. It should not exceed [30 MB]"
}
通过走公网域名访问应用程序就会报错:
java.net.SocketException: Connection reset by peer: socket write error
2.问题排查
首先在客户端抓包发现服务器在tcp连接中返回了RST包
由于nginx服务器做了上传文件大小限制,那么推测上传文件太大超过了nginx的限制,于是nginx返回了文件太大的报错,但此时应用程序仍然在发送数据流,因此nginx发现自己的响应没有得到回馈,于是返回了RST包。如果此时客户端正在往Socket套接字的输入流中写数据则会提示“Connection reset by peer”。
那为什么内网测试能收到正常返回的数据呢?收到正常返回数据说明client正常完成了一次请求,由于内网速度远远大于外网速度,文件又不是足够的大,因此client在发送完数据流后正常响应了nginx的response。
3.一波三折
又有同事反馈说,通过postman以同样的外网环境调用接口上传文件时,postman能正常接收到返回的数据
同样的环境,为啥客户端去访问却报错,postman能正常接收到数据呢,难道postman有什么异常处理机制?抓包发现通过postman去调用接口的时候链接并没有被RST,而是正常关闭的,并且并没有发生文件的上传
4.问题解决
在网上查询了半天,发现http协议中有这么一个header:Expect:100-continue:
尝试在代码中加入这个header,问题得以解决: