1. 压力测试的理解,xxx 的性能 10w/s,对你有意义么?

没有那家卖瓜的会说自己家的不甜,同样,没有哪个开源项目愿意告诉你在对它条件最苛刻的时候压力情况是多少,一般官网号称给你看的性能指标都是在最理想环境下的,毫无参考意义。

举个栗子,Redis 官网压测的例子,256 字节的读速度 11w/s,写速度 8.1w/s,都知道 redis 优点是多变的数据结构,string、List、hash、set、sortset,实际工作稍微复杂的环境往往都是各种结构混合使用,字符串长度各异,你需要的是真正在你的工作环境下,即:你混合使用的数据结构下,你的访问压力下,你的字符串长度下 redis 的 x 响应性能。这个值往往跟官方公布的差异很大。

我这个服务压力 2000tps,你觉得很牛逼?

看着很牛逼对不对,好像 tps 值越高显得能力越强一样,其实很可笑,如果性能好只是比这个,那写一个 1+1=2 的程序估计是无敌了吧。具体问题要具体分析,你牛逼你要说明你牛逼在哪里,在什么条件下,什么样子的背景,才能说你的 tps 是多少,这样才有意义。

反正线上没出现过问题,我们撑得住,你确定?

线上没出现过问题,不代表流量不会增加,流量不会增加不代表业务不会复杂,业务复杂性能下降是很有可能的,没有压力测试做保证,出问题就是大问题。

压力测试都是 qa 在做,有问题会反馈给我,你的服务极限到底在哪里?

你应该关注一下 qa 是怎么做压力测试的,北京java培训无论从服务的角度还是从个人发展的角度。qa 只能给你测试结果,不会告诉你性能瓶颈在哪里。

2.压力测试到底要关注什么

压测不是玩笑,你的 4 个 9 的指标呢

好的服务都会有一项指标,叫 4 个 9,即 99.99%得服务可靠性。这是衡量一个服务是否优秀的普世标准,压力测试的好坏最直观的影响 4 个 9 的保障。压力测试就是用来确保服务的稳定,给出服务稳定极限条件。稳定指的是服务负载,cpu 利用率,接口的响应时长,网络的延迟,结果准确性等等都在你的标准之内。而这些指标又相互影响。

条件,用尽量多的已知去推测未知,模拟仿真,你要做的预测未来

硬件条件:服务器 cpu 核数、内存大小、网络条件、同宿主机下其他服务影响,软件条件:虚拟访问用户数、gc 的稳定程度,响应时长要求,第三方依赖的可用程度、jdk 的不同版本等都会严重影响压力测试的结果,造成你的压测结果上线之后达不到逾期。如果这些条件不注意,很可能你压测时按照达标条件 tps=1000,其实线上 tps 才 500 的时候,服务已经崩溃了。压测的时候,最好保障压测环境与线上一致。你的结果才更有意义。

3.你想要的到底是个什么东西

tps 只是结果,虚拟用户数,线程数,平均响应时长,错误数,90%的平均响应时长,服务器负载,结果准确性尽量用越来越多的点来评估你的服务。

tps:服务处理的吞吐量,每秒响应请求的数量,tps 是压力测试最直观的结果,是衡量服务性能的一个结果性指标,一般说压力测试性能值就是 tps 值。最浅显直白的理解,统计 access 日志每秒的总数就是那一秒的 tps 值。

错误数:一般服务压力测试的时候是不允许出现错误的,即错误数:0%,但是复杂条件下,有的服务是允许出错率不超过 x%的,看服务而定。

平均响应时长:移动互联网时代,你让一个用户打开 app 等你 1s,用户早就跑了,打开 app 立刻看见内容是最起码的要求,一般好的 app 接口相应时间都是毫秒级别的,但是不同的场景不同的要求,我的上一家公司要求平均相应时长在 20ms 以内。可是上上家公司的算法接口,平均相应时长在 100ms,不同的服务不同的要求,你需要找到适合你自己的要求。

90%的平均响应时长:jmeter 学来的,表示 90%的事务,服务器的响应都维持在某个值附近。比如有三个时间:1 秒、5 秒、12 秒,则平均时间为 6 秒,而另外一种情况:5 秒、6 秒、7 秒,平均时间也为 6 秒,显然第二种比第一种要稳定多了。

所以,我们在查看平均事务响应时间的时候,先看整体曲线走势,如果整体趋势比较平滑,没有忽上忽下的波动情况,取“Average Time”与“90 Percent Time”都可以,如果整体趋势毫无规律,波动非常大,我们就不用“Average Time”而使用“90 Percent Time”可能更真实些

