1、问题背景
做一个项目,前端通过nginx调用zuul后调用后台微服务,但是项目上线后,总是频繁的出现下面的错误。
这个感觉就是后台返回报文不全(其实此时压根没想到nginx这个东西)
但是偶尔又不会出现任何错误。
2、问题分析
初步猜测可能是后台返回的报文太长了,毕竟有看到微服务是有输出交易的,这种情况,那就在开发环境造数据看看是否能否重现呗!
然而在开发环境造数据后却没有发现任何问题,虽然没有做分页,有点卡,这就尴尬了,那就直接看代码呗,发现是在下面代码报错。
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
String lines = "";
while ((lines = reader.readLine()) != null) {
recv += lines;
}
难道返回有特殊字符,或者后台接口返回的数据不全导致的,然后百度看看,说reader.readLine()是会有这种错误!(其实这里越走越篇了)。
对比一下别的项目调用微服务,发现不是用这种方法,而是用下面这种方式
client.getHttpConnectionManager().getParams().setSoTimeout(Integer.parseInt( response_timeout));
client.executeMethod(post);
String s = post.getResponseBodyAsString();
难道是调用方式不对?(其实本质上是一样的,还是偏了)
然后不管三七二十一,改一下走换版流程,上线发现,还是不行,开始报下面的错误了
这他喵不是一个意思么,还是报文不对。
后面突然想到,我们前端调用微服务,因为是直接http工具类来调用的,所以没有跟注册中心交互,用的是nginx来调用zuul的集群。会不会是nginx因为返回报文太大了,截取了?
毕竟上面还尝试了把生产环境的报文拿到开发环境模拟了一下,发现报文大小差不多200k,百度了下nginx 返回报文截取,发现真的有这样的情况
然后我登录上我们生成环境微服务看下日志,果然,是有类似的日志
看看权限
为啥是nobody。
所以本质原因是:nginx对于小的反向代理请求是使用内存作中转,对于稍微大一点的,是使用临时文件系统来做中转的,临时文件目录/usr/local/nginx/proxy_temp.因为这个目录没有权限,导致异常结果。
解决办法
修改nginx用户。
解决办法:删除proxy_temp下的文件,重新reload一下nginx就可以了。
然后我登陆发现我的nginx配置文件里面是如下配置
#user nobody
尴尬,然后改为
user nginx
页面有做什么删除,直接reload一下,就OK了。