游戏服务端压测实践

最近这两周在做服务端的压力测试,之前也写了一系列的机器人入门教程,我用着这套框架进行压测,这次分享压测的一些使用方法和打包到服务器上进行压测,主要使用docker把运行环境和设置好挂载路径。

游戏服务端压测实践

使用multiProcess并发

我这里用的多进程的方式进行,每个进程上大约100个玩家,每个玩家3个线程,每个进程由一个心跳线程对所有的线程进行广播,原本的框架里是每个玩家自带一个心跳,放在sendActor里执行,为了sendActor的性能我把它迁出来。

导入进程池模块

from multiprocessing import Pool

机器人登录

这里有个随机角色名字,可自由定义

def players(min=1,max=2):
    name = 'test'
    for i in range(min,max):
        send = Main(account=f'{name}{i}',actor_name=random_actor_name(),server_id=server_id)
        yield send

定义运行方法

test_data: 账号起止数据和remote里要调用的方法 heart_timer: 我自定义的心跳广播方法,等会说到 player_list: 根据登录账号段自动登录,执行测试在for循环的call里面,具体的方法在机器人第4篇有写到

def one_process(test_data,player_stop=False):
    start_num,end_num, remote_method = test_data
    player_list = list(players(start_num,end_num))
    heart_timer()
    for _ in range(100):
        for call in player_list:
            if remote_method:
                call(remote_method)
        time.sleep(6)
    if player_stop:
        for st in player_list:
            st.stop()
        pykka.ActorRegistry.stop_all()

广播心跳

第一次这样尝试保持心跳,如果后续有问题,再优化上来;它这里的实现方式是通过ActorRegistry 来广播给指定的Actor,我在playerActor增多一个消息类型MSG_HEART ,广播消息后,playerActor 的on_receive 会收到这条信息,然后通过SendActor发送给服务端保持心跳。

def heart_timer():
    if pykka.ActorRegistry.get_by_class_name('Player'):
        pykka.ActorRegistry.broadcast('MSG_HEART', 'Player')
        timer = threading.Timer(20, heart_timer)
        timer.start()

心跳处理方法 发送自己项目的心跳协议,要参数的带上参数

            if case(MSG_HEART):
                # 判断发送线程是否活着
                if self.send_actor.is_alive():
                    self.send_actor.tell({MSG_PROTO: ['send_heart_XXX']})

并发

维持执行的进程总数为4,当一个进程执行完毕后会添加新的进程进去 调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束

def main():
    player_pool = Pool(4)
    for case in test_case:
        player_pool.apply_async(one_process,(case,))
    player_pool.close()
    player_pool.join()
    
if __name__ == '__main__':
    main()

docker打包部署

前面我有提到我这里用的协议类型是sproto,协议解析打包用的是GitHub的开源框架,当我想在Windows上运行的时候发现一个问题,无法生成动态链接库,尝试几遍失败后就想着转到虚拟机运行吧,后面也要部署到Linux上运行,不浪费功夫研究,为了方便部署就打起了docker的心思,之前也用docker+Jenkins部署自动化。关于docker的使用,这里跳转到菜鸟教程

创建镜像dockerFile

可以直接用docker命令来执行也可以用dockerFile执行,可以参考我的dockerFile看看。

# 机器人压测 Dockerfile
# Version 1.0
# Base images 基础镜像
FROM python:3.6.9
#MAINTAINER 维护者信息
MAINTAINER AJian
# 开启权限
USER root
#ENV 设置环境变量
ENV PATH /usr/local/python3/bin:$PATH
#ADD  文件放在当前目录下,拷过去会自动解压
ADD '要运行的代码' /usr/local/robotTest/
ADD '第三方库的路径' /usr/local/lib/python3.6/site-packages
# 可以挂载文件路径
VOLUME /usr/local/robotTest

CD到dockerFile的目录下,执行build命令

docker build -t xxx_test:1.0 .

启动容器

这里设置了挂载目录

docker run -it --name XXXTest -v '你的本地目录':/usr/local/robotTest AJian/xxx_test:1.1

进入容器运行看看,查验下有没有问题

docker exec -it XXXTest /bin/bash

进入容器,找到自己的代码运行看看,没问题就可以推送镜像,当然也可以完善你的容器再打包成镜像

推送镜像

这里要说一下镜像命名,如果要推送上去的镜像要加上自己的账号名,也可以用tag命令重命名

docker push AJian/xxx_test:1.1

到这里,在本机的操作已经完成,接下来可以进入自己的服务器拉取镜像

拉取镜像

拉取完镜像后执行:docker images 看看是否出现了刚推送的镜像 接下来再启动容器即可

docker pull AJian/xxx_test:1.1

源自公众号  游戏测试技术分享



留言