首页 > 其他分享 >应用层性能优化思路及方法

应用层性能优化思路及方法

时间:2024-11-10 10:08:04浏览次数:5  
标签:流程 方法 性能 耗时 arthas 思路 优化 应用层

性能优化思路

性能优化的实质

  • 去除大量重复、不必要的操作。
  • 并发、批量操作。

重复操作:

  • 重复创建同一个对象;
  • 以相同参数重复调用同一个接口;
  • 重复上传或下载同一个文件;
  • 重复编译正则表达式;
  • 重复获取一个规则集或数据集;
  • 重复走一个流程。

性能优化的思路

  • 过滤去重:除去不需要处理的,适合小成本
  • 缓存:从更邻近的地方预先获取,预编译
  • 分治:缩小搜索范围
  • 并发:同时进行
  • 批量:一次处理多个
  • 非阻塞:避免无效等待
  • 精简:去除重复和非必要

性能优化的“拦路石”

性能优化的“拦路石”:

  • 高并发。比如检测任务创建去重。要应对高并发,就需要限流、加锁,就会导致阻塞,阻塞就会导致性能开销。这些加锁和限流只是针对少量极限场景,在大多数时候只是白白浪费资源。
  • 少数场景。为了逻辑的完善,需要应对少量场景。比如 新上报的告警消息晚于上报的告警修复消息,需要走修复流程,会先把告警修复消息存在 redis, 然后在告警上报时访问 redis 去做修复。但是对于绝大部分场景而言,都用不到,白白增加一次 redis 访问开销。要检查是否有其它可替代方案,比如对于这种新上报的告警消息晚于上报的告警修复消息使用延迟队列消费。
  • 代码编写。比如 lambda 会打断 arthas trace 的方法栈调用,导致工具无法分析完整的方法调用栈耗时。
  • 网络波动。难以控制。

解决性能问题的途径

从根本层面来说,解决性能问题的途径有三种:

  • 更好的数据结构与算法(时间复杂度的降低);
  • 更少的等待时间(精简流程、优化 IO 访问);
  • 更好的逻辑组织(串行改并发)。

绝大部分性能问题的求解,从底层来看,无非就是 数据结构与算法、等待时间、逻辑组织的优化改进,反映在应用层就是各种具体技术措施手段。

实战方法

工欲善其事,必先利其器。性能优化靠的是工具和洞察力。工具能够有效揭示异常迹象,而洞察力能够敏锐意识到问题之所在。

工具与测量

性能优化的首要步骤不是去做代码分析,而是去测量出“热点区域”,有针对性地优化,才能让 ROI 最大化。

全链路

arthas

  • 对于 RT 持续较高的方法,使用 arthas trace 跟踪方法调用栈耗时,进一步分析和定位热点区域。
  • 对于 RT 较低但波动较大且有明显规律的方法,使用 arthas tt 命令针对耗时大的调用进行分析,看看是否与特定情形有关。
  • 对于 RT 较低但波动较大且无明显规律的方法使用, arthas monitor 监控方法的平均 RT,同时监控 DB 或 API 耗时,看看是否与DB或外部服务有关。
  • 使用 top ,arthas thread 确定 CPU 高的代码区域。

可以有明显效果的方法(> 50%)

