【腾讯TMQ】抽丝剥茧定位Windows客户端CPU占用问题

2024-04-14 04:38

本文主要是介绍【腾讯TMQ】抽丝剥茧定位Windows客户端CPU占用问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

摘要

本文主要展示了从电脑管家CPU占用过高问题发现到解决的全过程。包括分析问题的思路、解决问题的方法、压力测试的设计、优化前后数据对比等。同时,在末尾分享了自动弹窗工具的设计思路,以及笔者对于测试自动化的一些思考和看法。

一、导火索

某天,我们接到一例用户反馈——问题的核心的在于管家在没有触发任何漏洞、扫毒、垃圾清理和体检的场景下,却占用了比较高的CPU资源。截图如下:

但是这个问题在测试过程中是从未出现,而且从用户反馈的场景描述中,也提取不出必现路径和关键逻辑。为此,我们主动联系该用户,在用户许可并且积极配合的前提下,获取其真实的机器环境和场景,抓取相关的管家信息,从而进一步进行分析和定位。

二、定位分析

联系用户抓取ETL文件进行分析(该工具的使用可参见微软官网申明:https://msdn.microsoft.com/library/windows/hardware/mt270977(v=vs.85).aspx)。

从收集上来的etl性能日志来看,CPU的异常主要是由管家进程的:A.dll(消耗大概10%的CPU)、B.dll(消耗大概16%的CPU)、C.dll(消耗大概7%的CPU)这三个模块影响,定位到模块之后,继续向下深挖,定位到三个模块下的具体函数调用关系链时,我们发现这三个模块下,资源占用最高的函数都有一个共同点,那就是他们都是通过微软的API-SetWinEventHook函数向系统注册的回调函数。
SetWinEventHook函数本质是windows系统向外提供的一种消息处理机制,每当有特定消息发出后,在目标应用程序处理该消息之前,SetWinEventHook程序就会先捕获该消息,提前调用注册的回调函数处理并可以决定是否继续将消息往下传送。具体有关于SetWinEventHook的使用可参见https://msdn.microsoft.com/en-us/library/dd373640(VS.85).aspx官方使用文档说明。这里不再展开讨论。
由于每个模块调用SetWinEventHook进行注册的回调函数都不相同,其消息的过滤策略以及内部逻辑都不一样,所以其占用的CPU的数值会有所区别。其中占用最高的B.dll模块是因为没有处理好窗口消息的过滤,A.dll模块其实本身对于消息的过滤机制处理的较为完善,之所以占用CPU比C.dll要高一些的原因在于A.dll的回调函数处理中,某个注册表读取的操作消耗了资源。
那排除三个模块业务上的干扰的因素,我们提取问题的核心本质:当三个模块同时都注册了SetWinEventHook到底会造成什么结果?为什么会让管家一直占用如此高的CPU资源?为什么用户机器会出现高占用,而测试机器却没有呢?
相信下面抽象出来的模型图,能够很清晰的展现出问题的本质。

由此可见,每一个窗口消息过来之后,windows相当于调用三次管家的模块进行处理。如果用户的windows消息数量处于某临界值以下时,问题的表现并不明显,而一旦用户机器上有某进程不停的创建窗口消息,那将导致管家一直在处理消息函数,从而占用大量的系统资源。

三、复现场景

猜测是用户环境中,某一软件在频繁的创建窗口消息,从而导致SetWinEventHook函数不停的向注册的回调函数分发数据,每一个分发的数据都需要一定的处理时间,占用一定的CPU资源,因此从用户感知的层面,就出现管家CPU一直占用过高的情况。为此,我们测试方开发了一个小软件,用于模拟在电脑上频繁创建窗口。虽然没有完全复现出用户CPU占用情况,但是可以看出当窗口数骤然剧增时,管家Tray进程的占用量也明显增加。

四、解决方案

4.1不同角色任务分配
4.1.1开发侧:
(1)、优化窗口消息处理模块代码,由A.dll模块提供公共模块用于注册窗口监听事件,统一管理;
(2)、A.dll持续优化窗口信息过滤模式。
4.1.2测试侧:
(1)、SetWinEventHook加入代码扫描规则—所有管家代 码中,只允许出现一次调用该函数的场景(即A.dll中);
(2)、增加对于弹窗功能的压力测试和性能测试。
4.2 代码逻辑优化
SetWinEventHook是由微软提供的系统api,其本身触发管家回调函数,进行消息处理的逻辑是没有问题的,因此我们重点要优化的是管家对于回调消息的处理逻辑:由于A.dll模块在窗口消息过滤方面比较完善,其CPU占用较高的原因是由于回调函数内部有一个读取注册表的操作,当不断接受窗口消息时,就会引发其不断的进行注册表读取操作,从而引其高CPU的占用。当A.dll解决掉注册表的性能后,其注册SetWinEventHook的功能所占用的CPU是一个可接受的范围内。因为A.dll下的窗口信息接收和过滤能力是经过几轮优化后,被实践证明其功能实现已经是比较成熟的。因此各个业务方不再自己独立进行窗口监听,而是统一由A.dll中注册和监听窗口消息。
优化后的处理流程:

窗口消息的注册监听统一由A.dll模块管理,由于其冗余消息的过滤策略比较完善,由A.dll来统一管理并获取窗口信息分发给各业务,可以大幅减少各个业务获取窗口或者宿主进程信息的次数。

五、压力测试

当上述优化项改动完成基本的功能测试后,为了便于以后能实时发现和解决窗口弹窗过多的问题,我们开发了一个简单的弹窗小工具,对管家进行压力测试(具体工具的设计和使用见附录)。
1、短时间内触发多个弹窗,抓取PC的etl文件进行分析。
以约5-7s内触发100个窗口为例,抓取同一PC修改前后的管家版本的etl进行分析,连续抓取10次后,查看管家进程占用CPU数据。抓取数据波动比较稳定的时刻,进行压力测试场景,抓取etl文件,分析优化前后tray资源的占用情况:初始模块,弹窗压力测试下,抓取数据波动比较稳定的情况下,tray占用cpu的权重大约为6%-8%之间,如下图:

替换优化后的模块,再进行弹窗压力测试,tray占用的cpu的权重下降到2%左右,如下图:

抓取10次数据对比图:

由上述对比图可以发现,在不停触发弹窗的场景下,可以明显感知到,优化后,tray进程的CPU占用资源明显下降。由此,该弹窗工具既可以在一定程度上复现用户电脑出现的场景,又可以验证我们针对本次CPU占用过高的问题的解决措施的有效性。

六、总结和思考

6.1、总结:

6.2、思考:
用户的环境的复杂度会远超于我们测试时的环境,对于用户反馈的Bug,尤其是测试环境无法复现的Bug要重点关注,抽丝剥茧、层层分析背后的原因,并且根据分析后的结果,迅速采取强有效的措施解决。
同时,又要及时吸取经验教训,通过各种手段(如codereview、压力测试等)保证该问题不会重复出现。同时,在以后的测试分析场景中,对于类似的一些功能,也需要考虑到可能会导致CPU升高的一些特殊场景。
最后,便是自动化的实现。自动化测试作为软件测试的一种技术手段,常常会被想象成是测试人员走向人生巅峰的必备技能,从而导致其重点在于自动化而非测试本身,容易陷于解决技术问题,而忽略了其结果是否能满足测试的需要。在此,笔者推荐测试专家JamesA.Whittaker提出过的测试构建方法:寻找缺陷—提炼模式—识别机械部分–开发工具。详细思路可见笔者附录:弹窗工具的设计。

附:弹窗工具的设计

此附录为笔者参考测试专家JamesA.Whittaker和史亮所提到过的测试工具构建方法和自动化弹窗工具设计实践结合的展示,希望能带给大家一个新的看待自动化的视角:

1、寻找缺陷:发现或收集软件的缺陷or问题。

本次发现的问题是管家客户端CPU占用过高问题。

2、提炼模式:分析缺陷的根本原因,提炼一个模式,用它捕获相似的缺陷,一个模式就相当于一种攻击手段,这个过程需要回答如下几个问题:

(1)何时实施该攻击?
管家安装完成并正常运行。

(2)该攻击会捕获何种问题?

该攻击会导致管家进程的CPU占用资源飙升。

(3)利用该攻击如何识别软件问题?

执行该攻击的同时抓取windows的性能日志文件ETL,通过ETL文件分析管家的资源占用情况,识别攻击是否会引发软件异常问题。

(4)如何实施攻击?

短时间内生成大量的windows窗口消息。

(5)样例和分析?

参见前文提到过的问题和分析。

3、开发自动化工具:识别出攻击过程中机械的部分,编写工具去自动化模式的应用。
此处的测试自动化不是自动的执行测试用例,而是提供计算机辅助功能,其目的是让计算机完成高负荷的运算,让人专注于富有智力挑战的任务。
首先,识别本次攻击过程的机械部分—毫无疑问就是如何产生大量的windows窗口信息。
是否需要自动化:需要。
原因:
1、大量的windows消息包含大量重复性的创建or显示or关闭等等一系列的操作;
2、手工的点击速度完全无法模拟机器在短时间内产生大量窗口信息(通过代码可能1s就可以创建100个窗口,而手工点击最多也就也就两三个)。
自动化弹窗工具设计流程,如下图:

使用说明:
通过OpenParaOfWindows.txt中的三个参数和可以灵活的配置不同的弹窗场景。
其参数说明:详见附件中的使用说明(附件扫码下载)。

这篇关于【腾讯TMQ】抽丝剥茧定位Windows客户端CPU占用问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/902090

相关文章

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

缓存雪崩问题

缓存雪崩是缓存中大量key失效后当高并发到来时导致大量请求到数据库,瞬间耗尽数据库资源,导致数据库无法使用。 解决方案: 1、使用锁进行控制 2、对同一类型信息的key设置不同的过期时间 3、缓存预热 1. 什么是缓存雪崩 缓存雪崩是指在短时间内,大量缓存数据同时失效,导致所有请求直接涌向数据库,瞬间增加数据库的负载压力,可能导致数据库性能下降甚至崩溃。这种情况往往发生在缓存中大量 k

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

在 Windows 上部署 gitblit

在 Windows 上部署 gitblit 在 Windows 上部署 gitblit 缘起gitblit 是什么安装JDK部署 gitblit 下载 gitblit 并解压配置登录注册为 windows 服务 修改 installService.cmd 文件运行 installService.cmd运行 gitblitw.exe查看 services.msc 缘起