<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    聶永的博客

    記錄工作/學(xué)習(xí)的點(diǎn)點(diǎn)滴滴。

    基于Erlang OTP構(gòu)建一個(gè)TCP服務(wù)器

    套接字模式

    主動(dòng)模式(選項(xiàng){active, true})一般讓人很喜歡,非阻塞消息接收,但在系統(tǒng)無(wú)法應(yīng)對(duì)超大流量請(qǐng)求時(shí),客戶端發(fā)送的數(shù)據(jù)快過(guò)服務(wù)器可以處理的速度,那么系統(tǒng)就可能會(huì)造成消息緩沖區(qū)被塞滿,可能出現(xiàn)持續(xù)繁忙的流量的極端情況下,系統(tǒng)因請(qǐng)求而溢出,虛擬機(jī)造成內(nèi)存不足的風(fēng)險(xiǎn)而崩潰。

    使用被動(dòng)模式(選項(xiàng){active, false})的套接字,底層的TCP緩沖區(qū)可用于抑制請(qǐng)求,并拒絕客戶端的消息,在接收數(shù)據(jù)的地方都會(huì)調(diào)用gen_tcp:recv,造成阻塞(單進(jìn)程模式下就只能消極等待某一個(gè)具體的客戶端套接字,很危險(xiǎn))。需要注意的是,操作系統(tǒng)可能還會(huì)做一些緩存允許客戶端機(jī)器繼續(xù)發(fā)送少量數(shù)據(jù),然后才會(huì)將其阻塞,此時(shí)Erlang尚未調(diào)用recv函數(shù)。

    混合型模式(半阻塞),使用選項(xiàng){active, once}打開(kāi),主動(dòng)僅針對(duì)一個(gè)消息,在控制進(jìn)程發(fā)送完一個(gè)數(shù)據(jù)消息后,必須顯示調(diào)用inet:setopts(Socket, [{active, once}])重新激活以便接受下一個(gè)消息(在此之前,系統(tǒng)處于阻塞狀態(tài))。可見(jiàn),混合型模式綜合了主動(dòng)模式和被動(dòng)模式的兩者優(yōu)勢(shì),可實(shí)現(xiàn)流量控制,防止服務(wù)器被過(guò)多消息淹沒(méi)。

    以下TCP Server代碼,都是建立在混合型模式(半阻塞)基礎(chǔ)上。

    prim_inet相關(guān)說(shuō)明

    prim_inet沒(méi)有官方文檔,可以認(rèn)為是對(duì)底層socket的直接包裝。淘寶yufeng說(shuō),這是otp內(nèi)部實(shí)現(xiàn)的細(xì)節(jié) 是針對(duì)Erlang庫(kù)開(kāi)發(fā)者的private module,底層模塊,不推薦使用。但在Building a Non-blocking TCP server using OTP principles示范中演示了prim_inet操作Socket異步特性。

    設(shè)計(jì)模式

    一般來(lái)說(shuō),需要一個(gè)單獨(dú)進(jìn)程進(jìn)行客戶端套接字監(jiān)聽(tīng),每一個(gè)子進(jìn)程進(jìn)行處理來(lái)自具體客戶端的socket請(qǐng)求。

    Building a Non-blocking TCP server using OTP principles示范中,子進(jìn)程使用gen_fsm處理,很巧妙的結(jié)合狀態(tài)機(jī)和消息事件,值得學(xué)習(xí)。

    Erlang: A Generalized TCP Server文章中,作者也是使用此模式,但子進(jìn)程不符合OTP規(guī)范,因此個(gè)人認(rèn)為不是一個(gè)很好的實(shí)踐模式。

    simple_one_for_one

    簡(jiǎn)易的一對(duì)一監(jiān)督進(jìn)程,用來(lái)創(chuàng)建一組動(dòng)態(tài)子進(jìn)程。對(duì)于需要并發(fā)處理多個(gè)請(qǐng)求的服務(wù)器較為合適。比如socket 服務(wù)端接受新的客戶端連接請(qǐng)求以后,需要?jiǎng)討B(tài)創(chuàng)建一個(gè)新的socket連接處理子進(jìn)程。若遵守OTP原則,那就是子監(jiān)督進(jìn)程。

    TCP Server實(shí)現(xiàn) 

    基于標(biāo)準(zhǔn)API簡(jiǎn)單實(shí)現(xiàn)

    也是基于{active, once}模式,但阻塞的等待下一個(gè)客戶端連接的任務(wù)被拋給了子監(jiān)督進(jìn)程。

    看一下入口tcp_server_app吧

    讀取端口,然后啟動(dòng)主監(jiān)督進(jìn)程(此時(shí)還不會(huì)監(jiān)聽(tīng)處理客戶端socket請(qǐng)求),緊接著啟動(dòng)子監(jiān)督進(jìn)程,開(kāi)始處理來(lái)自客戶端的socket的連接。

    監(jiān)督進(jìn)程tcp_server_sup也很簡(jiǎn)單:

    需要注意的是,只有調(diào)用start_child函數(shù)時(shí),才真正調(diào)用tcp_server_handler:start_link([LSock])函數(shù)。

    tcp_server_handler的代碼也不復(fù)雜:

    代碼很精巧,有些小技巧在里面。子監(jiān)督進(jìn)程調(diào)用start_link函數(shù),init會(huì)返回{ok, #state{lsock = Socket}, 0}. 數(shù)字0代表了timeout數(shù)值,意味著gen_server馬上調(diào)用handle_info(timeout, #state{lsock = LSock} = State)函數(shù),執(zhí)行客戶端socket監(jiān)聽(tīng),阻塞于此,但不會(huì)影響在此模式下其它函數(shù)的調(diào)用。直到有客戶端進(jìn)來(lái),然后啟動(dòng)一個(gè)新的子監(jiān)督進(jìn)程tcp_server_handler,當(dāng)前子監(jiān)督進(jìn)程解除阻塞。

     

    基于prim_inet實(shí)現(xiàn)

    這個(gè)實(shí)現(xiàn)師從于Non-blocking TCP server using OTP principles一文,但子進(jìn)程改為了gen_server實(shí)現(xiàn)。

    看一看入口,很簡(jiǎn)單的:

    監(jiān)督進(jìn)程代碼:

    策略不一樣,one_for_one包括了一個(gè)監(jiān)聽(tīng)進(jìn)程tcp_listener,還包含了一個(gè)tcp_client_sup進(jìn)程樹(shù)(simple_one_for_one策略)

    tcp_listener單獨(dú)一個(gè)進(jìn)程用于監(jiān)聽(tīng)來(lái)自客戶端socket的連接:

    很顯然,接收客戶端的連接之后,轉(zhuǎn)交給tcp_client_handler模塊進(jìn)行處理:

    和標(biāo)準(zhǔn)API對(duì)比一下,可以感受到異步IO的好處。

    小結(jié)

    通過(guò)不同的模式,簡(jiǎn)單實(shí)現(xiàn)一個(gè)基于Erlang OTP的TCP服務(wù)器,也是學(xué)習(xí)總結(jié),不至于忘記。

    您若有更好的建議,歡迎告知,謝謝。

    參考資料

    1. Building a Non-blocking TCP server using OTP principles
    2. Erlang: A Generalized TCP Server
    3. 《Erlang程序設(shè)計(jì)》
    4. 《Erlang/OTP并發(fā)編程實(shí)戰(zhàn)》

    posted on 2012-10-24 18:14 nieyong 閱讀(13100) 評(píng)論(1)  編輯  收藏 所屬分類(lèi): Socket

    評(píng)論

    # re: 基于Erlang OTP構(gòu)建一個(gè)TCP服務(wù)器 2013-12-26 15:51 yf2800z

    你好,我用了你的第一個(gè)服務(wù)端做了下實(shí)驗(yàn),我的系統(tǒng)是mac 10.9osx 在啟動(dòng)客戶端連接后 我連接了243個(gè)連接 就不能在連接了 這是為什么 能具體的指導(dǎo)下嗎?  回復(fù)  更多評(píng)論   

    公告

    所有文章皆為原創(chuàng),若轉(zhuǎn)載請(qǐng)標(biāo)明出處,謝謝~

    新浪微博,歡迎關(guān)注:

    導(dǎo)航

    <2012年10月>
    30123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    統(tǒng)計(jì)

    常用鏈接

    留言簿(58)

    隨筆分類(lèi)(130)

    隨筆檔案(151)

    個(gè)人收藏

    最新隨筆

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 国产午夜亚洲精品不卡免下载| 亚洲成av人在片观看| 亚洲一区免费观看| 四虎国产成人永久精品免费| 亚洲午夜无码片在线观看影院猛| 国产亚洲高清不卡在线观看| 亚洲av无码国产精品色午夜字幕 | 小日子的在线观看免费| a级亚洲片精品久久久久久久 | 免费国产真实迷j在线观看| 久久久久亚洲AV综合波多野结衣| 亚洲尹人九九大色香蕉网站| 久久亚洲国产成人影院| 深夜免费在线视频| 日本在线免费观看| 国产精品va无码免费麻豆| 久久亚洲国产午夜精品理论片| 亚洲精品无码av片| 国产免费一区二区视频| 日韩人妻无码免费视频一区二区三区| 国产AV无码专区亚洲AV手机麻豆| 国产午夜精品理论片免费观看 | 日本高清在线免费| 国产又粗又猛又爽又黄的免费视频| WWW国产亚洲精品久久麻豆| 黄色网址免费大全| 亚洲色大成网站WWW久久九九| 亚洲高清乱码午夜电影网| 日本中文一区二区三区亚洲| 亚洲高清资源在线观看| 一级做a爰片久久毛片免费陪 | 亚洲国产成人久久综合野外| aa在线免费观看| 亚洲国产综合人成综合网站| 亚洲首页国产精品丝袜| 97人妻精品全国免费视频 | 久草免费手机视频| 学生妹亚洲一区二区| 亚洲国产一区视频| 亚洲精品视频免费看| 亚洲激情黄色小说|