结果准确性:多线程下访问下结果的正确性。这个在压测的时候往往容易被忽略。这个需要你在压力测试的时候抽查访问接口,查看结果是否正确,曾经碰到过 qa 测试通过的接口,上线之后发现返回结果不正确,内网回测正确,后来内网压力测试的时候成功复现,是由于使用了不安全的多线程代码导致的,其实压测的时候抽查看一眼,很容易看出来。

线程数:这个指标不在各大压力测试工具监控之内,但是这其实是压力测试非常重要的服务指标。根据经验,好多时候服务崩掉的时候,线程数已经满了,好多时候应用服务器的线程在某个范围之内,服务是最健康的状态,超过某个范围,服务处于不稳定状态,处于有点网络抖动延迟都容易崩溃的临界点,所以熟悉这个值,你就心里清楚你的服务当前在什么状态下。

虚拟用户数(并发线程数):好多人容易把 tps 和虚拟用户数搞混,虚拟用户数表示当前正在访问你服务的用户数,就是说压力测试工具启动多少个线程来不停访问你的接口。但是实际上,哪个用户会像疯狗一样疯狂一直不间断的访问的你接口,对用户来说,访问你的接口,点进去看内容,好久不再访问才是常态(专业术语叫思考时间),可是这个值的大小,严重影响 tps 的值。那这个值多少合适呢?

我知道的有 2 种做法:

一种是求得 tps 的最大值,在压力测试的时候虚拟用户数不可测,那干脆不管,我就管好我服务的 tps 吞吐量,服务的吞吐量极限就是我的真实极限。

做法就是找一个 tps 最高时的虚拟用户数,记做压力测试的虚拟用户数指标,当然,这有个严重的问题,做过压力测试的就知道,有的服务虚拟用户很低时 tps 很高,但是虚拟用户一但稍有提升,性能下降的非常快,怎么弥补这种情况呢,策略是补区间,得到最好 tps 的虚拟用户之后,在这个虚拟用户数之上加减某个值(例如 30),得到 3 个压力测试结果,3 个压力测试结果的趋势作为服务的性能指标。

第二种是估算,当前服务的 tps 是多少,用压测工具可以得到达到当前 tps 的并发线程数是多少,但这个值肯定也只是一个估计值而已。

多说一句,这个值为什么又可以不去管它:

其实真正线上流量大的时候经常会有一种现象:服务直接重启撑不起来当前流量,调整前端流量分配(部分 nginx 摘除重启 server 等做法),慢慢启动就可以支持起线上流量,再打开所有流量,发现 server 又可以支持没问题了(ps:所以 nginx 有一个流量缓增的收费模块就是干这个的),但是慢慢启动线上流量和一次打过来线上流量,其实在同一时刻虚拟用户数是差不多,斯以为这种现象是因为服务刚启动时流量全打过来时需要创建的可复用复用对象和线程很多,容易造成了服务的不稳定,那么其实压力测试时虚拟用户数重要么?它真的是不可代替的么?

其实虚拟用户数只是用来探测服务性能的一个表现的总结而已,服务真正的健康情况其实反映在线程数,响应时长,服务器负载,性能瓶颈点(比如事务或者锁)等等,而虚拟用户数只是这些健康极限情况的表象总结而已。就是说,当压力测试总结的虚拟用户数在某一个范围值 tps 达到多少,其实内在真正描述的是在这个虚拟用户时,由于线程数是多少,负载是多少,平均相应时长是多少,线程数是多少,gc 稳定程度是多少达到了 tps 值是多少。

4.面试总问的 jvm 调优到底是要干什么?

请注意,jvm 调优,调的是稳定,并不能带给你性能的大幅提升。服务稳定的重要性就不用多说了,保证服务的稳定,gc 永远会是 Java 程序员需要考虑的不稳定因素之一。复杂和高并发下的服务,必须保证每次 gc 不会出现性能下降,各种性能指标不会出现波动,gc 回收规律而且干净,找到合适的 jvm 设置。

说些题外话,面试发现,jvm 调优很多人都没有经验,有人甚至怀疑这东西真正是否有用,有的公司统一 jvm 的设置贯穿所有服务。

其实只是没碰到生产条件复杂的情况而已,举个简单例子:我曾经的公司,碰到过服务运行超过 14h 直接死机的问题,头天下午压测,第二天上午服务自动重启了,按照当时习惯,新服务需要压力测试满 12h,原则上我的服务通过测试,由于测试环境复杂,所有开发都可以登陆而且脚本很多,qa 认为可能是有脚本误杀了,但是当时离上线 deadline 时间还早,于是决定再压力一次,成功复现,最后查看 jvm 发现每次 fullgc 之后 o 区总是会多一点,jmap 打印内存栈发现 char 对象使用逐渐增大,最后撑满内存, 最后定位到调用 JNI 发生内存泄露,解决了这个问题。

