最后更新于 .

最近在调整游戏的后台架构,之前因为需要快速出产品,所以整个代码都揉成一团,也基本没有做任何分层处理。现在服务器端的开发也开始逐渐招进来,所以打算打算换一套统一的架构,以后做新游戏只要做其中的业务逻辑即可。

其实之前在腾讯的时候,基本不会用到message queue这种,所有的分布式处理都是由自己写c++ server来互相通信的。这样的处理虽然开发量稍微大一点,但是性能和灵活性确实很高。

现在自己在外面做,虽然自己已经封装了一套server的框架出来,但是毕竟还有太多的轮子需要自己制造,所以就想到了之前一直有了解过celery,来看一下这种基于message queue的任务系统能达到什么性能。

RabbitMQ

celery首推的mq是rabbitmq,所以需要先安装一下:

在mac下用brew 安装:

brew install rabbitmq

安装成功之后,即可启动server了。

不过在这之前,我们先把后台管理的插件打开:

rabbitmq-plugins enable rabbitmq_management

之后执行如下命令,启动server:

rabbitmq-server

这个时候就可以通过 http://127.0.0.1:15672/ 来访问后台管理端了,默认的用户名和密码是guest guest,可以自己在页面上修改。截图如下:

NewImage

 

Redis

celery也支持redis作为broker和backend,所以redis也需要安装一下,这里就不赘述了 

Celery

安装命令为:

pip install celery

 

性能测试

新建 t.py:

from celery import Celery

app = Celery(backend='amqp', broker='amqp://')


@app.task
def add(x, y):
    return x + y

以及测试文件 test.py:

import time
from t import add


t1 = time.time()
result = add.delay(1, 2)
print result.get()

print time.time() - t1

 

启动celery worker:

celery -A t worker --loglevel=info -c 2

执行 python test.py 输出结果为:

0.545017004013

修改 t.py 为:

from celery import Celery

app = Celery(backend='redis', broker='redis://')

@app.task
def add(x, y):
    return x + y

 

测试结果为:

0.603708028793

 

无论是rabbitmq还是redis,性能都慢的让人无法接受,最终还是放弃了用celery做任务分布的想法,还是老老实实的用server通信吧。

Pingbacks

Pingbacks已关闭。

评论

  1. Jeffrey4l

    Jeffrey4l on #

    可能是和CPU有关?我在服务器上和自己笔记本上做相同的测试结果是服务器: 0.08笔记本: 0.3-0.5

    Reply

    1. 朱念洋

      朱念洋 on #

      嗯,有可能,我之前也是在centos上跑出来的性能比笔记本上高几倍。不过即使在mac上,试了一下自己写的纯python server,也就1ms的事。

      Reply

  2. Poser

    Poser on #

    用单台笔记本来做这个本来应该用于服务器集群的mq,是否欠妥当?就像你单机上跑hadoop,确实不如直接操刀上手的。性能扩展不用这么搞吧,将程序模块化,将来将“server通信”直接替换成 mq 就行,不用改多少结构和代码的

    Reply

    1. 朱念洋

      朱念洋 on #

      嗯,确实很多东西没有考虑,不过mq的性能量级还是有体现的,在笔记本上跑的纯python server,差不多是1ms返回

      Reply

  3. bensonjia

    bensonjia on #

    推荐使用zeromq。

    Reply

    1. 朱念洋

      朱念洋 on #

      zeromq确实极快无比,不过其实他已经不能算是mq了。。如果只是简单的client-server模式的话,和自己封装一层socket recv的方式是一样的。不过话说回来,用zmq直接替换socket看起来也是不错的选择。

      Reply

  4. muxueqz

    muxueqz on #

    其实我觉得Celery的意义不在于响应快,而是异步+横向扩展能力

    Reply

    1. 朱念洋

      朱念洋 on #

      嗯是的,只是顺便测试了下

      Reply

  5. genius-he

    genius-he on #

    请教楼主一个问题,就是说 socket的链接,本质上是在TCP/IP一层,或者类似企鹅利用UDP封装了一层,然后在上层进行可靠性校验。那么我的问题时,redis本质上底层也是socket的链接,那么对于单机的redis和在文章结尾中你提到的server通信的区别是什么呢?如果是基础的server通信,跑上面的一个testcase耗时是怎样的呢?

    Reply

    1. 朱念洋

      朱念洋 on #

      本质都是socket,我的意思是说用上面的这套框架,其内部帮你做了很多不需要做的事情,比如存储,路由 等等,相应的也会降低性能。所以如果明确自己的需求,那么就可以用完全自己定制的方案,不浪费多余的性能。

      Reply

      1. genius-he

        genius-he on #

        bingo,感谢up主的解惑 thx:)

        Reply

  6. 何世友Ernest

    何世友Ernest on #

    看celery源码:https://github.com/celery/celery/blob/master/celery/result.py#L125def get(self, timeout=None, propagate=True, interval=0.5,你这属于调用不当。

    Reply

    1. 朱念洋

      朱念洋 on #

      赞,感谢指正。也就是结果获取是轮询的,而不是事件通知? 这样的实现似乎满足不了远程返回结果的需求。。

      Reply

      1. 何世友Ernest

        何世友Ernest on #

        这是celery实现的比较挫的地方,也是因为官方根本不情愿给这个方法,因为会变成sync。如果要返回结果可以考虑callback。不过用celery的话真的是不大考虑实时获取结果,事务性较强的还是同步好了,直接rpc。

        Reply

  7. Ping

    Ping on #

    这种异步任务调度,就是用来拿性能换负载的东西。跟你应用场景不搭。

    Reply

  8. 最励志官网

    最励志官网 on #

    网站真不错 最励志网http://www.zuilizhi.net/?

    Reply

  9. 歪妖内涵网

    歪妖内涵网 on #

    过来支持一下 值得收藏分享

    Reply

  10. justin

    justin on #

    你好,我觉得调用get,然后来计算响应时间是不对的,这就等于让CPU一直等待结果完成,其实可以通过周期性ready()调用来检验过程是否处理完毕。

    Reply

    1. 朱念洋

      朱念洋 on #

      嗯,只是有时候请求只能顺序执行,所以我想得到的其实是调用方总共要等待的时间,而无论内部的实现。

      Reply

      1. justin

        justin on #

        那我理解你的用意, 抱歉我理解错了。

        Reply

        1. 朱念洋

          朱念洋 on #

          没关系,不同的角度而已

          Reply

  11. 小苍MM

    小苍MM on #

    我也想了解了解!!!先顶一个

    Reply

  12. ashui

    ashui on #

    这样测试明显有问题啊。。python冷启动是要时间的,正常的服务器端程序肯定不会每次都冷启动。

    Reply

发表评论