出现背景
项目再新建用户的时候,突然新用户的访问接口速度整体下降,所有新建的用户都很卡。生产上很着急,产品一直催。
解决思路
项目接口无报错,只是很慢,其他用户访问正常,第一时间想到可能是GC有异常,
-
使用top命令,观察到cpu再接口访问的时候飙升至百分之300多,怀疑是gc线程再垃圾回收。
-
使用在使用jstack 1 |grep 1 使用发现一直有垃圾回收线程,误以为再垃圾回收,使用jstat -gc #pid 1000 100 观察gc垃圾回收情况,参数参考https://www.cnblogs.com/williamjie/p/9329776.html圾回收稳定10多秒一次正常,一次的事件也再50ms以下正常,垃圾回收无问题。
-
排除垃圾回收问题继续分析
-
使用ps -ef|grep #pid(你的pid)查看到是项目,在使用jstack 1 |grep 1 > /1.txt 将内存快照导出到本地文件分析。
-
使用https://fastthread.io/ft-index.jsp分析发现有很多等待的线程,怀疑是线程等待导致系统资源不足
-
后续观察导出的快照,发现这些线程是xxljob的用户设置的定时任务无问题。线程等待是正常的。问题回到原点。
-
后来观察到pom.xml中文件的初始堆参数设置为1g 最大4g,配置如下,看资料一般都要相等。所以更改为4g。
<container>
<jvmFlags>
<jvmFlag>-javaagent:/agent/skywalking-agent.jar</jvmFlag>
<!-- <jvmFlag>-Dspring.profiles.active=${docker-profile-config}</jvmFlag>-->
<jvmFlag>-Dskywalking.agent.service_name=${project.artifactId}</jvmFlag>
<jvmFlag>-Dskywalking.collector.backend_service=${skywalking-host-config}</jvmFlag>
<jvmFlag>-Xms4000m</jvmFlag>
<jvmFlag>-Xmx4000m</jvmFlag>
<jvmFlag>-Duser.timezone=Asia/ShangHai</jvmFlag>
</jvmFlags>
<!--使用该参数将镜像的创建时间与系统时间对其-->
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
<mainClass>cn.com.people.GoffApplication</mainClass>
</container>
</configuration>
- 没发现有任何改善,后来觉得cpu一访问就飙高肯定是再处理什么,本地debug了半天,发现redis存的值大概有600k使用阿里巴巴的fastjson解析这部很慢,此时才定位到原因,
@Transactional
public void cacheLoginUser(LoginUser loginUser) {
loginUser.setLoginTime(System.currentTimeMillis());
loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds * 1000);
// loginUser.setExpireTime(loginUser.getLoginTime() + expireSeconds);
redisService.setString(RedisKey.getTokenKey(String.valueOf(loginUser.getId())), loginUser.toString(),
expireSeconds, TimeUnit.SECONDS);
}
将loginUser.toString()直接toString丢到redis了,
@Override
public String toString() {
return JSON.toJSONString(this, SerializerFeature.WriteMapNullValue);
}
}
toString的方法使用的是为空也设置,问题是User实体嵌套了teams和roles实体roles的实体中有一个users 存了好多好多 ,就是这个特别大导致的redis的值很长很长 json转换很慢所以系统很慢。
- 终于找到问题了,那就简单了在往redis设置值的时候不放这个属性就可以了,toString的时候忽略这个属性就可以了。增加 @JSONField(serialize = false)
@JsonIgnore
两个注解。
很奇怪fastjson好像不认识@JsonIgnore 所以两个都写了。至此问题解决