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

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

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

RabbitMQ

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

在mac下用brew 安装:

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

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

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

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

NewImage

 

Redis

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

Celery

安装命令为:

 

性能测试

新建 t.py:

以及测试文件 test.py:

 

启动celery worker:

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

修改 t.py 为:

 

测试结果为:

 

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

暂无相关产品

23则回应给“分布式消息系统尝试(rabbitmq, celery, redis)”

  1. Jeffrey4l说道:

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

    [回复]

    朱念洋 回复:

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

    [回复]

  2. Poser说道:

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

    [回复]

    朱念洋 回复:

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

    [回复]

  3. bensonjia说道:

    推荐使用zeromq。

    [回复]

    朱念洋 回复:

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

    [回复]

  4. muxueqz说道:

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

    [回复]

    朱念洋 回复:

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

    [回复]

  5. genius-he说道:

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

    [回复]

    朱念洋 回复:

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

    [回复]

    genius-he 回复:

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

    [回复]

  6. 何世友Ernest说道:

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

    [回复]

    朱念洋 回复:

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

    [回复]

    何世友Ernest 回复:

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

    [回复]

  7. Ping说道:

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

    [回复]

  8. 最励志官网说道:

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

    [回复]

  9. 歪妖内涵网说道:

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

    [回复]

  10. justin说道:

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

    [回复]

    朱念洋 回复:

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

    [回复]

    justin 回复:

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

    [回复]

    朱念洋 回复:

    没关系,不同的角度而已

    [回复]

  11. 小苍MM说道:

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

    [回复]

  12. ashui说道:

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

    [回复]

发表评论