博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gfirefly 框架分析
阅读量:5888 次
发布时间:2019-06-19

本文共 2280 字,大约阅读时间需要 7 分钟。

  hot3.png

数据包

协议

协议如下表 | HEAD_0 | ... | HEAD_3 | protoVersion | serverVersion | length | |--------|--------|--------|--------|--------|--------| | char | ... | char | int | int | int | 框架是基于TCP协议的长连接,框架中没有使用keep-alive,那么网络异常断开(如网线突然拔掉)的时候,应用层是不知道,当我们自己使用的时候就必须加心跳包等机制来解决这个问题。另外数据加密没有放到协议层,那么需要加密数据只能在打包数据之前使用加密算法。

黏包

gfirefly中对底层的数据包进行了黏包处理,如上表所示,协议头定义了length,此时应用层就知道什么时候结束单个包的传输。见gfirefly/netconnect/protoc.py line 43:

def dataReceived(self, data):    length = self.factory.dataprotocl.getHeadlength()#获取协议头的长度    self.buff += data    while self.buff.__len__() >= length:        unpackdata = self.factory.dataprotocl.unpack(self.buff[:length])        if not unpackdata.get('result'):            log.msg('illegal data package --')            self.factory.connmanager.loseConnection(self.transport.sessionno)            break        command = unpackdata.get('command')        rlength = unpackdata.get('length')        request = self.buff[length:length+rlength]        if request.__len__()< rlength:            log.msg('some data lose')            break

网络

gfirefly 是由firefly修改而来,那么当底层网络模块由twisted 更换为 gevent的时候,加入了一个叫gtwisted的wrapper。实际上还是使用的gevent.StreamServer。还有一些用不爽的地方,而且一直没有修改,比如gtwisted/core/base.py line 122左右, getHost函数 手动返回"0.0.0.0"什么的。

rpc

length data
int string

rpc的协议头如上表,其中data为dict经marshal的结果,marshal速度还算可以,我测试中marshal和msgpack速度不相上下,但是msgpack可以跨平台,呵呵。data的内部是这样的:{'_msgtype': _msgtype, '_key': _key, '_name': _name, '_args': args, '_kw': kw},看样子没什么特别之处。

分布式

gfirefly中实现了rpc的双向调用,使之实现分布式更容易一下。不过我测试双向RPC的效率却很低,qps大概在4000左右,而测试单向的mprpc qps达到1W8.

  1. gate节点为中心节点。
  2. 有child节点连接到gate,child之间相互通讯也是通过gate节点来中转。

缓存

框架封装了一个使用memcache的来缓存mysql数据的模块,数据查询仅限于有主键或者外键的表,不过也已经足够。不足的地方在于value保存的是一个很大的字典,每次调用修改一个字段的时候,需要修改存储的整个value,这样效率比较低。如果用redis的hset会好很多,另外我自己对比测试redis驱动和memcache驱动。结果如下

| redis-py | | memcache | pylibmc | |--------|--------|--------| | 2W+ | 4W+ | 2W+ | 5W+ | 补充:credis没有封装对命令的函数。

gevent中的坑

模拟大量登录时,程序变慢。官方的mysql采用的是(底层是c/c++),在所有mysql驱动中算是很快的了,比umysql慢点,不过umysql不兼容DB-API 2.0。测试的时候gevent在调用里面查询的时候被阻塞住。之后用豆瓣的greenify并没有成功,最终换成了pymysql。memcache驱动换成了,memcache足够快了,如果再用gevent只会拖慢速度,搜索得出的结果是gevent中会有大量的系统调用,==亚毫秒级不推荐用greenlet==。

万物归一

使用场景分析:这个框架只适用于一些简单的(游戏)服务器应用。python用起来很爽,不过速度是一个很大的问题,即使使用各种黑科技,可能也不尽人意啊,毕竟很多游戏服务器是 同时I/O和CPU密集的。

转载于:https://my.oschina.net/toil/blog/384461

你可能感兴趣的文章
C#实体对象序列化成Json,并让字段的首字母小写
查看>>
遍历PHP数组的6种方式
查看>>
重构-改善既有代码的设计(一)--重构,第一个案例
查看>>
MVPArms官方首发一键生成组件化,体验纯傻瓜式组件化开发
查看>>
块级格式化上下文(BFC)
查看>>
[LintCode] Buy Fruits
查看>>
ZStack源码剖析之二次开发——可扩展框架
查看>>
Elasticsearch分布式一致性原理剖析(一)-节点篇
查看>>
一个基于vue的图片轮播组件的实现
查看>>
Scrapy 之 settings
查看>>
动态规划入门H - 合唱队形 (最优子序列的另一个应用,这里是最优递增和最优递减子序列的结合)...
查看>>
游戏服务器JVM优化
查看>>
【359天】每日项目总结系列096(2018.01.30)
查看>>
HDU 1039 Easier Done Than Said?
查看>>
vue+微信支付目录+JSSDK签名解决方案
查看>>
搭建自己的博客 —— 关于域名设置
查看>>
mybatis sqlSession的运行过程
查看>>
你可能需要的优秀英文网站
查看>>
翻译 | 一行 JavaScript 代码的逆向工程
查看>>
ES6系列---对象功能扩展
查看>>