适合在完成初始设计和实现的情形下使用。通常是整体结构性改善。

  1. 优化存储结构。如果数据和存储设计不够好,在外围做再多优化,效果也是有限的。
    (1)表的记录数量应当与表实体的维度匹配。比如文件上传依赖文件 MD5 ,就只与不重复MD5的数量有关。
    (2)合适的分表、分库、分片、分区(详情与查询分离,按时间分表、冷热分表、按业务维度分表)。
    (3)读写分离。数据库写,使用 ES 或 HBase 读。
  2. 检查和添加必要的索引。索引区分度、最左匹配准则、覆盖索引、索引命中率等。
  3. 加缓存,避免不必要的重复流程和工作量。缓存时间和大小需要仔细设定,需要考虑内存开销,避免缓存时间或大小过大。
  4. 数据结构与算法改进,多重循环降重。通常是构建一个Map,然后从Map中取值。
  5. 单个改批量。批量查询,提供批量接口,批量处理方式。
  6. 串行改并发。相互独立的子数据集的处理,可以并发执行然后汇总。
  7. 同步改异步。耗时较长的次要流程,可以改成异步,加速主流程的消费。
  8. 阻塞改非阻塞。
  9. 中间件优化。
  10. 添加更多的服务实例。动态扩容。服务支持无状态。
  11. 添加更多的CPU和内存。

可以只保留必要的流程,去掉那些 RT 波动比较大的方法,如此可以测试出性能的上限,作为一个可追求的性能目标。

性能微调的方法( < 30%)

适合在结构已经稳定的情形下使用。

  1. 简化流程,合并 IO 和 API 调用。比如获取告警详情,需要获取告警的各项信息。初期为了可维护性,每个方法都查询一次告警对象。实际上应该是在入口处查一次,然后在 Context 里传递。
  2. 去除重复的调用和计算。
  3. 去除不必要的操作和流程。比如病毒检测流程有一个告警去重过程,但阻断类的病毒检测流程也会走到这里,实际上并不需要。这是因为走到这个流程的条件比较宽泛,需要再限定一下。
  4. 耗时区域后移。如果一个操作必须在某个条件满足后才能执行,应该把这个操作移到条件判断满足之后。
  5. 查询数据库时,则只查询所需要的字段。避免 select *。
  6. 调节线程池参数。
  7. 调节中间件参数,比如数据库连接池、消息队列消费参数。
  8. 针对业务特殊性做特殊处理。
  9. 分布式锁之前加缓存【存疑】。
  10. 悲观锁改乐观锁。减少悲观锁的锁定范围;使用版本号机制替代直接加锁。

提升检测流程吞吐量的途径

  • 存储设计优化,去掉不必要的字段和大对象,减少占用空间;
  • 黑白名单,快速过滤;
  • 快速去重过滤;
  • 加缓存(有一定风险),减少 API 调用次数和查询数据源的次数;
  • 尽可能去除 RT 波动较大的方法;
  • 精简流程;
  • 减少大对象序列化与反序列化。

辅助方法

  1. 拆分。拆分不会直接带来性能改善,但是能够分离出性能热点区域,为性能优化做好铺垫。

排查命令

查看 CPU 、内存、负载概况

top
top -Hp pid

查看 mongo 慢查和 CPU 高

db.setProfilingLevel(1, 50);
db.system.profile.find().sort({$natural:-1}).limit(5)
db.getProfilingStatus()

db.runCommand({shardConnPoolStats:1})

arthas 启动和停止


su -s /bin/sh -c 'java -jar arthas-boot.jar' titan

java -jar arthas-client.jar 127.0.0.1 3658 -c "stop"

方法 RT 监控(整体视角)

monitor -c 1 xxx.ids.components.DuplicateDetectionFilter process -n 10000

monitor -c 1 xxx.IdsCdcTaskScheduler$Consumer consume -n 10000

monitor -c 1 xxx.IdsCdcTaskScheduler$IdsCdcTaskSender run -n 10000

方法耗时跟踪(定位热点,耗时长定位)

trace com.qt.eventflow.definitions.BizComponent process -m 60 '#cost>20'

trace xxx.ids.components.DuplicateDetectionFilter process  -n 10000 --skipJDKMethod false

tt -t xxx.ids.components.DuplicateDetectionFilter process  -n 10000
tt -i t_index

耗时统计

awk -F'=' ' $4 > 50 {print } ' rt_costs.txt > rt_50_costs.txt 

