微服務(wù)通訊:RPC框架和thrift

背景

要看4個thrift接口半夷。thrift是一種RPC框架,先看一下怎么一回事极颓。

與我做的這層的關(guān)系

API這層其實是兩端服務(wù)盅藻,一個是作為客戶端調(diào)用后端服務(wù)糜颠,一個是作為服務(wù)端為前端提供接口汹族。在調(diào)用后端服務(wù)這一端上面,95%以上的接口都是RPC其兴,為前端提供接口這部分顶瞒,如果是native調(diào)用,那么多為http元旬,如果是H5榴徐,RPC調(diào)用越來越多了。(關(guān)于native和H5匀归,請參考這篇這篇坑资,這里不做詳細(xì)介紹)

微服務(wù)通訊

從通訊模式角度考慮

1對1 1對多
同步 請求響應(yīng)模式,最常見
異步 通知/請求異步響應(yīng) 發(fā)布訂閱/發(fā)布異步響應(yīng)

從通訊協(xié)議角度考慮:

  • REST
  • RPC
  • MQ

RPC框架

選擇RPC框架考慮的東西:

  1. I/O(NIO/BIO)穆端,線程調(diào)度模型(多線程/調(diào)度方式)

  2. 序列化方式(很影響RPC通訊效率):

    1. 可讀的:

      1. XML: e.g. webservice, soap

      2. JSON, e.g. fastjson, json-rpc

    2. binary: e.g. thrift, JDK自帶的序列化方式

  3. 是否需要服務(wù)治理: e.g. 部署袱贮,HA,etc.

用的多的RPC框架包括Dubbo, Thrift, gRPC

Thrift原理

框架如下圖:(source: Thrift Wikipedia)

architect.png

Thrift RPC調(diào)用過程:

  1. 客戶端調(diào)用本地代理

  2. 本地代理對客戶端的請求進(jìn)行序列化并發(fā)起網(wǎng)絡(luò)請求体啰,等待返回結(jié)果

  3. 服務(wù)端也有個代理攒巍,它接受到網(wǎng)絡(luò)請求之后會對請求參數(shù)進(jìn)行反序列化,并對真實server application方法進(jìn)行調(diào)用荒勇,對返回結(jié)果進(jìn)行序列化并發(fā)出網(wǎng)絡(luò)請求返回結(jié)果

  4. 客戶端代理接受到返回結(jié)果后對返回結(jié)果進(jìn)行反序列化并將結(jié)果交給客戶端發(fā)起調(diào)用的方法

可以看出很重要的一個地方: client application和client柒莉,server application和server,都是分開的沽翔;也就是說兢孝,真正的client和server都是有代理的(兩個橙色的service client)

Protocol和Transport層

從上圖看出,除開input code這個自己寫的代碼部分仅偎,和Generated code這個thrift框架生成的代碼跨蟹,下面還有2層: TProtocol和TTransport: 實際上這就是RPC中最重要的兩層(TProtocol和TTransport中的T前綴代表Thrift)。一旦這兩層具體方式確定了橘沥,那么就可以進(jìn)行RPC通訊了窗轩。

  1. Protocol: 序列化協(xié)議:Client和Server兩端需要遵循相同的序列化協(xié)議,才能進(jìn)行RPC通訊威恼。支持的protocol有

    1. TBinaryProtocol

    2. TCompactProtocol

    3. TJSONProtocol

    4. TSimpleJSONProtocol

  2. Transport: 傳輸層:如何傳輸序列化字節(jié)流品姓。支持的傳輸方式有

    1. TSimpleFileTransport

    2. TFramedTransport

    3. TMemoryTransport

    4. TSocket

    5. TZlibTransport

  3. 補(bǔ)充一下:Server也有幾種: TNonblockingServer, TSimpleServer, TThreadedServer, TThreadPoolServer

Thrift框架使用

t.png

如果不看Thrift的原理而只是看client和server之間進(jìn)行RPC通訊的過程寝并,那么流程如下:

