thrift服務(wù)(for Python/Java)的簡(jiǎn)易搭建步驟(不求甚解版)

關(guān)于這個(gè)話題芍瑞,網(wǎng)上有大量的文章;但是配置部分都講得比較混亂皮胡,直接拷來并不能跑通痴颊。
本文以python和java分別作為服務(wù)端/客戶端及其逆形式進(jìn)行了演示,不求甚解屡贺,只求能用蠢棱。

定義好thrift文件,作為C/S的契約[1]

xxx.thrift
注意:以下代碼都是手動(dòng)混淆過的甩栈,僅大致示意寫法泻仙,不保證內(nèi)容正確

namespace java com.x1.x2.x3.x4.x5.gen_java # 注意,如果是為java版本準(zhǔn)備的量没,一定要寫好package

struct MyStruct1{
    1:string field1,
    2:list<string> field2,
    3:optional list<MyStruct1> field3, # 注意java不支持optinal玉转,生成的代碼中只有必選項(xiàng)
}

struct MyStruct2{
    1:list<i16> data
}

service MyService{
    void f1(1:MyStruct1 s1)
    list<MyStruct2> f2(1:string field1, 2:MyStruct1 data)
}

將thrift文件分別編譯成服務(wù)器端語言和客戶端語言
注意:自動(dòng)生成的python代碼中,可能有class A依賴class B殴蹄,而A的代碼卻寫到了同一個(gè)文件中B的下方的情況究抓;這可能是thrift的一個(gè)BUG,手動(dòng)調(diào)整代碼順序即可

mkdir gen_py gen_java # 默認(rèn)名字是用短橫線分隔(gen-py)袭灯,不符合python的包命名要求漩蟆;手動(dòng)改成下劃線
thrift -r --gen py -out gen_py xxx.thrift
thrift -r --gen java -out ../../../../../../ xxx.thrift # 路徑中有x1-x5,就要上6層

實(shí)現(xiàn)服務(wù)端邏輯

注意:

  • gen_py和gen_java文件夾的內(nèi)容最好別改動(dòng)妓蛮;它們都只是作為輔助類庫(kù)使用的
  • 服務(wù)器端要自己寫一個(gè)Handler類去override指定的方法
  • 客戶端只要綁定到指定的端口上調(diào)用即可

python版服務(wù)器端

先用自己的類來繼承IFace怠李,實(shí)現(xiàn)各個(gè)接口

# thrift 相關(guān)的引用
from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from thrift.transport import TSocket, TTransport
# import ... # 邏輯相關(guān)的引用

class MyHandler(MyService.Iface):
    def __init__(self):
        transport = TSocket.TSocket('hostname', 8095) # 最好用IP,穩(wěn)一點(diǎn)
        transport = TTransport.TBufferedTransport(transport)
        transport.open()  # 注意這一行不能少
        protocol = TBinaryProtocol.TBinaryProtocol(transport)
        # self.xxx = yyy 之類的初始化,省略 ...

    def f1(self, arg1):
        pass # ...

然后寫一個(gè)server.py來包裹handler并控制服務(wù)的起停

from thrift.protocol import TBinaryProtocol
from thrift.server import TServer
from thrift.transport import TSocket, TTransport

# sys.path.append('thrift/gen_py') # 可能需要把gen_py加到PYTHONPATH
# import ... # 邏輯相關(guān)的引用

def main():
    handler = MyHandler()
    processor = MyService.Processor(handler)
    transport = TSocket.TServerSocket('10.1.x.x', 8081)
    tfactory = TTransport.TBufferedTransportFactory()
    pfactory = TBinaryProtocol.TBinaryProtocolFactory()
    server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)

    logger.info('---------- starting xxx server over thrift...')
    server.serve()
    logger.info('---------- shutting down xxx server over thrift...')

if __name__ == '__main__':
    main()

java版的服務(wù)器端

同理捺癞,先寫個(gè)Handler類來覆蓋相應(yīng)的method

package com.xxx.xxx.xxx
// import ...

public class MyHandler implements MyService.Iface {
    @Override
    public synchronized void f1(MyStruct1 arg1) throws TException {
        // ...
    }
    // ... 
}

