如何给客户端服务器应用进行压力测试/负载测试?

13 投票
5 回答
11136 浏览
提问于 2025-04-11 18:35

我正在开发一个基于客户端-服务器和数据库的系统,现在需要想办法对这个系统进行压力测试或负载测试。客户总是想知道一些事情,比如:

• 一个服务器能支持多少个客户端?
• 一个服务器能同时处理多少个搜索请求?
• 我们的数据库能存储多少数据?
• 其他类似的问题。

这些问题的关键在于响应时间。我们需要能够测量在增加负载时,响应时间和性能是如何下降的,这样我们就可以制作一些漂亮的图表,给客户展示在特定硬件配置下的性能预期。

目前,我们只是凭经验猜测,估计系统的表现。随着产品在更高要求的条件下运行,这种方法已经不能满足我们的需求了。

我被指派去想出一种有效的方法来获取这些答案。我知道这个问题没有人能给出明确的答案,但我希望能听到大家在自己系统上是如何进行这项工作的建议。

值得一提的是,我们可以通过Python语言完全访问我们的客户端API(得益于SWIG),这比用C++进行这类工作要简单得多。

所以,我把这个问题抛出来:非常期待大家能提出什么好主意!

5 个回答

5

在性能方面,你需要关注两个方面:延迟(应用程序的响应速度)和吞吐量(每个时间段能处理多少操作)。对于延迟,你需要有一个可接受的基准;对于吞吐量,你需要有一个最低的可接受值。

这些是你的起点。如果你想告诉客户每个时间段能处理多少个xyz操作,你需要了解硬件和软件的配置。知道生产环境的硬件配置对获取准确的数据非常重要。如果你不知道硬件配置,那么你需要想办法将测试硬件的数据映射到最终的生产硬件上。

如果不了解硬件,你只能观察性能随时间变化的趋势,而不能得到具体的数值。

了解软件配置同样重要。你的服务器是集群配置吗?是否进行了负载均衡?服务器上还有其他程序在运行吗?你的软件能否扩展,还是必须扩展硬件来满足需求?

要知道你能支持多少个客户端,你需要理解什么是标准操作集。一个简单的测试方法是去掉客户端,写一个简单的客户端,然后尽可能多地启动这些客户端,让每个客户端连接到服务器。最终你会达到服务器连接资源的限制。如果没有连接池或更好的硬件,你无法超过这个限制。通常在这之前你会遇到架构问题,但无论如何,你都有一个上限。

把这些信息整理成一个脚本,让你的客户端可以执行。你需要记录你的脚本执行某个操作所需的时间,并与预期用户执行该操作所需的时间进行比较。按照上面提到的方法逐步增加客户端数量,直到你发现增加客户端导致性能显著下降。

有很多方法可以进行压力测试,但关键是理解预期负载。向你的客户询问他们的期望。每个时间段的预期需求是多少?从这里你可以计算出上限。

你可以进行一个浸泡测试,让多个客户端连续运行几个小时或几天。你也可以尽可能快地连接尽可能多的客户端,看看你的服务器在高需求下的表现(这也类似于拒绝服务攻击)。

并发搜索应该通过你标准的行为搜索来进行,代表客户端进行操作,或者写一个脚本来建立一个信号量,等待多个线程,然后一次性释放它们。这很有趣,也会对你的数据库造成压力。在进行搜索时,你需要考虑可能存在的缓存层。你需要测试有缓存和没有缓存的情况(在每个人都进行独特搜索请求的场景下)。

数据库存储是基于物理空间的;你可以根据字段长度和预期数据量来确定行大小。可以通过统计方法推算出这一点,或者创建一个数据生成脚本(这对你的负载测试场景很有用,也应该是你组织的资产),然后将生成的数据映射到业务对象。你的客户会关心他们能存储多少个“业务对象”,而你则关心能存储多少原始数据。

还有其他需要考虑的事项:预期的可用性是多少?服务器上线需要多长时间?如果服务器宕机一次需要两天才能恢复,99.9%的可用性就不算好。相反,如果可用性较低,但重启只需5秒钟,并且有备用方案,那就更能接受。

6

如果你对用Python写测试代码比较熟悉,我发现funkload这个工具非常强大。你没有说明你的服务器是否是基于HTTP的,所以你可能需要根据自己的客户端/服务器风格来调整它的测试功能。

一旦你在Python中写好了测试,funkload可以在多个线程上运行这个测试,监控响应时间,并在测试结束时给你一个总结。

8

测试 1: 疯狂地连接和断开客户端,看看你是如何处理会话的开始和结束的,以及你的服务器在高峰期能承受多少压力。同时,记录下有多少客户端连接失败。这一点非常重要。

测试 2: 让客户端连接并保持登录状态,比如一周,进行一些随机操作 (模糊测试)。记录每个操作的往返时间。同时,记录操作的顺序,这样你的“客户端”就能找到你使用案例中的漏洞(这非常重要,而且测试起来非常困难)。

测试 3 和 4: 确定你系统的主要使用场景,并编写脚本来执行这些任务。然后让多个客户端同时执行相同的任务(测试 3),再让多个客户端执行不同的任务(测试 4)。

系列: 这里你需要考虑的另一个维度是客户端的数量。 一个不错的系列可以是: 5, 10, 50, 100, 500, 1000, 5000, 10000,...

这样你就可以为每一系列测试收集不同负载的数据。

另外,恭喜你把客户端的 API 接入到 Python!这是一种很好的准备方式。

注意: IBM 有一个关于 Java 的模糊测试示例,虽然和你的情况无关,但会帮助你为系统设计一个好的模糊测试。

撰写回答