背景:指标对齐服务(CPU密集型)
原本指标对齐服务的请求较小,响应速度不会超过1s,采用http同步处理可以解决。但最近接入的业务中有大文件业务,响应时间指数上升,但nginx的超时时间设置默认设置60s,处于业务的特殊性,选择采用接入kafka异步处理。
但很快问题就来了,第一天上线,刚跑几个大文件业务,就来了一个超大文件的。topic设置的大小是10M,我和上有服务采用zip包传输,也就是说一个json请求体压缩后最大可以传输10M。这个大小可以传来几万个指标,程序计算量倍增。kafka配置如下图:
大文件业务要求的及时性不高,通常都是T+1以上的。原本以为只需要接入kafka,设置一两个消费线程,每次只消费一个请求,让整个大文件业务慢慢跑就可以解决问题。但没想到第一天就出现了kakfa重复消费的问题,当时的现场如下图:
可以看到当前已经发生了rebalance和revoked,并且kafka底层将这个消费者组直接移除了,然后消费者组又重新加进来消费,形成恶行循环。
于是我查了当前机器的CPU占用情况(如下图),发现CPU可以从10%瞬间爆拉到50%!这说明我服务的gc情况肯定是爆了的。
使用jprofiler跑了一下程序的情况,结合公司一些其他的监控平台(如下图)
得出一个结论:服务启动时程序就开始full gc,1分钟时间full gc 3次,并且超过30s,3min内程序分配的内存累计超过90G。这说明程序有严重的GC问题,并且这个问题的原因就是程序中有不断分配的大对象。kafka中session.timeout.ms和heartbeat.interval.ms 默认是 10000ms 和 3000ms,意味着默认kafka每3s会检测一次服务是否存活,如果程序10s内没有响应,kafka会任务服务已经死亡,并将这个消费者组踢出,消费者组过一会儿又会自己加进来,这才造成了重复消费的问题
问题解决方式:1、全面评审代码,将大对象复用,将无用的大对象删除,减少GC次数
2、第一种方法可以从根源上解决问题,但这显然不是解决问题最快的方式,毕竟线上业务都在接入,时不我待
快速解决办法:增大session.timeout.ms的时间,最起码要比一次full gc的时间要长,让kafka认定服务还存活,并且还要增加max.poll.interval.ms的时长,不然会出现下图这样的问题,并导致重平衡。
最后,将配置都修改完毕后,重新启动项目,问题解决,但gc问题仍在,再去改代码上的问题。
标签:服务,JVM,程序,kafka,问题,gc,ms,连带 From: https://www.cnblogs.com/aeimio/p/17038306.html