3个自建系统使用了一个统一的外部系统接入服务,该服务主要是统一处理外部系统对接,处理掉数据鉴权等问题,提供内部鉴权接口给自己的服务使用。类似一个对接网关。
问题背景
研发反应,后端接口请求时快时慢,影响演示效果。
排查过程
1. 使用postman等工具调用接入服务接口。接口响应再3秒左右,确实存在时快时慢问题。
2. 由于接口是透传接口,测试直接调用外部平台接口。响应速度很快,毫秒级。
3. 安排研发在接入服务上加日志,发现收到上层应用请求后,执行转发,到收到响应过程慢。
4. 直接在服务器上使用curl执行外部业务接口请求,存在响应慢问题。
5. 换其他虚拟机执行curl测试请求,响应毫秒级。从而判定接入服务主机及应用侧存在问题。
6. 执行
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
查看容器内连接状态。发现存在大量close_wait和fin_wait2。数量级过万。
7. close_wait和fin_wait2说明。
close_wait这个状态存在于服务端,当服务端发送FIN(之前客户端已经发送过fin),请求关闭连接之后进入close_wait,然而没有收到客户端的响应,可能由于客户端掉线了(如网络故障或者掉电),没有及时给予客户端回复造成问题。
或者由于客户端已经调用close(socket)退出,而服务端对其监测并断开连接,这种是服务端问题。fin_wait2个状态存在于主动发起断开请求的一端,如果服务器存在大量的这个状态,那么这个服务器就充当客户端的角色,如网络爬虫,出现的原因是由于客户端发起FIN请求结束连接之后,收到了服务端的应答之后进入FIN_WAIT2,之后就没收到服务端发送的FIN信号导致。
8. 根据网络连接情况判定,应用侧存在大量未结束连接,没有释放链接资源。拉研发判定,发现使用的是okhttp组件,并且研发没有主动关闭请求连接。更改成restTemplate组件处理,并配置了连接池进行优化。
9. 应用升级后查看链接状态。
netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
基本恢复正常,测试连接响应时间毫秒级。