目录
背景:
某项目由于业务需求,某个接口QPS需2000左右。比平时该项目全部请求QPS增加100倍。
上线后收到间歇性504超时告警。
现象:
- 分析Cat long-url 筛选3s以上的请求。分析多个请求的logView后,并未发现耗时的点。
- 怀疑gc,发现gc没有配置垃圾回收器。用的jdk8默认的回收器 UseParallelGC 即 Parallel Scavenge + Parallel Old。cat上并未出现预想中的打点。
- 打开host监控,查看宿主机和容器监控,并未发现异常点,只有超时导致的http链接异常。
未见load、cpu、I/O、内存、磁盘、thread(发生超时有明显http线程增加、正常现象)、等异常。 - 线上查看gc日志未见明显异常。
定位&分析:
- 告警时保留现场,继续查看gc日志,发现默认配置会导致gc时间过长。调整配合设为G1gc 并增加容器内存,增加jvm内存参数。由堆最大8G扩充到16G。发布后并未解决问题。端到端依然是间歇性504超时告警。
- 由于第一步改成g1gc后,cat上可以看到具体gc信息。没有old gc,young gc 次数和时间没有明显凸起,初步判断大量对象分配到young区,可被立刻回收。但是young gc耗时导致。
- 分析gc日志发现大部分gc(user)时间都集中在500ms以内,出问题的时间 gc的user高达1.5s ,并没有STW日志。user时间远大于 sys + real 。
一般出现该现象原因有2种,第一种swap占用,第二种IO过高gc日志阻塞gc。
重新查看宿主和容器host监控发现出问题的机器和告警时间的机器有IO高的问题。 - 定位是间歇性IO高导致的系统抖动。容器IO高可能是宿主机的问题 也可能是业务自己写大量日志。机器上查看该业务线上每个机器每小时日志输出量在1G多。
解决:
解决机器IO抖动问题既可以解决服务抖动。
临时关闭业务线上日志,问题解决。