背景:一个广告系统,主要提供针对终端APP的广告接口。其中有多个业务需要对接另外的内网系统。例如上传埋点和对接推荐系统。日均PV在千万级以上,高峰期的日pv达到过亿。
现象:从今天中午起,大量请求开始出现响应超过三秒的现象,另外查看CPU占用率,已经高达百分之九十以上。
排查:
1、通过查看日志,发现多数异步线程均在超时时间之后返回数据,导致主线程获取到的异步数据均为空,这一部分推荐的数据被舍弃。
2、进一步查看日志,发现大部分请求的主线程在结束之后,异步线程才开始返回数据,并且这个时间间隔越往后越大,就是说,例如主线程通过Feture.get()获取异步数据之后,异步线程经过了一定时间才返回了数据,中午一点的时候,这个数值是2s,4点之后,升级为3s,一直保持在3s左右。
3、初步判断是由于异步线程返回时间过长,线程池已经被占满(CPU为4核,线程池为核心数的两倍),遂将线程池数量扩充为当前数量的三倍,即24个。正常了一段时间,但是之后依旧有大量响应时间超过三秒的请求出现。
4、追踪异步线程逻辑,发现有一个异步线程,通过http方式获取推荐系统推荐的数据,查看日志,发现该异步线程的处理时间呈现递增趋势,最后一直稳定在3s。
5、追踪到关联方,发现他们的服务器竟然只有两台,超过负荷的请求,将会一直在排队,导致响应变慢。而http请求的默认超时时间为3s,所以每一个慢响应,都将占用异步线程池的一个线程3s,并发量上来之后,线程池自然出现耗尽的情况。
6、继续追