今天遇到一个性能压测的问题,也是很多同学做游戏服务器开发经常会遇到的,今天记录一下分享给大家。
性能压测遇到的问题
对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。
服务器硬件情况:
8核16G服务器, 带宽1000M, redis假设在独立的内网云服务上,通过内网连接;
性能压测:
压测功能接口1: 查询当前服务器的时间戳,并返回给客户端;
压测功能接口2: 给定key, 查询redis服务器hash表中的一个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: 做并发测试时,服务器的架构是如何的?如何部署的?
首先就要搞清楚,当前服务器架构是多少个线程or进程, 如何并发的?能否发挥多核的优势。
目前服务端架构是基于Java技术,网络请求基于Java的Netty, 逻辑处理接口采用多线程来进行处理。处理线程与Netty IO线程是分开的。目前IO线程为4个,处理线程为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线程数目是没有问题的。
大概估摸计算以后,我就让小伙伴加大逻辑处理线程与IO线程,然后对比,如图:
今天的分享就到这里了,问题比较简单,但是分析的思路值得推荐给大家,所以我就写了这个文章,关注我,可以获得更多游戏开发的文章与教程。