由于高传入流量导致 Web 应用程序失败的案例很多。这些主要是由于系统复杂、测试不充分、对系统依赖性了解不足、系统过载、资源耗尽以及复杂的故障恢复例程。
我们可以采取必要的步骤来避免故障,并通过执行性能测试更好地了解应用程序的局限性。
性能测试(PT)有助于确定系统和应用程序在预期负载下的限制。它还有助于微调应用程序,以确保应用程序稳定、可扩展,并在最佳资源利用率下始终如一地执行。
性能测试是应用程序生命周期中非常重要的一个方面。当正确进行 PT 时,它会考虑响应时间、可扩展性、停机时间、基础设施成本等因素,确保应用程序在最佳条件下运行。 PT 将有助于早期发现瓶颈并使团队修复它们。
应用程序的 PT 是多方面的,但可以大致分为 API 测试和应用程序测试两种类型。
1.API 测试-用于测量响应时间,分析托管和支持应用程序的基础架构。
2.应用程序测试-测试应用程序对其安装的设备的影响。例如,考虑一个旨在在 iOS 或 Android 设备上使用的应用程序。需要完成完整的应用程序测试,以确保安装此应用程序不会降低设备的整体性能(例如电池消耗、系统频繁挂起)。
在本文中,我将讨论 API 性能测试的重要性和不同方面。
我们将使用以下工具:
Apache JMeter 用于 API 性能测试
AWS EC2 用于托管我们的应用程序
数据库- MongoDB Atlas
API 性能测试的重要性
维护一致的应用程序性能和应用程序的可扩展性
帮助开发团队解决性能问题,并在用户基数增加时按需提供正确的资源
识别热点(慢速 API、内存泄漏)
帮助财务团队决定基础设施,注意预计的用户量
根据应用程序的类型和目标用户群,应用程序应该在不需要过多延迟的情况下提供请求,并保证绝对零停机时间。(特别是当应用程序新进入市场时,这可以在用户接受应用程序方面发挥重要作用。
在发布应用程序之前进行 PT 有助于维持用户并提供良好的用户体验。 PT 在应用程序生命周期中有助于通过确保应用程序稳定性来保留用户。
电商API接口 企业级数据
在进行API性能测试之前需要考虑以下几点:
通过模拟实时预期数据进行测试;
考虑应用程序特定功能的使用频率和预期用户数;
考虑服务器部署的地理位置以及负载测试的执行地点。
这些因素对我们的应用程序性能有重要影响。
模拟数据
使用符合实时预期数据的测试数据有助于验证API功能和性能。通过使用Postman工作流和集合运行器功能,可以模拟实际应用程序流程,并使用脚本创建要测试的功能的负载。
例如,如果一个API将所有已注册用户列出,并且页面大小限制为100,则需要创建至少100个已注册用户的负载来测试此API。 如果没有或负载较小,则PT将不会有效。 即使生成了不现实的数据集,也无法使PT有效,因为解决此类数据集的问题会导致分配额外的资源,从而增加部署成本。
注意:在整个测试过程中,应用程序服务器和数据库的配置是相同的。
注意:在整个测试过程中,应用程序服务器和数据库的配置是相同的。
1.
图1:当没有数据时的API响应。响应时间小于300毫秒。
图2:当存在预期实时数据时的API响应。响应时间高于1200毫秒。
图1和图2显示了对我们的API进行单个调用的响应时间。有数据的响应时间是没有数据的响应时间的4倍
使用JMeter进行测试
我们打算实现每秒100个请求的吞吐量,并且测试将持续10分钟。这两项测试都使用相同的服务器配置进行。
提示:使用JMeter的图形用户界面(GUI)设置测试脚本,使用CLI执行测试(由Apache JMeter推荐)。
1.
图3:没有数据的负载测试
图4:有数据的负载测试
在没有数据的测试中(图3),我们的错误率小于1%(即使这是在JMeter线程关闭时),平均响应时间为1300毫秒,我们能够达到100个RPS。
但是,在有数据的测试中(图4),我们的错误率达到了98%,响应时间超过5000毫秒,只能达到15个RPS。这主要是由于数据库连接和配置数量导致的。这里的API没有进行分页,这也导致了处理所需的额外时间。
我们可以通过减少线程数量来提高测试数据的错误率,但是RPS将小于我们预期的值(参见图5)。错误率从98%改善到6%,实现的吞吐量为3个RPS,平均响应时间为9000毫秒。
图5:减少线程(虚拟用户)以获得更低的错误率
API的选择
以列出所有已注册用户作为应用程序的主要功能/屏幕的API作为前面例子,如果这个API本身需要很长时间才能加载,则用户将很难使用这个应用程序。
选择进行测试的API是API性能测试的关键方面之一,因为每个API的调用频率和复杂性都不同。因此,识别适合测试的正确API非常重要。选择API时需考虑以下因素:
1.被调用的频率
2.执行性能密集型操作(如查找不同的集合)
3.在加载主屏幕时所调用的API
4.据应用程序的需要,还需要考虑其他许多因素。
如果应用程序处于生产状态,则可以通过收集使用统计信息来确定哪个功能/ API正在面临高流量,用户/功能的平均时间,哪个API需要很长时间才能响应以及哪个功能具有增加流量的可能。
在JMeter中,我们创建虚拟用户[VU],并在一段时间内对选定的API进行并发调用。JMeter生成的报告可帮助我们了解响应时间、错误率、实现吞吐量(以每秒请求数量为单位测量)等。
来自AWS的数据可以帮助我们了解CPU利用率、内存消耗、服务器请求处理能力和其他一些参数。
图6:对服务器的请求分布到4个API。
这4个API中,有2个API返回对象列表,另外2个API只返回一个对象。对服务器的总请求数为102989(#samples),平均分配到这4个API(即大约分配到25747个样本)。通过这样做,我们能够获得230 RPS的吞吐量和530毫秒的平均响应时间。
因此,将请求分布到不同的API上模拟实时场景非常重要。为了获得更好的结果,JMeter测试脚本应该被配置成让某些API具有更高的样本计数,而其他API则具有更少的计数。这可以通过为同一测试计划下正在测试的每个请求创建单独的线程组来完成。
地理位置考虑:
应用程序服务器和用户可以并且在大多数情况下将位于全球不同的地方。这将为系统添加网络延迟。
考虑到这一事实,需要解决性能谱系的2个极端点(具有和没有网络延迟的响应时间)。
注意:对于我们的应用程序,我们使用JMeter链接方法进行性能测试,这种方法使用主从配置创建大量并发用户。AWS EC2用于托管主机和从服务器配置的服务器。
性能测试中尽可能达到最佳性能的场景
在进行性能测试时,建议将测试工具部署在与应用程序服务器相同的地理位置,以最大程度地减少网络延迟。例如,如果应用程序服务器位于某一地区,那么执行负载测试的工具也应该部署在同一地区中的服务器上。就像我们的例子中,JMeter测试工具和应用程序服务器都部署在同一地区。这将为用户提供最佳的性能体验,因为较短的网络延迟将导致更快的响应时间和更好的性能。
示例场景:应用程序服务器部署在墨西哥地区,访问该应用程序的用户也在墨西哥。
1.
应用程序服务器相对较远的用户所在地理位置对性能的影响
这段话的意思是,在进行低端性能测试时,建议将负载测试工具部署在与应用程序服务器位于不同地理位置的服务器上,以模拟用户体验的最大网络延迟。
举个例子,假设应用程序服务器部署在美国俄勒冈州,而用户位于中亚地区。
1.
在这种情况下,将负载测试工具部署在距离应用程序服务器最远的地理位置上,以模拟用户的最大延迟。通过这种方式,我们可以更好的了解和分析用户体验,包括延迟和响应时间等,从而优化应用程序的性能,提供更好的用户体验。对各种地理位置的用户进行测试,有助于发现可能存在的性能问题,并采取相应的措施,以确保应用程序在全球范围内的稳定性和可靠性。
最后
在性能测试中我们发现了一些问题:
1.索引优化:在应用程序开始构建时,我们根据初始需求设置索引,但是随着应用程序的成长,这些索引没有得到优化,导致查询执行时间变长。
2.分页处理:当我们只查询一部分数据并对其进行处理时,使用的内存量和所需的时间比将整个数据加载到内存中并处理要少得多。
3.缓存:当我们从数据库中查询那些静态或很少更改的数据时,引入缓存可以降低数据库的负载。
4.合适的数据集:由于应用程序正在开发中且尚未发布,我们不能使用实际数据。这时我们可以使用Postman的功能模拟应用程序流程并生成数据。
5.API性能分析:利用语言提供的功能、数据结构和算法,通过API性能分析的定期练习可以使数据处理更加优化。
6.数据库连接:连接池框架有助于最大程度地利用数据库连接。
总结:
性能测试需要在应用程序的整个生命周期中进行,以解决在应用程序上线、用户基数增加或某些关键特性功能修改时可能出现的问题。 需要实施多次性能测试以获得最佳结果。这取决于应用程序的类型和特定的API集,需要投入大量时间和资金才能实现预期的吞吐量和优化资源设置。然而,投资于性能测试可以实现优化的资源设置和提高总体性能,从而提高用户体验和客户满意度。
完全消除所有问题并使资源规格完美是不可能的,但我们可以尽可能接近。 如果获取资源规格时出错,应用程序在关键时期可能会出现减速或崩溃。用户会感到烦恼,公司可能会损失金钱和声誉。 如果你过度规范,并且有过剩的容量,这将导致成本和复杂性多倍增加,但这是为了降低风险而付出的代价