前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >大厂的性能调优策略

大厂的性能调优策略

原创
作者头像
JavaEdge
修改2025-01-13 19:33:27
修改2025-01-13 19:33:27
2290
举报

0 前言

面对日渐复杂的系统,制定合理的性能测试,可以提前发现性能瓶颈,然后有针对性地制定调优策略。即:

  • 测试
  • 分析
  • 调优

咋制定系统的性能调优策略呢?

1 性能测试攻略

性能测试是提前发现性能瓶颈,保障系统性能稳定的必要措施。下面我先给你介绍两种常用的测试方法,帮助你从点到面地测试系统性能。

1.1 微基准性能测试

微基准性能测试可精准定位到某模块或某方法的性能问题,适合做一个功能模块或一个方法在不同实现方式下的性能对比。如对比一个方法使用同步实现和非同步实现的性能。

1.2 宏基准性能测试

宏基准性能测试是一个综合测试,需要考虑到测试环境、测试场景和测试目标。

先看测试环境,需模拟线上真实环境。

再看测试场景。需确定在测试某接口时,是否有其他业务接口也在平行运行,造成干扰。若有,请重视,一旦忽视这种干扰,测试结果就会出现偏差。

最后看测试目标。性能测试要有目标,可通过吞吐量及响应时间衡量系统是否达标:

  • 不达标,就优化
  • 达标,就加大测试并发数,探底接口的 TPS,这可深入了解接口性能。除了测试接口的吞吐量和响应时间以外,还需循环测试可能导致性能问题的接口,观察各个服务器的 CPU、内存以及 I/O 使用率的变化

性能测试存在干扰因子,使测试结果不准确。所以,做性能测试时,还要注意一些

2 问题

2.1 热身问题

做性能测试时,系统会运行越来越快,后面访问速度要比第一次访问快几倍,为啥?

所以刚开始运行的阶段,虚拟机会花费很长时间来全面优化代码,后面就能以最高性能执行了。

这就是热身过程,如果在进行性能测试时,热身时间过长,就会导致第一次访问速度过慢,你就可以考虑先优化,再进测试。

2.2 性能测试结果不稳定

性能测试时发现,每次测试处理的数据集都一样,但测试结果有差异。因为测试时,伴随很多不稳定因素,如其他进程影响、网络波动及每个阶段 JVM 垃圾回收的不同等。

可多次测试,将测试结果求平均或统计一个曲线图,只要保证平均值在合理范围内,而且波动不大,性能测试就是通过。

2.3 多 JVM 情况下的影响

若服务器有多个 Java 应用服务,部署在不同 Tomcat,即我们的服务器有多个 JVM。任一 JVM 都拥有整个系统的资源使用权。

若一台机器上只部署单独的一个 JVM,做性能测试时,测试结果很好或你调优效果很好,但在一台机器多个 JVM就不一定。所以尽量避免线上环境中一台机器部署多个 JVM。

3 合理分析结果,制定调优策略

分析和调优结合。

完成性能测试后,需输出一份性能测试报告,帮分析系统性能测试情况。测试结果需包含测试接口的avg、max和min吞吐量,RT,CPU、内存、I/O、网络 IO 使用率,GC频率等。

观察这些调优标准,可发现性能瓶颈,再自下而上分析查找问题:

  • 先从os层面,查看系统 CPU、内存、I/O、网络使用率是否异常,再命令查找异常日志
  • 还可从 Java 应用的 JVM 层面,查看 JVM 的垃圾回收频率及内存分配情况是否异常
  • 都没异常,可查看应用服务业务层是否存在性能瓶颈,如 Java 编程问题、读写数据瓶颈等

分析查找问题可自下而上,解决系统性能问题,则可自上而下逐级优化。

从应用层到os层的几种调优策略。

3.1 优化代码

应用层的问题代码往往因耗尽系统资源而暴露。如某段代码导致内存溢出,往往将 JVM 中内存用完,这时系统内存资源消耗殆尽,同时也引发 JVM 频繁GC,导致 CPU 100% 居高不下,这时又消耗了系统 CPU 资源。

还有非问题代码导致性能问题,难发现,需经验优化。如LinkedList 集合,如用 for 循环遍历该容器,将大大降低读效率,但这种效率降低很难导致系统性能参数异常。

有经验的改用 Iterator (迭代器)迭代循环该集合,这是因为 LinkedList 是链表实现的,如果使用 for 循环获取元素,在每次循环获取元素时,都会去遍历一次 List,这样会降低读的效率。

3.2 优化设计

