目录
问题
- 错误1:
httpClient向服务端发送请求,服务端有时候就会给客户端返回 500错误,
打开服务端错误日志,报如下错误:
2021-05-28 21:05:06.548 default [http-nio-0.0.0.0-xxxx-exec-6] ERROR o.a.c.c.C.[.[localhost].[/].[dispatcherServlet] - Line:175 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
(问题在于没有标注具体哪一行空指针,不好定位问题,而且也不是每次请求都报错,是偶尔报错。)
- 错误2:
java.net.SocketTimeoutException
分析
- 错误1分析
经过进一步分析,发现问题出在InputStream,
InputStream inputstream =request.getInputStream()
inputstream.read()
当获取请求中的InputStream后,读取InputStream的过程中出现上述错误2:java.net.SocketTimeoutException,而程序中只是捕获了这个异常,并没有处理,导致出现了空指针。
那么问题来了,为啥会报错误2,而且是有时候报错。
- 错误2分析
出现错误2的原因是httpclient 获取响应超时引起的,也就是服务端还没有读完InputStream,httpclient就已经响应超时,执行响应超时后的断开链接等动作,导致读取InputStream异常。
那为啥会触发响应超时呢,这个原因比较多,
有可能是网络原因,导致网络传输比较慢;
也可能是因为httpclient这次请求中携带数据比较大,服务端读取比较慢;
也有可能是服务端负载较高,处理数据较慢,等等。
解决
分析到原因后,通过两方面解决这个问题,
- 对于服务端来说,要对异常捕获进行处理,并且向客户端响应相应的提示信息。
- 对于客户端来说,可以将响应时间(http.socket.timeout)适当增大一些。
附录
关于httpclient的两个超时时间的设置,
- 请求超时(http.connection.timeout):也就是连接超时,指的是从client发起建立http链接,到http链接建立完成的时间。
- 响应超时(http.socket.timeout):也就是读取数据超时,指的是client发送完http请求到接收到server的响应的时间。
注意
- 写Java一定要捕获各种异常,并且要对异常进行处理;否则遇到问题很难定位。
- 对于各种文件流,网络流等,一定在finally{}中关闭流,既保证正常情况下关闭,也保证异常情况下关闭流,否则可能导致在异常情况下导致占用资源,而引起服务端不能正常对外提供服务。
- 相对难定位的问题就是有时候报错,有时候正常,而且有可能对于同一个请求一会正常,一会报错,对于这种问题有时候得从网络,硬件,CPU,内存,或者操作系统层面考虑。
参考
https://blog.csdn.net/goodlixueyong/article/details/50676821
https://blog.csdn.net/weixin_38629529/article/details/89788963
https://blog.csdn.net/senblingbling/article/details/43916851