成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

從網(wǎng)絡(luò)IO到Thrift網(wǎng)絡(luò)模型

馬永翠 / 2247人閱讀

摘要:基本原理函數(shù)監(jiān)視的文件描述符分類,分別是和。具體模型如下與模式相比,在完成數(shù)據(jù)讀取之后,將業(yè)務(wù)處理過程交由一個(gè)線程池來完成,主線程直接返回進(jìn)行下一次循環(huán)操作,效率大大提升。是提供的最高效的網(wǎng)絡(luò)模型。

I/O多路復(fù)用

IO多路復(fù)用就是通過一種機(jī)制,一個(gè)進(jìn)程可以監(jiān)聽多個(gè)文件描述符,一個(gè)某個(gè)描述符就緒(一般是讀就緒或?qū)懢途w),就能夠通知程序進(jìn)行相應(yīng)的讀寫操作。select、poll、epoll本質(zhì)上都是同步IO,因?yàn)樗麄冃枰谧x寫事件就緒后自己負(fù)責(zé)讀寫,即這個(gè)讀寫過程是阻塞的,而異步IO則無需自己負(fù)責(zé)讀寫,異步IO的實(shí)現(xiàn)會(huì)把數(shù)據(jù)從內(nèi)核拷貝到用戶空間。

select 基本原理

select 函數(shù)監(jiān)視的文件描述符分3類,分別是writefds、readfds、和exceptfds。調(diào)用后select函數(shù)會(huì)阻塞,直到有描述符就緒(有數(shù)據(jù) 可讀、可寫、或者有except),或者超時(shí)(timeout指定等待時(shí)間,如果立即返回設(shè)為null即可),函數(shù)返回。當(dāng)select函數(shù)返回后,可以通過遍歷fdset,來找到就緒的描述符。

select的缺點(diǎn)

單進(jìn)程所能打開的文件描述符有一定限制,32位機(jī)默認(rèn)1028,64位機(jī)默認(rèn)2048。

對(duì)socket進(jìn)程掃描時(shí)是線性掃描,效率很低。

用來存放文件描述符的數(shù)據(jù)結(jié)構(gòu),在用戶空間和內(nèi)核空間的復(fù)制開銷極大。

poll

poll與select類似,略過。

epoll

epoll是在linux 2.6內(nèi)核中提出的,是select和poll的增強(qiáng)版本。

基本原理

epoll支持水平觸發(fā)和邊緣觸發(fā),最大的特點(diǎn)在于邊緣觸發(fā),它只告訴進(jìn)程哪些fd剛剛變?yōu)榫途w態(tài),并且只會(huì)通知一次。還有一個(gè)特點(diǎn)是,epoll使用“事件”的就緒通知方式,一旦該fd就緒,內(nèi)核就會(huì)采用類似callback的回調(diào)機(jī)制來激活該fd。

epoll的優(yōu)點(diǎn)

沒有最大連接數(shù)的限制,1G內(nèi)存約能監(jiān)聽10W個(gè)端口。

不采用輪詢的方式,不會(huì)隨著FD數(shù)目的增加效率下降。只有活躍可用的FD才會(huì)回調(diào)。

內(nèi)存拷貝,epoll使用mmap減少復(fù)制開銷。(注:mmap本質(zhì)就是繞過從網(wǎng)卡、磁盤拷貝數(shù)據(jù)到內(nèi)核再拷貝到用戶空間的方式,直接從網(wǎng)卡拷貝數(shù)據(jù)到用戶空間,性能爆炸。)

Thrift網(wǎng)絡(luò)服務(wù)模型

thrift提供的網(wǎng)絡(luò)服務(wù)模型有阻塞服務(wù)模型、非阻塞服務(wù)模型:

阻塞服務(wù)模型:TSimpleServer、TThreadPoolServer

非阻塞服務(wù)模型:TNonblockingServer、THsHaServer和TThreadedSelectorServer

TSimpleServer

該模式采用最簡單的阻塞IO,一次只能接收并處理一個(gè)socket,處理流程如下:

此種模式效率低下,生產(chǎn)不會(huì)使用,略過。

TThreadPoolServer