这只是简单的一次,在那家公司,由于服务偏算法而且流量很高,碰到过很多这种问题。还有一次,压力测试 loadrunner 图像显示每隔一段时间的点上响应时间立刻下降,过 2s 又恢复正常,规律性很强,通过 jstat 发现频繁生成大对象直接进入老年代,老年代很快撑大触发 full gc 回收,回收时间过长造成服务暂停明显,立刻反应到压测的响应上。解决的办法是调大年轻代,让大对象可以在年轻代触发 yong gc,调整大对象在年轻代的回收频次,尽可能保证大对象在年轻代回收,减小老年代缩短回收时间,服务果然稳定下来。当时这么调整下来会有一点性能损失,基本可以忽略不计,但是提升了服务的稳定性,这才是这次 jvm 调优最重要的。

5.常用的压力测试工具及命令

loadrunner,jmeter,自写 jar 包,tcpcopy 等。

压力工具,大同小异,用什么都行,tcpcopy 是拷贝线上流量,对于已有接口和服务做压力测试是个神器,jmeter 和 loadrunner 是压力测试工具,loandrunner 压测结果更详细可视化不过笨重收费而且需要很多客户机,jmeter 相对是平民版的 loadrunner,胜在免费。之前也有由于数据需要实时从数据库查询,自己写 http 的 client,就需要辅助一些 shell 和 awk 命令统计相应指标。

jmap,jstack,jstat,其实不神秘但是特别实用,jstat 查看内存回收概况,实时查看各个分区的分配回收情况,jmap 查看内存栈,查看内存中对象占用大小,jstack 查看线程栈,死锁,性能瓶颈,某个线程使用 cpu 过高导致服务整体慢等都可以通过在这些命令辅助 Linux 命令看出来。

你的服务是跑在 linux 系统上的,是依赖第三方服务出问题了?是受别的服务影响还是自己利用资源过高?是网络抖动了?是网卡满了么?是 cpu 性能不够么?是写入磁盘瓶颈了?内核数据交换频繁?负载变高了?都需要 linux 命令才能看出来。

6.性能诊断到底难在哪里?

收到服务报警了,怎么办?打印的 log 日志都是连接不上 memcache,难道是 memcache 的问题,手动客户端连接 memcache 没问题,难道是网络的问题,测试网络延迟很低,那到底怎么了?

其实服务类似于人体,有的人感冒的时候鼻子通气嗓子疼,有的人头疼,有的人流清涕,有的人流黄涕,对症下药要治标治本。没有什么统一的答案,这就体现了经验的重要性。

举个栗子:某天晚上突然收到报警,vpn 登陆发现服务还正常返回,暂时没有报错,但是负载明显升高,resin 线程数飙升到 1000 多(正常情况下该服务高峰期线程数 500-700),cpu 使用率偏高,排查:

1.访问量激增?统计发现并没有。

2.网络状况异常?通过访问服务器发现也没有,稍微慢些是因为负载稍高。

3.程序有瓶颈?打印内存栈线程栈都没发现

4.受其他同宿主服务影响?查看监控发现并没有。

仔细观察发现流量稍有波动但是不明显。为什么负载高呢?最后排查发现是前端 nginx 带宽满了,带宽拥堵造成代理的后端服务无法及时返回数据,后端服务的句柄数拥堵造成服务器负载升高,服务器负载升高又使线程数和 cpu 利用率升高,造成服务的个别访问响应时长过长,触发报警。再严重些估计就会造成连接 memcache 超时,log 打出连接 memcache 错误的日志。蝴蝶效应而已。想要快速抓住重点,其实跟医生一样,就需要你对服务足够了解,平时多关心服务状态而且经验真的很重要。

7.到底是加机器还是优化服务?

成本,加机器是一种成本,优化服务也是一种成本,很有可能你的服务很多依赖第三方,推动他们符合你的要求也是一种沟通成本,很多时候,老板的思路永远在于成本,如果他认为服务有很大的优化空间,那你找他加机器他多半是不会同意的,所以这种要资源的事情,请考虑成本,也有一个问题,大公司往往会哭的才有奶吃,这也很现实,反正归根到底,对于我们这些搞服务端的来说,成就感不就应该是把硬件服务器资源压榨到底么。

小伙伴们有兴趣想了解内容和更多相关学习资料的请点赞收藏+评论转发+关注我,后面会有很多干货。
我有一些面试题、架构、设计类资料可以说是程序员面试必备!所有资料都整理到网盘了,需要的话欢迎下载!私信我回复【07】即可免费获取

原文出处:xie.infoq.cn/article/6556e02afd68c51ccf1ec1c62

