在基于spring-boot开发过程尤其是上线后,经常出现网络相关的错误,令人难以琢磨和下手,所以就spring-boot使用过程中可能碰到的网络相关问题进行分析,结合网络转包、日志报错和前端输出,针对网络连接超时、连接被拒绝、读超时等异常进行分析,有助于理解发生问题的根本原因,并快速定位和解决问题。
一、前端直接访问服务
1)服务地址不通
当使用Chrome访问服务的地址不存在时,Chrome会使用三个不同的源端口发送SYN报文,并且使用的规避算法,连续发送4次重连请求。就是大约1秒后第一次重发,距离重发第一次2秒后第二次重发,距离重发第二次4秒后第三次重发,具体重发第三次8秒后进行第4次重发,因为均未收到应答,浏览器判断连接不能建立,所以会显示如下信息:
当使用Postman访问服务地址不存在时,用一个源端口连续发起SYN请求,针对每个SYN请求,按照以上算法连续发送5次,均未收到确认时(也就是10次请求均无应答),在控制台显示如下信息:
2)服务地址通但端口不存在
使用Chrome时,连续发起两次SYN请求,服务端以RST应答,针对每个SYN,又进行了4次重传,Postman最终展示连接被拒绝,在控制台输出如下:
使用Postman时,会大约每500毫秒发送一波SYN请求,每一波包括相隔几毫秒的两个SYN请求,共5波10个SYN请求,服务端以RST应答,Postman最终展示连接被拒绝,在控制台输出如下:
3)服务正常但请求路径错误
使用浏览器访问时,服务端返回HTML格式的错误说明,具体示例如下:
使用Postman访问时,服务端返回json格式的错误说明,具体示例如下:
4)连接池耗尽
使用Chrome或Postman请求服务时,如果服务端连接耗尽,Chrome和Postman将一直等待,直到得到连接并返回结果
5)服务响应慢
使用Chrome或Postman请求服务时,缺省情况下永不超时,所以会一直等待,直到服务返回结果。
二、服务间调用-无超时
以下的测试基于浏览器或Postman访问A服务,A服务又调用B服务,并且均基于springboot+RestTemplate,并且RestTemplate未设置超时。
1)B服务地址不通
A服务在微秒级别内连续发送两次连接请求,后面每个请求按照规避算法重传了4次,然后A服务抛出连接超时异常,如下图所示:
由于该异常未被捕捉,所以该异常返回到前端。前端显示的出错信息就是上面标红的内容。
Postman调用结果:
Chrome调用结果
2)B服务端口不存在
A服务在微秒级别内连续发送两次连接请求,后面每个请求按照规避算法重传了4次,对于每个请求,B服务均以RST应答,A服务抛出拒绝连接异常,如下图所示:
由于该异常未被捕捉,所以该异常返回到前端,前端显示的出错信息就是上面标红的内容。
Postman调用结果:
Chrome调用结果
3)B服务连接池满
B服务连接池满时,A服务调用B服务去不到连接将无限期等待,直到取到连接后再发送请求,在前端、A服务和B服务均不报错。
三、服务间调用-有超时
以下的测试基于浏览器或Postman访问A服务,A服务又调用B服务,并且均基于springboot+RestTemplate,并且RestTemplate设置超时时间为5秒。
1)B服务地址不通
通过前端调用A服务,A服务调用B服务时,相差6微秒连续发送两个SYN请求,然后针对这两个SYN请求,又进行了两次重传,因为超时时间到,所以A服务抛出连接超时异常,具体输出如下:
因为A服务并未捕捉该异常,所以直接返回到前端。
使用Postman时,输出信息如下:
使用chrome时,输出信息如下:
2)B服务地址通到端口不存在
通过前端调用A服务,A服务调用B服务时,相差6微秒连续发送两个SYN请求,然后针对这两个SYN请求,又进行了四次重传,然后A服务抛出拒绝连接异常,具体输出如下:
由于异常未捕捉,所以直接返回到前端。
Post请求时,出错信息如下:
浏览器请求时,出错信息如下:
3)B服务正常,但响应时间超出5秒
前端调用A服务时,A服务与B服务经过3次握手建立连接后,发送HTTP请求,并做了一次重传,然后超时时间到,A服务发送FIN中断连接,此时A服务抛出读耗时异常:
Postman调用时,返回结果如下图所示:
使用Chrome时,返回结果如下图所示:
4)B服务连接被耗尽
A服务请求B服务,因B服务连接池耗尽,抛出读超时异常,错误输出如下:
因异常未捕捉,所以返回前端。
Chrome出错信息如下:
Postman出错信息如下:
四、通过网关调用服务
使用Springcloud Gateway作为网关。
1)下游服务地址不通
下游服务地址不通时,网关连续进行五次连接后报连接超时错误,报错信息如下:
网关并未把错误原封不动返回前端,而是做了处理,Postman端报错信息如下:
2)下游服务端口不存在
下游服务端口不存在时,网关连续多次SYN请求,都收到RST报文,抛出拒绝连接异常,报错信息如下:
网关并未把信息原封不动返回前端,而是错了处理,出错内容与地址不通相同,具体如下:
3)下游服务处理太慢
下游服务处理很慢时,SpringCloud gateway一直等待处理完成后把结果返回给前端
4)下游服务连接耗尽
下游服务连接耗尽时,SpringCloud gateway一直等待处理完成后把结果返回给前端
5)下游服务超时
下游服务超时有两种情况,一种是下游服务调用其下游服务地址不通,一种是下游服务调用其下游服务时下游服务处理太慢。
针对第一种情况,下游服务抛出连接超时错误,具体如下图所示:
如果未捕捉异常,则下游服务把异常信息返回到网关,由网关返回前端,前端报错信息如下:
针对第二种情况,下游服务抛出读超时错误,具体如下图所示:
如果下游服务未捕捉异常,则把异常消息发挥网关,由网关返回前端,前端报错信息如下: