双11怎么那么强!之二:浅析淘宝网络通信库tbnet的实现
最近開(kāi)始看Tair的源碼實(shí)現(xiàn),Tair的通信使用的是淘寶的開(kāi)源的網(wǎng)絡(luò)庫(kù)tbnet實(shí)現(xiàn)。具體來(lái)說(shuō)是依靠tbnet::Transport類(lèi)型實(shí)現(xiàn),其源代碼路徑如下:
http://code.taobao.org/svn/tb-common-utils/trunk/tbnet/src
下面介紹其通信流程:
1. 啟動(dòng)
Transport::start()完成其啟動(dòng),主要工作是啟動(dòng)了兩個(gè)線(xiàn)程:_readWriteThread和_timeoutThread.?這兩個(gè)線(xiàn)程的實(shí)際入口函數(shù)式Tranport::run(),?下面是Transport::run的實(shí)現(xiàn):
?
?
?
????A.?讀寫(xiě)線(xiàn)程:
????????1. 讀寫(xiě)線(xiàn)程使用epoll實(shí)現(xiàn),在Transport中存在一個(gè)EPollSocketEvent _socketEvent 成員變量, arg傳入的是這個(gè)成員變量的指針,EPollSocketEvent是epoll個(gè)操作的封裝,在EPollSocketEvent的構(gòu)造函數(shù)中會(huì)調(diào)用epoll_create初始化epoll。
????????2. eventLoop的實(shí)現(xiàn)步驟如下:
????????????????a.? 調(diào)用socketEvent->getEvents()?取得發(fā)生的事件并放入到ioevents數(shù)組中
????????????????????????i.??調(diào)用epoll_wait等待讀寫(xiě)事件;
????????????????????????ii.?每個(gè)事件的events[i].data.ptr存放有事件對(duì)應(yīng)的IOComonet(socket 封裝),可以用來(lái)處理讀寫(xiě)事件;
????????????????b.??對(duì)于讀寫(xiě)事件,分別調(diào)用ioc->handleReadEvent()和ioc->handleWriteEvent()處理;
????
????B. timeout線(xiàn)程
????????1. 主要用于檢查通信的socket是否超過(guò)一定時(shí)常沒(méi)有使用,對(duì)于TCPComponent(封裝通信socket),如果15分鐘沒(méi)有使用,則斷開(kāi)連接;
2. 監(jiān)聽(tīng)
通過(guò)調(diào)用Transport::listen()完成監(jiān)聽(tīng),?主要完成以下步驟:
????a.??創(chuàng)建TCPAcceptor,繼承于IOComonet(socket 封裝),并啟動(dòng)異步監(jiān)聽(tīng);
????b.?調(diào)用addComponent(acceptor, true, false);
????????????i.??創(chuàng)建epoll_event ev,設(shè)置ev.data.ptr = socket->getIOComponent(),用來(lái)處理讀寫(xiě)事件的IOComponentsocket 封裝)
????????????ii.?調(diào)用epoll_ctl(_iepfd,EPOLL_CTL_ADD,socket->getSocketHandle(),&ev)注冊(cè)監(jiān)聽(tīng)socket上的讀取事件;
????c. 當(dāng)客戶(hù)端有connect請(qǐng)求過(guò)來(lái)的時(shí)候會(huì)觸發(fā)監(jiān)聽(tīng)socket上的讀取事件,TCPAcceptor::handleReadEvent()會(huì)被調(diào)用。
3. 接受客戶(hù)端的連接請(qǐng)求
系統(tǒng)在TCPAcceptor::handleReadEvent()中接受客戶(hù)端的連接請(qǐng)求,主要步驟如下:
????a. socket = ((ServerSocket*)_socket)->accept()?接受連接請(qǐng)求并得到通信socket;
????b.?創(chuàng)建TCPComponent封裝通信socket;
????c.?調(diào)用addComponent(component, true, false) 注冊(cè)當(dāng)前socket的讀取事件。
4.?數(shù)據(jù)通信
????A.?數(shù)據(jù)讀取
?????????數(shù)據(jù)通信由通信socket完成,該socket在epoll中注冊(cè),當(dāng)有數(shù)據(jù)需要讀取的時(shí)候會(huì)觸發(fā)讀取事件并調(diào)用TCPComponent::handleReadEvent()處理。
????B.?數(shù)據(jù)發(fā)送
?????????當(dāng)有數(shù)據(jù)需要發(fā)送時(shí)Connection::postPacket()函數(shù),?這個(gè)函數(shù)中會(huì)調(diào)用_iocomponent->enableWrite(true),注冊(cè)寫(xiě)入事件,并調(diào)用TCPComponent::handleWriteEvent()處理。
轉(zhuǎn)載于:https://www.cnblogs.com/ranran/p/taobao_tongxin.html
與50位技術(shù)專(zhuān)家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的双11怎么那么强!之二:浅析淘宝网络通信库tbnet的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java继承 子类重写父类方法
- 下一篇: highcharts学习1----Lin