今天遇到一个性能压测问题,这是很多同学在开发游戏服务器时经常遇到的问题。 今天我就记录下来分享给大家。
是的,这里有一个游戏开发交流群。 希望大家可以点进去一起交流开发经验!
性能压力测试遇到的问题
服务器硬件状态:
8核16G服务器,带宽1000M,假设redis在独立的内网云服务上,通过内网连接;
性能压力测试:
压测功能接口1:查询当前服务器的时间戳并返回给客户端;
压测功能接口2:给定一个key,在redis服务器哈希表中查询一个value并返回给客户端;
压测方式,2000个并发请求;
测试功能接口1结果:(并发2000,TPS 16000,RT 20ms)
测试函数接口2结果:(并发2000,TPS 6000,RT 3000ms)
压力测试问题:
为什么2000并发时查询一个redis结果需要3秒,TPS却下降到6000? 问题是什么? 如何优化?
随附的:
RT:Response Time,从发送请求到得到结果的响应时间,包括Request Time和Response Time。
TPS:Transactions Per Second,每秒处理的交易数量。
绩效分析基本情况调查
遇到此类问题,首先要分析问题。 在解决问题之前,我们必须了解服务器在并发时的技术架构以及相关信息,然后对问题做出相应的判断和调试。 我想了想,问了一些相关问题,如下:
问题1:做并发测试时,服务器的架构是怎样的? 它是如何部署的?
首先,我们需要弄清楚当前服务器架构中有多少个线程或进程,它们的并发情况如何? 是否可以利用多核的优势。
目前的服务器架构都是基于Java技术,网络请求基于Java的Netty,逻辑处理接口采用多线程进行处理。 处理线程与 Netty IO 线程是分开的。 目前有4个IO线程和8个处理线程。
问题2:当前极限测试中各个CPU和硬件设备的比例是多少? (CPU、内存、IO、网络带宽)
CPU:当前CPU使用率在20%左右;
内存:当前内存使用量1G左右,内存稳定;
磁盘文件IO:测试时无文件读写等IO操作;
网卡使用情况:目前回复的数据量不是很大,网络带宽占用很低;
问题3:Redis服务器的情况如何?
目前Redis服务器是独立的,Redis服务器的资源还是充足的。 到目前为止尚未发现严重的性能问题。
问题4:停止并发后,单独响应redis需要多长时间? 正常吗?
停止并发后,客户端向服务器发送redis查询请求,大概响应时间在40ms左右。 包括往返网络时间,都是正常的。
问题5:服务器向Redis服务器进行redis查询需要多长时间?
这里打印的服务器代码中,查询Redis服务器hget大约需要1ms。
为什么要问这些问题? 这是解决性能问题的一些关键依据。 基于这些基础游戏开发实战,我们会针对问题制定一些可能的方向。 问题1 了解服务器的基本架构和部署,了解这个架构是否能够充分利用当前硬件的性能。 问题2主要是了解服务器是否遇到了运行时瓶颈,导致无法提升并发性能。 问题3:当前性能测试与Redis相关,排除Redis服务器的干扰。 问题4:阻塞并发后,检查整个查询链路逻辑是否有异常。 排查请求中的代码逻辑问题。 问题5:测试服务器对Redis的请求,彻底消除Redis的影响游戏开发实战,因为这个性能测试请求与Redis有关。
问题分析及解决方案
经过上述调查,我们总结了相关情况。 单次访问Redis正常,从请求到返回的时间在40ms左右,说明整个链路没有大问题。
Redis查询业务时间=客户端向服务器发送请求的时间+服务器查询Redis结果的时间+服务器向客户端发送响应的时间。
过程中没有大规模的内存创建和释放游戏评测,也没有IO操作。 内存和IO不会成为性能的瓶颈。 Redis服务器上一切正常,Redis支持的高并发一般不会造成大问题。 硬件的CPU使用率很低,硬件没有得到充分利用,说明应该还有改进的空间。
假设服务器在单核情况下处理业务,服务器请求Redis服务器需要等待1ms,那么2000个并发次数需要2秒。 同时还需要接受客户端的请求+发送数据给客户端进行网络IO。 题目中总共有8个CPU核心,CPU占用率在20%左右,这和我们从数据上分析的基本一致。 从上面的分析来看,我们可能没有足够的线程,导致处理redis时并发率无法提升。 是IO线程不够还是Task逻辑处理线程不够? 从简单查询来看,应该是逻辑处理线程不够。 当IO线程处理第一个网络请求时没有问题,说明IO线程数量没有问题。
经过粗略的估计和计算3D场景,我让朋友增加了逻辑处理线程和IO线程,然后进行了比较,如图:
今天的分享就到此为止。 问题比较简单,但是分析思路值得推荐给大家,所以写了这篇文章。 关注我,获取更多有关游戏开发的文章和教程。