原文:http://blog.rushcj.com/2010/08/21/try-thrift/

Thrift是一個非常棒的工具,是Facebook的開源項目,目前的開發非常的活躍,由Apache管理,所以用的是Apache Software License,這非常重要,因為可以放心的對其修改并用到自己的項目中。

談到修改Thrift,這非常重要。因為我覺得如果要嚴肅的使用Thrift,不可避免的要深入了解它,并幾乎都要修改Thrift的代碼。一個通信框架,它不可能幫你做到所有的事情,也不可能在不了解的情況下就貿然的使用。

1.Thrift 的Java Server/Client有個較為嚴重的bug(https://issues.apache.org/jira/browse/THRIFT-601 ),隨機向thrift  sever的監聽端口發些數據,可能會導致Server OutOfMemory,細細看看代碼,這個bug有點土。

2.Thrift Client線程不安全,多線程下使用可能導致Server和客戶端程序崩潰。Client的每次調用遠程方法其實是有多次Socket寫操作,因此每個線程中使用的Client要保證獨立,如果多個線程混用同一個Client(其實是用同一個Socket),可能會導致傳輸的字節順序混亂,使得Server OutOfMemory(參考1)

3.Thrift定義數據結構時,盡量避免用map, 或者set。在cpp下, map被對應為std::map(rb tree)和std::set,thrift生成的類不會重載”<”,因此需要手動修改生成類,否則link沒法通過。較為麻煩。

4.如果Client端基于效率考慮,要緩存Socket,需要重新實現其TTransport類,以支持 Socket緩存池。當然,這個實現其實跟thrift沒多大關系,算是2次開發。但一般都要這么做的吧?

5.如果Client基于效率考慮,緩存了Socket,那么thrift Server端的模式選擇就較為重要了。如果使用同步的TThreadPoolServer,那么無可避免的,客戶端緩存1個Socket,Server端就會有一個線程一直處于Server狀態,等待peek這個Socket上的數據。這個線程就不能用于其它請求了。所以,及時清理Client端的Socket及控制Socket池的大小是非常必要的。

6.聽同事說CPP Thrift Server的Epoll NonBlocking模式有效率問題。其實,并發要求不高的Server用LT模式的EPoll其實很方便的,當然,這個要自己給Thrfit Server做patch了,不過也不麻煩。開發起來也是很方便的。我想給我們的Server加個EPOLLONESHOT的同步EPoll實現。

7.CPP下的 TThreadPoolServer和TThreadServer由一個有趣的問題,如果有客戶端維護長連接,那么對這個Server實例做析構的時候會堵塞(前面說過了,在peek中…)。

8.用valgrind看,thrift cpp似乎有一些內存問題。沒細看。

9.無論是Java,還是CPP,Server端都無法通過合法的方式獲取Client的ip, port。可以通過編寫ThriftServerEventHandler可以處理這件事情。如果想要獲取Client ip, port的話,可以看看這個東西。