awk -F'=' '  {print $3} ' rt_costs.txt | sed 's/, cost_time//g' | sort | uniq -c | awk '{print $2" "$1}' | sort -rnk2

参考资料

标签:流程,方法,性能,耗时,arthas,思路,优化,应用层
From: https://www.cnblogs.com/lovesqcc/p/18537678

相关文章

  • 做AI大模型应用层产品研发,基本绕不开这几个大模型API
    国内有不少独立模型厂商提供API可供调用,几乎都会成为技术选择的可选项:MoonshotAI:API特点:其API与OpenAI兼容,方便开发者平滑迁移,开发者无需对代码做除基本参数外的“额外”修改,即可体验到Moonshot模型的能力。经过一段时间内测后已启动公开测试,所有开发者都可登......
  • C++代码优化(二): 区分接口继承和实现继承
    目录1.引言2.接口继承3.实现继承4.如何选择接口继承与实现继承5.完整实例6.总结1.引言        在C++中,区分接口继承和实现继承是一种良好的编程实践,有助于提高代码的可维护性、可读性和可扩展性。接口继承通常指的是从基类继承纯虚函数(purevirtualfunctions......
  • AI 扩展开发者思维方式:以 SQL 查询优化为例
    在现代软件开发中,AI技术的兴起让开发者的思维方式发生了显著变化。尤其是在SQL查询优化、代码重构以及算法设计等领域,AI提供的建议不仅扩展了开发者的思考路径,还帮助他们发现以往没有意识到的潜在解决方案。1.传统思维模式下的SQL查询过去,开发者在编写SQL查询时通常......
  • 关于 DP 的非常规优化
    感觉这个东西就是玄学啊,考场上真的有人能想得出来嘛。(还是我太菜了qwq)思想现在见到的有这几种:从\(i\)推到\(i+1\)时状态改变的数量不会太多,直接继承可以优化。可能对答案有贡献的状态不会太多。即通过一些性质来消除掉冗余状态以保证时间复杂度。ABC176FBraveCH......
  • 优化布线拥塞
    Note:文章内容以Xilinx系列 FPGA进行讲解    随着设计规模的增大和复杂度的提升,布线拥塞成为常见的问题,尤其是在用UltraScaleFPGA或UltraScale+FPGA时,布线拥塞往往成为时序收敛的瓶颈,也成为编译时间过长的“罪魁祸首”。1、布线拥塞的三种类型    ......
  • 【论文系列】DDIM ---DDPM上的优化
    WhatDDIM是啥?DDIM(DenoisingDiffusionImplicitModels)是一种扩散模型的变体,旨在加速图像生成过程并保持生成质量。它是在DDPM(DenoisingDiffusionProbabilisticModels)的基础上发展出来的,提供了一种更高效的去噪采样过程,减少了采样所需的步骤数量。WhyDDIM提出了能干啥?DD......
  • 如何进行数据库连接池的参数优化?
    以下是进行数据库连接池参数优化的一些方法:一、确定合适的初始连接数:考虑因素:数据库的规模、应用程序的启动需求以及预期的初始负载。如果数据库规模较小且应用程序启动时对数据库的即时访问需求不高,可以将初始连接数设置得较少,比如3到5个;如果数据库较大或应用启动后很快......
  • 六、MyBatis-Plus高级用法(1):最优化持久层开发
    一、MyBatis-Plus快速入门1.1简介课程版本:3.5.3.1MyBatis-Plus......
  • 浅谈单片机的gcc优化级别__以双音频信号发生器为例
    IDE:  CLionHOST: Windows11MinGW:x86_64-14.2.0-release-posix-seh-ucrt-rt_v12-rev0GCC: arm-gnu-toolchain-13.3.rel1-mingw-w64-i686-arm-none-eabi一、简介        gcc有多种优化级别,一般不选择的情况下,IDE默认是按照-Og或这-O2优化的。        ......
  • 计算机图形学论文 | 木工设计与制造计划的共同优化
    ......