前言

直接说遇到的问题吧

第一个问题:response body内容被截断,本来的返回值是一个json,但是实际返回值被截断了,说起来太抽象,直接给出例子:

本来应该是正确的返回值

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
  "key4": "value4",
  "key5": "value5"
}

但是实际的返回值变成了这个样子

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
  "key4": "value4"

变成了一个残缺的json,无法解析

第二个问题:server端tomcat报错 org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe

本来以为是服务端处理时间过长导致客户端提前断开连接导致的,网上搜了一下也是大把的这种答案,但是试了很多种方法都没有重现该问题。

贴一下在排查问题的过程中遇到的我觉得说的比较清楚的一篇博客: 博主重现了该异常,但是对我实际的排查问题还是没有带来太大的帮助

排查思路

首先说第一个返回值截断的问题:

现象是前端拿到的返回值是被截断的,于是直接调用了后端的接口,调用了很多次很多次。。。没有一次重现返回值被截断的现象。既然这样,那大概率就是中间的传输链路出了问题。

我们的大致链路是: browser -- nginx代理 -- server端,大概率问题就出现在了nginx代理上,然后我就搜了nginx导致返回值截断的相关文章,还真的找到了一些思路。

我们使用nginx其实只是做了一个反向代理,于是就从代理上找问题。后来发现nginx的proxy_temp目录竟然没有写入的权限,大致理了思路:nginx代理先往buffer里写东西,如果buffer满了之后会写入到磁盘,但是写入磁盘的时候没有权限,其实看nginx日志的话,会发现很多没有权限相关的日志。

第二个Broken pipe的问题:

先看了server端发生问题的接口的响应时间,发现接口的响应时间并不长,都在毫秒级别,有的甚至在十几毫秒的时候就报了这个异常。于是考虑难道是客户端在某些场景下主动abort了请求?这种排查起来就比较难了,项目属于网关层,有很多端的接入,根本无法排查。到这儿陷入了僵局。

但是还是很不甘心,在网上搜相关的文章,找到了一个说法:一般是客服端先断开了连接,但是如果中间经过了其他的nginx或者tomcat的话,也有可能是中间件中止了请求。从这方面入手,又想到了nginx代理。。。。。

解决问题

本来是想打开nginx的proxy_temp目录的权限的,但是运维小哥哥说由于安全原因啥的,最后只能增加了proxy_buffer的大小。
在出现问题的location下,增加如下配置:

proxy_buffering on;
proxy_buffers 8 10M;
proxy_buffer_size 4k;
proxy_busy_buffers_size 20M;

两个问题都解决了。。。