二、高并发治理:1、服务器与JVM运行环境优化

本文探讨了高并发场景下服务器选择的策略,重点分析了HotSpot VM和JVM参数优化,强调了架构和代码调优的重要性。在服务器配置中,建议在高QPS压力下选择8C16G的配置,并使用G1垃圾收集器。此外,文章还详细介绍了CMS和G1收集器的特性和适用场景。

一、服务器选择

1.1 服务器选择的场景

 以商品详情页加载为例

  • 非夜间QPS 20万-100万,每天晚上8-11点是高峰
  • 加载逻辑
    • 1、商品分模块组装:商品图文、商品颜色尺码选项、价格、库存、标签、会员信息、历史购买记录等
    • 2、部分模块查询本地缓冲,如果有直接返回,如果下一步远程查询
    • 3、并行RPC远程查询,设置总等待时间,必要内容(如图文、颜色尺码、价格)在总等待时间内查询到,即可返回给用户
    • 4、异步对第3步PRC查询结果,按照数据变化频率,针对性设置本地缓冲(不同模块过期时间不一样)
  • 商详查询的逻辑概括如下
    • IO密集:大部分是IO,CPU多数时间在等待IO返回。极小部分是逻辑处理组装
    • 内存占用高,大量使用了本地缓冲

1.2 不同服务器配置对比 

  • 50W QPS 稳定压力下,不同配置表现差异比较大
    • 依赖的接口,暂时认为性能稳定
    • 总的POD机器资源一样,都是240C480G
POD配置TOMCATJVM效果打分
4C8G*60台100-300 ThreadCMS  80%内存,新生代500M 老年代5G

接口RT波动大,YGC频繁,出现长达十几秒的FULLGC

调整新生代1G后,FULLGC频率降低,未出现1s以上FULLGC

60分
8C16G*30台300-600 ThreadG1   85%内存,MaxGCPauseMillis=200

接口RT波动性小于4C8G

FULLGC概率大幅度降低,未出现1s以上FULLGC

90分
  • 从40万QPS ,2分钟内升到80W QPS,不同配置表现差异巨大
POD配置TOMCATJVM效果打分
4C8G*60台100-300 ThreadCMS  80%内存,新生代500M 老年代5G前后接口性能波动巨大,错误率明显增大,FULLGC较长50分
8C16G*30台300-600 ThreadG1  85%内存,MaxGCPauseMillis=200CPU高位时长、接口性能波动范围、报错率,都远小于4C8G90分

1.3 总结POD不同配置差异

  • 如果日常单POD 每秒 QPS压力在1万+,特别是8-10万+,建议选择8C16G + G1版本
  • 优势:
    • 常驻线程多,创建线程开销减少(通过TOP命令 或 Jstack观察线程可以发现)
    • 内存和CPU 弹性更大,特别是内存 8G用6G,16G可以用14G,GC影响降低了很多
    • 如果单POD QPS 不到1W,且整体比较稳定 4C或8G都可以

二、HotSpot VM

在2006年的JavaOne大会上,Sun公司宣布最终会把Java开源,并在随后的一年,陆续将JDK的各个部分(其中当然也包括了HotSpot VM)在GPL协议下公开了源码, 并在此基础上建立了OpenJDKHotSpot VM便成为了Sun JDKOpenJDK两个实现极度接近的JDK项目的共同虚拟机。

本文后续内容,都是基于HotSpot VM探讨。

三、JVM 参数

本文基于JDK 8+ 讨论JVM参数配置

2.1 优化JVM前要遵循原则

优先架构调优和代码调优,大多数导致GC问题的原因, 是代码层面的问题导致。JVM优化是不得已的手段。

  • 架构调整
    • 应用上线之前,先将机器的JVM参数设置到最优
  • 代码调优
    • 减少不受限制,创建对象的数量(代码层面)
    • 减少使用全局变量和大对象(代码层面)