TThreadPoolServer模式采用阻塞socket方式工作,主線程負(fù)責(zé)阻塞式(劃重點(diǎn),不是select的方式)監(jiān)聽是否有新socket到來,具體的業(yè)務(wù)處理交由一個(gè)線程池來處理。

accept部分的代碼如下:

  protected TSocket acceptImpl() throws TTransportException {
    if (serverSocket_ == null) {
      throw new TTransportException(TTransportException.NOT_OPEN, "No underlying server socket.");
    }
    try {
      // 阻塞式監(jiān)聽新的連接
      Socket result = serverSocket_.accept();
      TSocket result2 = new TSocket(result);
      result2.setTimeout(clientTimeout_);
      return result2;
    } catch (IOException iox) {
      throw new TTransportException(iox);
    }
  }

具體模型如下:

TThreadPoolServer本質(zhì)是One Thread Per Connection模型。模型受限于線程池的最大線程數(shù),在連接數(shù)很大話,請(qǐng)求只能排隊(duì),對(duì)于高并發(fā)的場景,此模型并不合適。

TNonblockingServer

TNonblockingServer模式也是單線程工作,但是采用NIO的模式,借助Channel/Selector機(jī)制, 采用IO事件模型來處理。本質(zhì)是一種event-loop模型。

具體模型如下:

event-loop的核心代碼如下:

    private void select() {
      try {
        // 等待事件,jdk7之前的版本存在問題,會(huì)存在會(huì)將CPU打滿的情況,沒有事件,select卻返回,從而將CPU打滿;Netty中通過threshold,解決了該問題
        selector.select();

        // 獲取IO事件
        Iterator 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);
      }
    }

這個(gè)模型一般由一個(gè)event dispatcher等待各類事件,待事件發(fā)生后原地調(diào)用對(duì)應(yīng)的event handler,全部調(diào)用完后等待更多事件,故為"loop"。這個(gè)模型的實(shí)質(zhì)是把多段邏輯按事件觸發(fā)順序交織在一個(gè)系統(tǒng)線程中。一個(gè)event-loop只能使用一個(gè)核,故此類程序要么是IO-bound,要么是每個(gè)handler有確定的較短的運(yùn)行時(shí)間(比如http server),否則一個(gè)耗時(shí)漫長的回調(diào)就會(huì)卡住整個(gè)程序,產(chǎn)生高延時(shí)。在實(shí)踐中這類程序不適合多開發(fā)者參與,一個(gè)人寫了阻塞代碼可能就會(huì)拖慢其他代碼的響應(yīng)。由于event handler不會(huì)同時(shí)運(yùn)行,不太會(huì)產(chǎn)生復(fù)雜的race condition,一些代碼不需要鎖。此類程序主要靠部署更多進(jìn)程增加擴(kuò)展性。

THsHaServer

THsHaServer繼承于TNonblockingServer,引入了線程池提高了任務(wù)處理的并發(fā)能力。THsHaServer是半同步半異步(Half-Sync/Half-Async)的處理模式,Half-Aysnc用于IO事件處理(Accept/Read/Write),Half-Sync用于業(yè)務(wù)handler對(duì)rpc的同步處理上。

具體模型如下:

THsHaServer與TNonblockingServer模式相比,THsHaServer在完成數(shù)據(jù)讀取之后,將業(yè)務(wù)處理過程交由一個(gè)線程池來完成,主線程直接返回進(jìn)行下一次循環(huán)操作,效率大大提升。

但是,主線程仍然需要處理accpet、read、write時(shí)間,當(dāng)并發(fā)量非常大,讀取或者發(fā)送的數(shù)據(jù)量比較大時(shí),會(huì)將主線程阻塞住,新的連接無法被及時(shí)處理。

TThreadedSelectorServer

TThreadedSelectorServer是對(duì)THsHaServer的一種改進(jìn),它將selector中的read/write事件從主線程中剝離出來。

TThreadedSelectorServer是thrift提供的最高效的網(wǎng)絡(luò)模型。具體模型如下:

構(gòu)成如下:

一個(gè)Accpet線程,專門用來處理新的socket

n個(gè)SelectorThread,用來處理read/write事件,讀取、返回?cái)?shù)據(jù)都是有這些線程完成的,每個(gè)SelectorThread會(huì)與若干個(gè)socket綁定,每個(gè)SelectorThread會(huì)處理與它綁定socket的read/write事件。

