redis太长导致的问题

记录一次jvm调优

出现背景

项目再新建用户的时候,突然新用户的访问接口速度整体下降,所有新建的用户都很卡。生产上很着急,产品一直催。

解决思路

项目接口无报错,只是很慢,其他用户访问正常,第一时间想到可能是GC有异常,

  1. 使用top命令,观察到cpu再接口访问的时候飙升至百分之300多,怀疑是gc线程再垃圾回收。修改前是百分之300

  2. 使用在使用jstack 1 |grep 1 使用发现一直有垃圾回收线程,误以为再垃圾回收,使用jstat -gc #pid 1000 100 观察gc垃圾回收情况,参数参考https://www.cnblogs.com/williamjie/p/9329776.html圾回收稳定10多秒一次正常,一次的事件也再50ms以下正常,垃圾回收无问题。垃圾回收稳定10多秒一次正常,一次的事件也再50ms以下正常

  3. 排除垃圾回收问题继续分析

  4. 使用ps -ef|grep #pid(你的pid)查看到是项目,在使用jstack 1 |grep 1 > /1.txt 将内存快照导出到本地文件分析。

  5. 使用https://fastthread.io/ft-index.jsp分析发现有很多等待的线程,怀疑是线程等待导致系统资源不足
    在这里插入图片描述

  6. 后续观察导出的快照,发现这些线程是xxljob的用户设置的定时任务无问题。线程等待是正常的。问题回到原点。

  7. 后来观察到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>
  1. 没发现有任何改善,后来觉得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转换很慢所以系统很慢。

  1. 终于找到问题了,那就简单了在往redis设置值的时候不放这个属性就可以了,toString的时候忽略这个属性就可以了。增加 @JSONField(serialize = false)
    @JsonIgnore
    两个注解。
    很奇怪fastjson好像不认识@JsonIgnore 所以两个都写了。至此问题解决
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值