gfirefly 框架分析

數據包

協議

協議以下表 | HEAD_0 | ... | HEAD_3 | protoVersion | serverVersion | length | |--------|--------|--------|--------|--------|--------| | char | ... | char | int | int | int | gfirefly框架是基於TCP協議的長鏈接,框架中沒有使用keep-alive,那麼網絡異常斷開(如網線忽然拔掉)的時候,應用層是不知道,當咱們本身使用的時候就必須加心跳包等機制來解決這個問題。另外數據加密沒有放到協議層,那麼須要加密數據只能在打包數據以前使用加密算法。python

黏包

gfirefly中對底層的數據包進行了黏包處理,如上表所示,協議頭定義了length,此時應用層就知道何時結束單個包的傳輸。見gfirefly/netconnect/protoc.py line 43:mysql

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"什麼的。c++

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.git

  1. gate節點爲中心節點。
  2. 有child節點鏈接到gate,child之間相互通信也是經過gate節點來中轉。

緩存

框架封裝了一個使用memcache的來緩存mysql數據的模塊,數據查詢僅限於有主鍵或者外鍵的表,不過也已經足夠。不足的地方在於value保存的是一個很大的字典,每次調用修改一個字段的時候,須要修改存儲的整個value,這樣效率比較低。若是用redis的hset會好不少,另外我本身對比測試redis驅動和memcache驅動。結果以下github

| redis-py | credis | memcache | pylibmc | |--------|--------|--------| | 2W+ | 4W+ | 2W+ | 5W+ | 補充:credis沒有封裝對命令的函數。redis

gevent中的坑

模擬大量登陸時,程序變慢。官方的mysql採用的是mysql-python(底層是c/c++),在全部mysql驅動中算是很快的了,比umysql慢點,不過umysql不兼容DB-API 2.0。測試的時候gevent在調用裏面查詢的時候被阻塞住。以後用豆瓣的greenify並無成功,最終換成了pymysql。memcache驅動換成了pylibmc,memcache足夠快了,若是再用gevent只會拖慢速度,搜索得出的結果是gevent中會有大量的系統調用,==亞毫秒級不推薦用greenlet==。算法

萬物歸一

使用場景分析:這個框架只適用於一些簡單的(遊戲)服務器應用。python用起來很爽,不過速度是一個很大的問題,即便使用各類黑科技,可能也不盡人意啊,畢竟不少遊戲服務器是 同時I/O和CPU密集的。sql

相關文章
相關標籤/搜索