所以用這個框架分3步:

  1. IDL語法寫demo.thrift文件

  2. thrift --gen <language> <demo.thrift>生成接口

  3. 有了接口箫措,自己實現(xiàn)這個接口

Demo:

Thrift文件:

service Calculator extends shared.SharedService {

  /**
   * A method definition looks like C code. It has a return type, arguments,
   * and optionally a list of exceptions that it may throw. Note that argument
   * lists and exception lists are specified using the exact same syntax as
   * field lists in struct or exception definitions.
   */
   void ping(),

   i32 add(1:i32 num1, 2:i32 num2),

   i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),

   /**
    * This method has a oneway modifier. That means the client only makes
    * a request and does not listen for any response at all. Oneway methods
    * must be void.
    */
   oneway void zip()

}

Python client:

def main():
    # socket傳輸,后面用buffer封裝socket,協(xié)議用binary,上層用client封裝,然后就可以調(diào)用了
    transport = TSocket.TSocket('localhost', 9090)

    # Buffering is critical. Raw sockets are very slow
    transport = TTransport.TBufferedTransport(transport)

    # Wrap in a protocol
    protocol = TBinaryProtocol.TBinaryProtocol(transport)

    # Create a client to use the protocol encoder
    client = Calculator.Client(protocol)

    # Connect!
    transport.open()

    client.ping()
    print('ping()')

    sum_ = client.add(1, 1)

Java Server (注意Calculator.java這個自動生成的接口文件沒寫)

// initialize server
try {
      TServerTransport serverTransport = new TServerSocket(9090);
      TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));

      // Use this for a multithreaded server
      // TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));

      System.out.println("Starting the simple server...");
      server.serve();
    } catch (Exception e) {
      e.printStackTrace();
    }
// 自定義實現(xiàn)類
public class CalculatorHandler implements Calculator.Iface {
        // ...
}

參考

  1. https://en.wikipedia.org/wiki/Apache_Thrift

  2. https://thrift.apache.org/

  3. https://coding.imooc.com/learn/list/198.html

  4. https://sunchao.github.io/posts/2015-09-22-understanding-how-thrift-works.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市衬潦,隨后出現(xiàn)的幾起案子斤蔓,更是在濱河造成了極大的恐慌,老刑警劉巖镀岛,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弦牡,死亡現(xiàn)場離奇詭異友驮,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)驾锰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進(jìn)店門卸留,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人椭豫,你說我怎么就攤上這事耻瑟。” “怎么了赏酥?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵喳整,是天一觀的道長。 經(jīng)常有香客問我裸扶,道長框都,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任呵晨,我火速辦了婚禮魏保,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘何荚。我一直安慰自己囱淋,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布餐塘。 她就那樣靜靜地躺著妥衣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戒傻。 梳的紋絲不亂的頭發(fā)上税手,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機(jī)與錄音需纳,去河邊找鬼芦倒。 笑死,一個胖子當(dāng)著我的面吹牛不翩,可吹牛的內(nèi)容都是我干的兵扬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼口蝠,長吁一口氣:“原來是場噩夢啊……” “哼器钟!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起妙蔗,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤傲霸,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昙啄,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡穆役,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了梳凛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耿币。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖韧拒,靈堂內(nèi)的尸體忽然破棺而出掰读,到底是詐尸還是另有隱情,我是刑警寧澤叭莫,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布蹈集,位于F島的核電站,受9級特大地震影響雇初,放射性物質(zhì)發(fā)生泄漏拢肆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一靖诗、第九天 我趴在偏房一處隱蔽的房頂上張望郭怪。 院中可真熱鬧,春花似錦刊橘、人聲如沸鄙才。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽攒庵。三九已至,卻和暖如春败晴,著一層夾襖步出監(jiān)牢的瞬間浓冒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工尖坤, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留稳懒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓慢味,卻偏偏與公主長得像场梆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子纯路,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355