一個(gè)負(fù)載均衡器SelectorThreadLoadBalancer對(duì)象,在accpet線程接收到新的socket以后,由SelectorThreadLoadBalancer決定將socket與哪個(gè)SelectorThread綁定(其實(shí)就是一個(gè)next函數(shù),每分配一個(gè)socket,就調(diào)用next)。

一個(gè)ExecutorService類型的worker線程池,在SelectorThread讀取數(shù)據(jù)之后,將其包裝成一個(gè)task,分配給worker線程池,處理業(yè)務(wù)邏輯。

總結(jié):TThreadedSelectorServer模式,其實(shí)就是標(biāo)準(zhǔn)的Reactor模式,Tomcat7以后的版本、Cobar、MyCat(分庫分表proxy)基本都是這個(gè)套路,具體實(shí)現(xiàn)略有差異。

原文鏈接

https://segmentfault.com/a/11...

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/76986.html

相關(guān)文章

  • Thrift 簡易入門與實(shí)戰(zhàn)

    摘要:簡介是一個(gè)軟件框架用來進(jìn)行可擴(kuò)展且跨語言的服務(wù)的開發(fā)它結(jié)合了功能強(qiáng)大的軟件堆棧和代碼生成引擎以構(gòu)建在這些編程語言間無縫結(jié)合的高效的服務(wù)官網(wǎng)地址安裝的安裝比較簡單在下可以直接使用快速安裝或可以通過官網(wǎng)下載這里就不再多說了當(dāng)下載安裝完畢后我們就 簡介 thrift是一個(gè)軟件框架, 用來進(jìn)行可擴(kuò)展且跨語言的服務(wù)的開發(fā). 它結(jié)合了功能強(qiáng)大的軟件堆棧和代碼生成引擎, 以構(gòu)建在 C++, Java...

    iliyaku 評(píng)論0 收藏0
  • Thrift架構(gòu)

    摘要:服務(wù)器端使用它來做頂層接口,編寫實(shí)現(xiàn)類。會(huì)自動(dòng)生成同步調(diào)用和異步調(diào)用的兩個(gè)接口。方法參數(shù)的封裝類,以方法名命名方法返回值的封裝類,以方法名命名參考個(gè)人博客 基本概念 輕量級(jí)、跨語言的RPC框架 功能特點(diǎn): 基于IDL(接口描述語言)生成跨語言的RPC clients and servers,支持超過20種語言 支持二進(jìn)制的高性能的編解碼框架 支持NIO的底層通信 相對(duì)簡單的服務(wù)調(diào)用模...

    wall2flower 評(píng)論0 收藏0
  • thrift調(diào)用流程分析

    摘要:由于工作需要使用,并且需要根據(jù)需求修改源碼,因此必須熟悉執(zhí)行的流程。目前支持的模型包括使用阻塞的單線程服務(wù)器,主要用于調(diào)試。 由于工作需要使用thrift,并且需要根據(jù)需求修改thrift源碼,因此必須熟悉thrift執(zhí)行的流程。以下是根據(jù)thrift源碼閱讀而得出流程分析。 thrift協(xié)議棧概述 thrift是一個(gè)rpc框架,開發(fā)者可以通過thrift自帶的接口定義語言(IDL)來...

    nidaye 評(píng)論0 收藏0
  • 使用swoole運(yùn)行thrift服務(wù)

    摘要:是一種接口描述語言和二進(jìn)制通訊協(xié)議,它被用來定義和創(chuàng)建跨語言的服務(wù)。它被當(dāng)作一個(gè)遠(yuǎn)程過程調(diào)用框架來使用,是由為大規(guī)??缯Z言服務(wù)開發(fā)而開發(fā)的。筆者使用的異步服務(wù)端提供的接口實(shí)現(xiàn)一個(gè)了異步協(xié)程化的應(yīng)用。 Swoole擴(kuò)展簡介 Swoole:面向生產(chǎn)環(huán)境的 PHP 異步網(wǎng)絡(luò)通信引擎使 PHP 開發(fā)人員可以編寫高性能的異步并發(fā) TCP、UDP、Unix Socket、HTTP,WebSock...

    Hancock_Xu 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<