原文:http://blog.rushcj.com/2010/08/21/try-thrift/
Thrift是一個(gè)非常棒的工具,是Facebook的開(kāi)源項(xiàng)目笼蛛,目前的開(kāi)發(fā)非常的活躍洒放,由Apache管理,所以用的是Apache Software License滨砍,這非常重要往湿,因?yàn)榭梢苑判牡膶?duì)其修改并用到自己的項(xiàng)目中。
談到修改Thrift,這非常重要惋戏。因?yàn)槲矣X(jué)得如果要嚴(yán)肅的使用Thrift领追,不可避免的要深入了解它,并幾乎都要修改Thrift的代碼响逢。一個(gè)通信框架绒窑,它不可能幫你做到所有的事情,也不可能在不了解的情況下就貿(mào)然的使用舔亭。
1.Thrift 的Java Server/Client有個(gè)較為嚴(yán)重的bug(https://issues.apache.org/jira/browse/THRIFT-601 )些膨,隨機(jī)向thrift? sever的監(jiān)聽(tīng)端口發(fā)些數(shù)據(jù),可能會(huì)導(dǎo)致Server OutOfMemory钦铺,細(xì)細(xì)看看代碼订雾,這個(gè)bug有點(diǎn)土。
2.Thrift Client線程不安全矛洞,多線程下使用可能導(dǎo)致Server和客戶端程序崩潰洼哎。Client的每次調(diào)用遠(yuǎn)程方法其實(shí)是有多次Socket寫(xiě)操作,因此每個(gè)線程中使用的Client要保證獨(dú)立沼本,如果多個(gè)線程混用同一個(gè)Client(其實(shí)是用同一個(gè)Socket)噩峦,可能會(huì)導(dǎo)致傳輸?shù)淖止?jié)順序混亂,使得Server OutOfMemory(參考1)
3.Thrift定義數(shù)據(jù)結(jié)構(gòu)時(shí)抽兆,盡量避免用map, 或者set壕探。在cpp下, map被對(duì)應(yīng)為std::map(rb tree)和std::set,thrift生成的類(lèi)不會(huì)重載”<”郊丛,因此需要手動(dòng)修改生成類(lèi)李请,否則link沒(méi)法通過(guò)。較為麻煩厉熟。
4.如果Client端基于效率考慮导盅,要緩存Socket,需要重新實(shí)現(xiàn)其TTransport類(lèi)揍瑟,以支持 Socket緩存池白翻。當(dāng)然,這個(gè)實(shí)現(xiàn)其實(shí)跟thrift沒(méi)多大關(guān)系,算是2次開(kāi)發(fā)滤馍。但一般都要這么做的吧岛琼?
5.如果Client基于效率考慮,緩存了Socket巢株,那么thrift Server端的模式選擇就較為重要了槐瑞。如果使用同步的TThreadPoolServer,那么無(wú)可避免的阁苞,客戶端緩存1個(gè)Socket困檩,Server端就會(huì)有一個(gè)線程一直處于Server狀態(tài),等待peek這個(gè)Socket上的數(shù)據(jù)那槽。這個(gè)線程就不能用于其它請(qǐng)求了悼沿。所以,及時(shí)清理Client端的Socket及控制Socket池的大小是非常必要的骚灸。
6.聽(tīng)同事說(shuō)CPP Thrift Server的Epoll NonBlocking模式有效率問(wèn)題糟趾。其實(shí),并發(fā)要求不高的Server用LT模式的EPoll其實(shí)很方便的甚牲,當(dāng)然拉讯,這個(gè)要自己給Thrfit Server做patch了,不過(guò)也不麻煩鳖藕。開(kāi)發(fā)起來(lái)也是很方便的魔慷。我想給我們的Server加個(gè)EPOLLONESHOT的同步EPoll實(shí)現(xiàn)。
7.CPP下的 TThreadPoolServer和TThreadServer由一個(gè)有趣的問(wèn)題著恩,如果有客戶端維護(hù)長(zhǎng)連接院尔,那么對(duì)這個(gè)Server實(shí)例做析構(gòu)的時(shí)候會(huì)堵塞(前面說(shuō)過(guò)了,在peek中…)喉誊。
8.用valgrind看邀摆,thrift cpp似乎有一些內(nèi)存問(wèn)題。沒(méi)細(xì)看伍茄。
9.無(wú)論是Java栋盹,還是CPP,Server端都無(wú)法通過(guò)合法的方式獲取Client的ip, port敷矫±瘢可以通過(guò)編寫(xiě)ThriftServerEventHandler可以處理這件事情。如果想要獲取Client ip, port的話曹仗,可以看看這個(gè)東西榨汤。