java 面试 jvm 调优的意义 _java 培训相关推荐

  1. java面试jvm调优的意义

    压力测试的理解,xxx的性能10w/s,对你有意义么? 没有那家卖瓜的会说自己家的不甜,同样,没有哪个开源项目愿意告诉你在对它条件最苛刻的时候压力情况是多少,一般官网号称给你看的性能指标都是在最理想环 ...

  2. java面试-JVM调优和参数配置

    JVM的参数类型: 1.标配参数: java -version java -help 2.X参数: -Xmixed 混合模式 -Xint  解释执行 -Xcomp 第一次使用就编译成本地代码 3.XX ...

  3. JAVA之JVM调优-从eclipse开始

    一.概述 什么是jvm调优呢?jvm调优就是根据gc日志分析jvm内存分配.回收的情况来调整各区域内存比例或者gc回收的策略:更深一层就是根据dump出来的内存结构和线程栈来分析代码中不合理的地方给予 ...

  4. java面试 系统调优_面试官:Java性能调优你会多少?一个问题就把我问的哑口无言,哭了!...

    一.前言 什么是性能调优? 性能调优其实很好理解,就是优化硬件.操作系统.应用之间的一个充分的协作,最大化的发挥出硬件的极致性能,来应对高负载的业务需求. 为什么需要性能优化? 其实说到底就是两个原因 ...

  5. Java虚拟机jvm 调优总结

    一.相关概念 基本回收算法 引用计数(Reference Counting) 比较古老的回收算法.原理是此对象有一个引用,即增加一个计数,删除一个引用则减少一个计数.垃圾回收时,只用收集计数为0的对象 ...

  6. [jvm][面试]JVM 调优总结

    说明: 以下的总结内容适用于jdk8以下的版本. jdk8已经移除了永久区(PermGen) 堆大小设置 JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制:系 ...

  7. Java之JVM调优案例分析与实战(1) - 高性能硬件上的程序部署策略

    本JVM系列均来源于<深入理解Java虚拟机>一书中,版权归该书作者所有. 环境:一个15万PV/天左右的在线文档类型网站最近更换了硬件系统,新系统硬件为4个CPU.16GB物理内存.OS ...

  8. Java之JVM调优案例分析与实战(5) - 服务器JVM进程奔溃

    环境:一个基于B/S的MIS系统,硬件为2个CPU.8GB内存的HP系统,服务器是WebLogic9.2(就是第二个案例中的那个系统).正常运行一段时间后,最近发现在运行期间频繁出现集群节点的虚拟机进 ...

  9. Java面试必问JVM调优,那.NET5呢?

    JVM调优已经是普通Java工程师的必修课了,而.NET开源快5年了,CLR层面的优化到目前都不多见,甚至常用的性能调优工具都还没玩过..NET5马上来了,要想在互联网大潮中逆袭,光靠平台是不够的,开 ...

最新文章

  1. php session获取不到的解决方法
  2. centos部署openstack--网络规划(openvswitch的安装)
  3. AngularJs 常用指令标签
  4. 如何在程序中不用加号实现加法_程序员那些事 | JavaScript基础(六)
  5. python问卷调查系统设计案例_从设计到施工,全面剖析超级玻璃屋面系统案例!...
  6. ip_conntrack: table full, dropping packet的问题
  7. 古典绘画水墨文化艺术插图手绘合集,再也不愁没有设计灵感!
  8. Python入门-Python中的包,impot,from,import
  9. 漫画:996的本质是什么?
  10. Python中的while循环
  11. 求正整数2和n之间的完全数
  12. 大厂纷纷押宝“元宇宙”“鸡肋”智能眼镜难成密钥
  13. win10点一个程序要很久才响应解决方法
  14. ArcGIS——GIS中的坐标系
  15. R语言实现SOM(自组织映射)模型(三个函数包+代码)
  16. 玩客云刷甜糖(2022-7-26亲测)
  17. th标签内的Cannot resolve ‘msg‘爆红出现的问题
  18. 网络营销的手段有哪些?(二)
  19. iPad Air越狱白苹果怎么办?越狱白苹果修复教程
  20. matlab轴向柱塞泵动力学仿真,斜盘式轴向柱塞泵柱塞副油膜特性研究

热门文章

  1. .gz 与.tar.gz解压区别
  2. CMOS反相器的工作原理和电路结构
  3. chi2inv函数 matlab_MATLAB概率统计函数(1)
  4. MicroBlaze:Xilinx官方软核学习与一些实验测试
  5. Unity Spine动画中Complete 委托 、事件、缓存 += -= 委托
  6. 第十届CCF大数据与计算智能大赛总决赛暨颁奖典礼在苏州吴江顺利举办
  7. 思维导图MindManager的文件格式与例图
  8. Android bluetooth介绍(一):基本概念及硬件接口
  9. IDEA打包war,并部署在Tomcat
  10. QTS5.0 不用docker 手动安装wordpress