Thrift server比較和使用

Thrift提供了多種服務器實現(xiàn)羡玛。

WechatIMG20.jpeg

它們各有特點稼稿,適應不同的需求環(huán)境。下面我將結(jié)合網(wǎng)絡資源和自己的理解來梳理一下Thrift各種java server的特點和使用姿勢渺杉。

  • TSimpleServer

while (!stopped_) {
  TTransport client = null;
  TProcessor processor = null;
  TTransport inputTransport = null;
  TTransport outputTransport = null;
  TProtocol inputProtocol = null;
  TProtocol outputProtocol = null;
  ServerContext connectionContext = null;
  try {
    client = serverTransport_.accept();
    if (client != null) {
      processor = processorFactory_.getProcessor(client);
      inputTransport = inputTransportFactory_.getTransport(client);
      outputTransport = outputTransportFactory_.getTransport(client);
      inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
      outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
      if (eventHandler_ != null) {
        connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol);
      }
      while (true) {
        if (eventHandler_ != null) {
          eventHandler_.processContext(connectionContext, inputTransport, outputTransport);
        }
        if(!processor.process(inputProtocol, outputProtocol)) {
          break;
        }
      }
    }
  }
}

TSimplerServer在while循環(huán)中每次接受一個連接是越,處理連接請求,直到客戶端關閉了連接浦徊,它才會去接受一個新的連接。由于它只在一個單獨的線程中以阻塞I/O的方式完成這些工作霞丧,所以它只能服務一個客戶端連接冕香,其他所有客戶端在被服務器端接受之前都只能等待。其使用方法如下:

public static void sample() throws Exception {
    ServerSocket socket = new ServerSocket(8912);
    TServerSocket serverTransport = new TServerSocket(socket); // HelloServiceImpl 為自己實現(xiàn)的Thrift服務接口的具體實現(xiàn)  
    TServer server = new TSimpleServer(new TServer.Args(serverTransport).processor(processor));
    System.out.println("Server start...");
    server.serve();
}
  • TNonblockingServer

public void run() {
  try {
    if (eventHandler_ != null) {
      eventHandler_.preServe();
    }

    while (!stopped_) {
      select();
      processInterestChanges();
    }
    for (SelectionKey selectionKey : selector.keys()) {
      cleanupSelectionKey(selectionKey);
    }
  } catch (Throwable t) {
    LOGGER.error("run() exiting due to uncaught error", t);
  } finally {
    try {
      selector.close();
    } catch (IOException e) {
      LOGGER.error("Got an IOException while closing selector!", e);
    }
    stopped_ = true;
  }
}
private void select() {
  try {
    // wait for io events.
    selector.select();

    // process the io events we received
    Iterator<SelectionKey> selectedKeys = selector.selectedKeys().iterator();
    while (!stopped_ && selectedKeys.hasNext()) {
      SelectionKey key = selectedKeys.next();
      selectedKeys.remove();

      // skip if not valid
      if (!key.isValid()) {
        cleanupSelectionKey(key);
        continue;
      }

      // if the key is marked Accept, then it has to be the server
      // transport.
      if (key.isAcceptable()) {
        handleAccept();
      } else if (key.isReadable()) {
        // deal with reads
        handleRead(key);
      } else if (key.isWritable()) {
        // deal with writes
        handleWrite(key);
      } else {
        LOGGER.warn("Unexpected state in select! " + key.interestOps());
      }
    }
  } catch (IOException e) {
    LOGGER.warn("Got an IOException while selecting!", e);
  }
}

TNonblockingServer 使用非阻塞的 I/O 解決了TSimpleServer一個客戶端阻塞其他所有客戶端的問題。它使用了java.nio.channels.Selector愕难,通過調(diào)用select()惫霸,它使得你阻塞在多個連接上,而不是阻塞在單一的連接上猜丹。當一或多個連接準備好被接受/讀/寫時茫打,select()調(diào)用便會返回。TNonblockingServer處理這些連接的時候轮洋,要么接受它抬旺,要么從它那讀數(shù)據(jù),要么把數(shù)據(jù)寫到它那里开财,然后再次調(diào)用select()來等待下一個可用的連接责鳍。通用這種方式,server可同時服務多個客戶端历葛,而不會出現(xiàn)一個客戶端把其他客戶端全部“餓死”的情況。
使用方法:

public static void nonBlock() throws TTransportException {
    TNonblockingServerSocket serverSocket = new TNonblockingServerSocket(8912);
    Hello.Processor processor = new Hello.Processor(new HelloServiceImpl());
    TNonblockingServer.Args args = new TNonblockingServer.Args(serverSocket);
    args.transportFactory(new TFramedTransport.Factory());
    args.protocolFactory(new TCompactProtocol.Factory());
    args.processor(processor);
    TNonblockingServer server = new TNonblockingServer(args);
    server.serve();
}
  • ThreadedSelectorServer