然后寫個(gè)Server類來包裹Handler并控制服務(wù)的起停

package com.x.x.x.xxx

import ... // 邏輯相關(guān)的引用
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;

import java.io.IOException;
import java.net.InetSocketAddress;

public class MyServer {
    public static void main(String[] args) throws IOException, TTransportException {
        MyService.Processor processor = new MyService.Processor(new MyHandler());

        TServerSocket serverTransport = new TServerSocket(new InetSocketAddress("1.2.3.4", 1234));
        TServer server = new TSimpleServer(new TThreadPoolServer.Args(serverTransport).processor(processor));
        System.out.println("Starting server...");
        server.serve();
    }
}

實(shí)現(xiàn)客戶端邏輯

java版客戶端

先把之前運(yùn)行thrift -r --gen java ...命令生成的gen_java文件夾拷進(jìn)來夷蚊,作為一個(gè)package;
然后把Guava等其它各種類庫(kù)寫進(jìn)maven/Gradle髓介。
插一句:如果用到讀寫wav文件的功能惕鼓,可以把wavFile相關(guān)的類庫(kù)[2]下載了拷進(jìn)來。

package com.xxx.yyy;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
// import ...

public class App {
    public void work(List<String> arg) {
        try {
            TTransport transport = new TSocket("1.2.3.4", 1234); // 注意兩邊都盡量用IP唐础,比較穩(wěn)一點(diǎn)
            transport.open();
            TProtocol protocol = new TBinaryProtocol(transport);
            
            MyService.Client client = new MyService.Client(protocol);
            // arg1 = ...
            client.f1(arg);
            // 多次調(diào)用 client.f2(...)

            transport.close();
            System.out.println("----- client done");
        } catch (TException ex) {
            ex.printStackTrace();
        } // 更多catch ...
    }

    public static void main(String[] args) {
        App app = new App();
        app.work(Lists.newArrayList("arm", "aunt", "autumn"));
    }
}

python版的客戶端寫法

from thrift.protocol import TBinaryProtocol
from thrift.transport import TSocket, TTransport

# 可能需要將gen_py加到PYTHONPATH
# import 邏輯相關(guān)的模塊 ...

def main():
    transport = TSocket.TSocket('1.2.3.4', 8081)
    transport = TTransport.TBufferedTransport(transport)
    transport.open()
    protocol = TBinaryProtocol.TBinaryProtocol(transport)
    client = MyService.Client(protocol)

    # arg = ...
    client.f1(arg)
    # 多次調(diào)用 client.f2(...)
    print('----- client done')

if __name__ == '__main__':
    main()

  1. thrift文件寫法參考:http://www.reibang.com/p/0f4113d6ec4b ?

  2. Java Wav File IO API:http://www.labbookpages.co.uk/audio/javaWavFiles.html ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末箱歧,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子一膨,更是在濱河造成了極大的恐慌呀邢,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豹绪,死亡現(xiàn)場(chǎng)離奇詭異价淌,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瞒津,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蝉衣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巷蚪,你說我怎么就攤上這事病毡。” “怎么了屁柏?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵剪验,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我前联,道長(zhǎng)功戚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任似嗤,我火速辦了婚禮啸臀,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘烁落。我一直安慰自己乘粒,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布伤塌。 她就那樣靜靜地躺著灯萍,像睡著了一般。 火紅的嫁衣襯著肌膚如雪每聪。 梳的紋絲不亂的頭發(fā)上旦棉,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天齿风,我揣著相機(jī)與錄音,去河邊找鬼绑洛。 笑死救斑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的真屯。 我是一名探鬼主播脸候,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绑蔫!你這毒婦竟也來了运沦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤配深,失蹤者是張志新(化名)和其女友劉穎携添,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凉馆,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年亡资,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了澜共。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锥腻,死狀恐怖嗦董,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情瘦黑,我是刑警寧澤京革,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站幸斥,受9級(jí)特大地震影響匹摇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜甲葬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一廊勃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧经窖,春花似錦坡垫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至配乱,卻和暖如春溉卓,著一層夾襖步出監(jiān)牢的瞬間皮迟,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工的诵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留万栅,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓西疤,卻偏偏與公主長(zhǎng)得像烦粒,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子代赁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容