如设计模式可优化业务层及中间件层代码设计:

  • 不仅精简代码
  • 还能提高整体性能

如单例模式在频繁调用创建对象的场景中,可共享一个创建对象,这样可以减少频繁地创建和销毁对象所带来的性能消耗。

3.3 优化算法

3.4 时间换空间

系统对查询速度无很高要求,而对存储空间要求苛刻,考虑时间换空间。

如String 对象的 intern 方法,可将重复率比较高的数据集存储在常量池,复用一个相同对象,大大节省内存存储空间。但由于常量池使用的是 HashMap 数据结构类型,如果我们存储数据过多,查询的性能就会下降。所以在这种对存储容量要求比较苛刻,而对查询速度不作要求的场景,我们就可以考虑用时间换空间。

3.5 空间换时间

这种方法是使用存储空间来提升访问速度。现在很多系统都是使用的 MySQL 数据库,较为常见的分表分库是典型的使用空间换时间的案例。

因为 MySQL 单表在存储千万数据以上时,读写性能会明显下降,需将表数据通过某字段 Hash 值或其他方式分拆,系统查询数据时,根据条件的 Hash 值判断找到对应表,因为表数据量减小,查询性能提升。

3.6 参数调优

以上业务层代码优化。JVM、Web 容器及os优化也关键。

根据业务场景,合理设置 JVM 的内存空间以及垃圾回收算法可以提升系统性能。如业务创建大量大对象,可通过设置,将这些大对象直接放进老年代。可减少年轻代频繁发生小的垃圾回收(Minor GC),减少 CPU 占用时间,提升系统性能。

Web 容器线程池设置及 Linux 操作系统的内核参数设置不合理也有可能导致系统性能瓶颈,根据自己的业务场景优化这两部分,可提升系统性能。

4 兜底策略

确保系统稳定性。

4.1 限流

对系统的入口设置最大访问限制。这里可以参考性能测试中探底接口的 TPS 。同时采取熔断措施,友好地返回没有成功的请求。

4.2 智能化横向扩容

可保证当访问量超过某一个阈值时,系统可以根据需求自动横向新增服务。

4.3 提前扩容

应用于高并发系统,例如,瞬时抢购业务系统。这是因为横向扩容无法满足大量发生在瞬间的请求,即使成功了,抢购也结束了。

目前很多公司使用 Docker 容器来部署应用服务。这是因为 Docker 容器是使用 Kubernetes 作为容器管理系统,而 Kubernetes 可以实现智能化横向扩容和提前扩容 Docker 服务。

5 总结

性能测试分为:

  • 微基准性能测试:前者可精准调优小单元的业务功能
  • 宏基准性能测试:后者可结合内外因素,综合模拟线上环境来测试系统性能

两种方法结合,可以更立体地测试系统性能。测试结果可制定性能调优策略,调优方法很多,这里就不一一赘述了。调优策略千变万化,但思路核心一样:从业务调优到编程调优,再到系统调优。

任何调优都需要结合场景明确已知问题和性能目标,不能为了调优而调优,以免引入新 Bug,带来风险弊端。

FAQ

Q:电商系统,新品上线,还有抢购活动,哪些功能做微基准性能测试,哪些做宏基准性能测试?

A:新品上线需要对系统基础功能、尤其是上线涉及改动、有耦合的业务做宏基准测试,如:用户服务、商品服务、订单服务、支付服务、优惠券服务等。从而保证支撑抢购活动的服务正常运行

针对抢购活动,做微基准测试以验证服务是否达预期。留意qps、内存、cpu、网络带宽、线程堆栈等指标是否达标。不仅考虑单机性能,更要拓展到集群时性能的阈值能达到多少从而给出更加准确的性能测试评估报告。

考虑服务质量,测出抢购活动的瓶颈,方便开发、运维团队制定更好的服务限流、降级、动态伸缩等方案。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 0 前言
  • 1 性能测试攻略
    • 1.1 微基准性能测试
    • 1.2 宏基准性能测试
  • 2 问题
    • 2.1 热身问题
    • 2.2 性能测试结果不稳定
    • 2.3 多 JVM 情况下的影响
  • 3 合理分析结果,制定调优策略
    • 3.1 优化代码
    • 3.2 优化设计
    • 3.3 优化算法
    • 3.4 时间换空间
    • 3.5 空间换时间
    • 3.6 参数调优
  • 4 兜底策略
    • 4.1 限流
    • 4.2 智能化横向扩容
    • 4.3 提前扩容
  • 5 总结
  • FAQ
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档