ThreadedSelectorServer允許你用多個線程來處理網(wǎng)絡 I/O乓诽。它維護了兩個線程池鸠天,一個用來處理網(wǎng)絡 I/O,另一個用來進行請求的處理稠集。使用方法:

public static void threadSelector() throws TTransportException, IOException {
    TNonblockingServerSocket serverSocket = new TNonblockingServerSocket(8912);
    Hello.Processor processor = new Hello.Processor(new HelloServiceImpl());
    TThreadedSelectorServer.Args args = new TThreadedSelectorServer.Args(serverSocket);
    args.transportFactory(new TFramedTransport.Factory());
    args.protocolFactory(new TBinaryProtocol.Factory());
    args.selectorThreads(10);
    args.acceptQueueSizePerThread(10);
    args.processor(processor);
    TThreadedSelectorServer server = new TThreadedSelectorServer(args);
    server.serve();
}
  • TThreadPoolServer

TThreadPoolServer有一個專用的線程用來接受連接旦接受了一個連接巍杈,它就會被放入ThreadPoolExecutor中的一個 worker 線程里處理。worker 線程被綁定到特定的客戶端連接上筷畦,直到它關閉刺洒。一旦連接關閉逆航,該worker線程就又回到了線程池中。你可以配置線程池的最小因俐、最大線程數(shù),默認值分別是5(最谐盘)和Integer.MAX_VALUE(最大)澳眷。使用方法:

public static void threadPool() throws Exception {
    TNonblockingServerSocket serverSocket = new TNonblockingServerSocket(8912);
    Hello.Processor processor = new Hello.Processor(new HelloServiceImpl());
    TThreadPoolServer.Args args = new TThreadPoolServer.Args(serverSocket);
    args.transportFactory(new TFramedTransport.Factory());
    args.protocolFactory(new TBinaryProtocol.Factory());
    args.processor(processor);
    args.maxWorkerThreads(10);
    TThreadPoolServer server = new TThreadPoolServer(args);
    server.serve();
}
最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钳踊,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子缴罗,更是在濱河造成了極大的恐慌祭埂,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異侧但,居然都是意外死亡矢空,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門禀横,熙熙樓的掌柜王于貴愁眉苦臉地迎上來屁药,“玉大人,你說我怎么就攤上這事柏锄∧鸺” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵趾娃,是天一觀的道長缭嫡。 經(jīng)常有香客問我,道長妇蛀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任笤成,我火速辦了婚禮评架,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘炕泳。我一直安慰自己纵诞,他們只是感情好,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布培遵。 她就那樣靜靜地躺著浙芙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪籽腕。 梳的紋絲不亂的頭發(fā)上嗡呼,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天,我揣著相機與錄音节仿,去河邊找鬼晤锥。 笑死,一個胖子當著我的面吹牛廊宪,可吹牛的內(nèi)容都是我干的矾瘾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼箭启,長吁一口氣:“原來是場噩夢啊……” “哼壕翩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起傅寡,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤放妈,失蹤者是張志新(化名)和其女友劉穎北救,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芜抒,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡珍策,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了宅倒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片攘宙。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖拐迁,靈堂內(nèi)的尸體忽然破棺而出痪蝇,到底是詐尸還是另有隱情绿语,我是刑警寧澤,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布檐盟,位于F島的核電站蔓同,受9級特大地震影響缆娃,放射性物質(zhì)發(fā)生泄漏亏较。R本人自食惡果不足惜遏佣,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望割卖。 院中可真熱鬧前酿,春花似錦、人聲如沸鹏溯。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽丙挽。三九已至,卻和暖如春匀借,著一層夾襖步出監(jiān)牢的瞬間颜阐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工吓肋, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凳怨,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓是鬼,卻偏偏與公主長得像肤舞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子均蜜,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

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

  • 聊聊阻塞與非阻塞偶芍、同步與異步、I/O 模型 來源:huangguisu 鏈接:http://blog.csdn.n...
    meng_philip123閱讀 1,642評論 1 13
  • NIO(Non-blocking I/O德玫,在Java領域匪蟀,也稱為New I/O),是一種同步非阻塞的I/O模型宰僧,也...
    閃電是只貓閱讀 3,116評論 0 7
  • 1. Java基礎部分 基礎部分的順序:基本語法材彪,類相關的語法,內(nèi)部類的語法撒桨,繼承相關的語法查刻,異常的語法,線程的語...
    子非魚_t_閱讀 31,639評論 18 399
  • 我以前就是一個淘寶購物狂凤类,經(jīng)常是沒有時間出門穗泵,上班沒有假期所以,慢慢就成了淘寶購物狂谜疤。什么東西都喜歡網(wǎng)上購...
    一朵白薔薇閱讀 137評論 0 0
  • 下雨天夷磕,很冷履肃,就要穿厚點兒也要記得帶傘。不要讓自己那么狼狽坐桩,所有能預先知道的事情尺棋,你就要有所準備。你明明更新過天氣...
    92b1602690b6閱讀 346評論 0 0