2.2 GC选择

 没有最好的垃圾收集器,更加没有万能的收集器,只能选择对具体应用最合适的收集器。

2.2.1 HotSpot虚拟机包含所有收集器

大家主要掌握CMS 和 G1

  • Serial收集器,适用于Client模式下java应用。
  • ParNew 收集器其实就是Serial收集器的多线程版本
  • Parallel 吞吐量优先的并行收集器 ,适合后台运算无需太多交互的任务Server模式下的默认垃圾收集器。
  • Serial OldSerial收集器的老年代版本,是一个单线程收集器,使用“标记-整理算法”。
  • Parallel OldParallel收集器的老年代版本,使用多线程和“标记-整理”算法,在注重吞吐量以及CPU资源敏感的场合,都可以优先考虑Parallel  收集器+Parallel Old收集器的组合
  • ConcMarkSweep 响应时间优先的并发收集器 ,适用于互联网站或者B/S系统的服务端上。基于“标记-清除”算法实现的。
  • G1  分区收集 , JDK 7 Update 4后开始进入商用。
    • G1收集器之前的其他收集器,进行收集的范围都是整个新生代或者老年代,而G1收集器整个Java堆分为多个大小相等的独立区域(Region),虽然还保留有新生代和老年代的概念,但新生代和老年代不再是物理隔离的了,它们都是一部分Region的集合。
    • G1收集器跟踪各个Region里面的垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许 的收集时间,优先回收价值最大的Region(这也是Garbage-First名称的由

2.2.2 CMS 和 G1 二者结构

 虽然设计结构差异很大,单依然保留了分代的概念

2.2.3 判断GC的两个核心指标

  • 延迟(Latency): 也可以理解为最大停顿时间,即垃圾收集过程中一次 STW 的最长时间,越短越好,一定程度上可以接受频次的增大,GC 技术的主要发展方向。
  • 吞吐量(Throughput): 应用系统的生命周期内,由于 GC 线程会占用 Mutator 当前可用的 CPU 时钟周期,吞吐量即为 Mutator 有效花费的时间占系统总运行时间的百分比,例如系统运行了 100 min,GC 耗时 1 min,则系统吞吐量为 99%,吞吐量优先的收集器可以接受较长的停顿。

2.3 8G\16G内存 GC配置

8G内存,CMS和G1均可以

注意CMS的话,特别是有本地缓冲的系统,新生代最好达1G-2G,太小会导致大量内存直接进入老年代

老年代的fullgc特别频繁,且容易出现超长的fullgc
如下图1:fullgc耗时长

图1:fullgc耗时长

2.3.1 8G内存CMS 线上配置

注意不了解的参数不要调整
-Xmn2048M 
-XX:MetaspaceSize=256M 
-XX:MaxMetaspaceSize=256M 
-XX:SurvivorRatio=8 
-XX:MaxTenuringThreshold=8  
-XX:CMSInitiatingOccupancyFraction=80

 2.3.2 16G内存推荐的G1 线上配置

-XX:MaxRAMPercentage=85.0 
-XX:InitialRAMPercentage=85.0 
-XX:MinRAMPercentage=85.0
-XX:+UseG1GC    
-XX:MaxGCPauseMillis=200
-XX:+ParallelRefProcEnabled 
-XX:+PrintGCDetails 
-Xloggc:/home/ops/logs/tomcat_gc.log 
-XX:+PrintGCDateStamps 

2.4、JVM常用命令

本文章节2.3 给出的JVM配置,需要我们结合实际情况持续调优。JVM常用命令整理如下:

jps:  输出JVM中运行的进程状态信息

jstack:查看某个Java进程内的线程堆栈信息

jmap:用来查看堆内存使用状况

jstat:JVM统计监测工具

jhat:与jmap搭配使用,用来分析jmap生成的dump

top :实时动态地查看LINUX系统的整体运行情况

 本专栏会在工具篇>> Linux 和 JVM工具中专门介绍,此处不做进一步讲解。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米灵君的架构思维

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值