山西大同企业做网站,inove wordpress,长治网站建设案例,苏州cms模板建站宝背景 最近负责了一个审批流程新项目#xff0c;带领了几个小伙伴#xff0c;哼哧哼哧的干了3个月左右#xff0c;终于在三月底完美上线了#xff0c;好消息是线上客户用的很丝滑#xff0c;除了几个非常规的业务提单之外#xff0c;几乎没有什么大的问题#xff0c;但是…背景 最近负责了一个审批流程新项目带领了几个小伙伴哼哧哼哧的干了3个月左右终于在三月底完美上线了好消息是线上客户用的很丝滑除了几个非常规的业务提单之外几乎没有什么大的问题但是美中不足的是发现每个pod的GC频率非常高基本上30分钟就会有一次FGC导致每次流量高峰的时候会有一部分客户反馈系统有些卡顿观察监控平台发现每天流量高峰的时候FGC竟然达到了惊人的5分钟每次每次GC的时间差不多有400-700ms此时部分接口的耗时达到了5s因此接口优化和参数调优迫在眉睫 因为本项目是基础服务每个业务方都会调用所以当时申请节点内存大小的时候就富裕了一点共部署了4个pod每个pod资源是8核16G但是观察监控平台发现每个pod内存只使用不到2G其中eden 200M old 500m survivor更是只有可怜的96m左右导致年轻代很容易就占满了存活的对象就被转移到老年代了由于老年代分配的内存也特别少QPS一高就会频繁的触发FullGC导致系统卡顿甚至接口超时。 排查代码发现有一个占比60%量一个接口虽然查询的表比较单一但是查询了所有字段其中一个字段存储的是一个JSON但业务中却又没有使用到。
JVM常见参数 一、配置垃圾收集器 1、Serial垃圾收集器新生代 开启-XX:UseSerialGC 关闭-XX:-UseSerialGC //新生代使用Serial 老年代则使用SerialOld 2、ParNew垃圾收集器新生代 开启 -XX:UseParNewGC 关闭 -XX:-UseParNewGC //新生代使用功能ParNew 老年代则使用功能CMS 3、Parallel Scavenge收集器新生代 开启 -XX:UseParallelOldGC 关闭 -XX:-UseParallelOldGC //新生代使用功能Parallel Scavenge 老年代将会使用Parallel Old收集器 4、ParallelOld垃圾收集器老年代 开启 -XX:UseParallelGC 关闭 -XX:-UseParallelGC //新生代使用功能Parallel Scavenge 老年代将会使用Parallel Old收集器 5、CMS垃圾收集器老年代 开启 -XX:UseConcMarkSweepGC 关闭 -XX:-UseConcMarkSweepGC 6、G1垃圾收集器 开启 -XX:UseG1GC 关闭 -XX:-UseG1GC 二、堆内存相关配置 设置堆初始值 指令1-Xms2g 设置堆区最大值 指令1-Xmx2g 新生代内存配置 指令1-Xmn512m 2个survivor区和Eden区大小比率 指令-XX:SurvivorRatio6 //S区和Eden区占新生代比率为1:6,两个S区2:6默认是8即8:1:1 新生代和老年代的占比 -XX:NewRatio4 //表示新生代:老年代 1:4 即老年代占整个堆的4/5默认值2 三、GC并行执行线程数 -XX:ParallelGCThreads16 四、进入老年代的GC年龄 -XX:InitialTenuringThreshol7 //年轻代对象转换为老年代对象最小年龄值默认值7对象在坚持过一次Minor GC之后年龄就加1每个对象在坚持过一次Minor GC之后年龄就增加1 -XX:MaxTenuringThreshold15 //年轻代对象转换为老年代对象最大年龄值默认值15 五、GC日志信息配置 -Xloggc:/data/gclog/gc.log//固定路径名称生成 -Xloggc:/home/GCEASY/gc-%t.log //根据时间生成 打印GC的详细日志 开启 -XX:PrintGCDetails 关闭 -XX:-PrintGCDetails 六、在Full GC时生成dump文件 -XX:HeapDumpBeforeFullGC //实现在Full GC前dump -XX:HeapDumpAfterFullGC //实现在Full GC后dump。 -XX:HeapDumpPathe:\dump //设置Dump保存的路径 调优过程 一、业务调优 业务调优就不展开讲述了主要是用到了arthas这个调优工具trace了耗时比较久的接口排除不优雅的编码之后就来到了数据层面由于项目使用的是postgres sql并且已经分库分区了核心表的数据量级也是百万级别所以最终关注的是索引使用explain查看核心sql的执行计划看其是否命中索引 补充一点由于项目有一张历史表的数据量比较大8000万左右并且业务中也需要使用到每个单据号对应的审批流程一般是流程节点的10倍左右比如某个审批流程10个节点那么改流程结束后就会产生100条数据在列表中使用到了改表中的某些数据起初直接根据单据号进行查询那么分页条数为1000的时候每次就会查询1000*100条记录而业务真正需要关注的只是10个节点的审批结果而已白白浪费90%的查询记录因此在业务中冗余了一个节点字段标识是否是节点的审批结果每次查询除了使用单据号之外加上该字段就大大的过滤了记录数量这样做法有如下好处 ①减少网络传输量 ②降低内存使用起初是内存过滤高cpu操作 ③防止OOM 二、JVM参数调优 第一版 第一版比较偷懒直接上了G1因此G1不用配置过多的参数很多就自适应调节但是一上线发现cpu就很容易飙升到80以上并且接口耗时也慢了一倍起初每个接口的耗时到该200msG1之后就变成400ms终于在运行3天之后就有监控告警有大量的接口请求超时观察到jvm堆内存使用长时间100%导致健康检查机制强行将节点重启了5s检查一次15未检查到就重启为了不影响业务先增加了两个节点降低QPS从而降低堆内存使用。 具体的参数配置
-XX:UseContainerSupport -XX:MaxRAMPercentage75.0 -XX:PrintGC -Xloggc:/data/logs/gc.log -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/data/logs/ -XX:UseG1GC -Xmx9G -Xms9G -XX:MaxDirectMemorySize1g -XX:ConcGCThreads8 -XX:MaxGCPauseMillis500 第二版 由于公司所有的项目都是K8s集群部署所以JVM参数基本都用的是默认参数这一次只是设置了Xms11gXmx10gXmn4g但是发现年轻代的from和to的比例不对按照正常的默认811应该是410m左右但是监控上面显示的始终是121m这样的话QPS达到高峰的时候老年代上升的速率就比较快3.76G基本上12h就用完触发了FGC这显然是不合理的因为业务逻辑中没有需要常驻内存的对象基本上朝生夕灭的在年轻代就应该被回收而导致出现这个原因是from和to的内存太小了存货了15次之后的对象就被转移到老年代了。 开始的时候使用-XX:-UseAdaptiveSizePolicy –XX:SurvivorRatio8确实改变年轻代的具体分配内存但是使用 jmsp -heap 1命令发现jvm的垃圾回收器是ParallelGC并不是我们想要的CMS因此不论年轻代from和to的设置了多大空间其使用始终不会超过121m老年代还是晋升的速率比较快并没有彻底解决问题。具体参数配置如下
-XX:UseContainerSupport -XX:MaxRAMPercentage75.0 -Xmx11g -Xms11g -Xmn5g -XX:PermSize1g -XX:MaxPermSize1g -XX:SurvivorRatio8 -XX:-UseAdaptiveSizePolicy -XX:PrintGC -XX:PrintGCDetails -XX:PrintGCDateStamps -XX:PrintGCTimeStamps 第三版 最终版本 开启CMS收集参数 -XX:UseConcMarkSweepGC监控和运行变得正常堆空间各个区域的分配也是正常的。
-XX:UseContainerSupport -XX:MaxRAMPercentage75.0 -XX:UseConcMarkSweepGC -Xmx11g -Xms11g -Xmn5g -XX:PermSize1g -XX:MaxPermSize1g -XX:PrintGC -XX:PrintGCDetails -XX:PrintGCDateStamps -XX:PrintGCTimeStamps -Xloggc:/data/logs/gc.log -XX:HeapDumpOnOutOfMemoryError -XX:HeapDumpPath/data/logs 小结 容器部署节点只分配1G具体原因可以参考这篇文章频繁 GC 问题排查以及UseContainerSupport与MaxRAMPercentage的正确使用-CSDN博客 按照理论上第二次调优就已经能够满足业务需求了但是依据《深入理解Java虚拟机》讲的jdk8默认的垃圾收集器是CMS那么年轻代的eden、from和to分配内存空间的比例应该是8:1:1显然目前我的数据不正确进入到pod节点发现jvm使用的是ParallelGC如下图所示 jvm调优常见问题 常用命令 jmap -heap pid 查看内存使用情况
推荐配置 8C16G下的参数配置
综上所述8C16G下推荐使用如下的参数设置 -Xmx12g -Xms12g -XX:ParallelGCThreads8 -XX:ConcGCThreads2 -XX:UseConcMarkSweepGC -XX:UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction70 -XX:MaxGCPauseMillis100 // 按业务情况来定 -XX:PrintGCTimeStamps -XX:PrintGCDetails -XX:PrintGCDateStamps