<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          網(wǎng)頁端收消息,究竟是推還是拉?

          共 2010字,需瀏覽 5分鐘

           ·

          2020-12-30 20:33

          任何脫離業(yè)務(wù)的架構(gòu)設(shè)計(jì)都是耍流氓。

          網(wǎng)頁端收消息,究竟是推還是拉?

          什么業(yè)務(wù)場(chǎng)景?
          對(duì)于在網(wǎng)頁端登錄的用戶A,發(fā)送方,也就是消息的來源有幾方面:
          (1)系統(tǒng)發(fā)給A的“系統(tǒng)通知”,可能對(duì)實(shí)時(shí)性要求沒這么高;
          (2)用戶發(fā)給A的“聊天消息”,有對(duì)實(shí)時(shí)性要求比較高,越實(shí)時(shí)越好;

          消息的處理方,也就是系統(tǒng)側(cè),一般來說:
          (1)有服務(wù)對(duì)消息進(jìn)行邏輯處理;
          (2)有數(shù)據(jù)庫對(duì)數(shù)據(jù)進(jìn)行落地;
          (3)有緩存對(duì)數(shù)據(jù)進(jìn)行加速;
          拋開這些技術(shù)細(xì)節(jié)不談,暫且認(rèn)為服務(wù)端對(duì)每一個(gè)用戶都有一個(gè)“待收消息”的隊(duì)列,里面存放了需要給這個(gè)用戶的一切消息。

          消息的接收方,也就是用戶A,如果是在網(wǎng)頁端登錄,因?yàn)镠TTP協(xié)議是“請(qǐng)求-響應(yīng)”式的,服務(wù)端與網(wǎng)頁之間沒有消息通道,對(duì)于這類“收消息”的需求,是如何處理的呢?

          方案一:輪詢拉取
          輪詢拉取,是最容易想到的實(shí)現(xiàn)方式:
          (1)發(fā)送方發(fā)送了消息,先入隊(duì)列;
          (2)網(wǎng)頁端起一個(gè)timer,每個(gè)一段時(shí)間(例如10秒),發(fā)起一個(gè)輪詢請(qǐng)求,拉取隊(duì)列里的消息;
          (3)如果隊(duì)列里有消息,就返回消息;
          (4)如果隊(duì)列里無消息,就10秒后再次輪詢;

          這種方式的優(yōu)勢(shì)是:實(shí)現(xiàn)簡單,直觀且,容易理解,互聯(lián)網(wǎng)興起時(shí),人數(shù)不多的聊天室就是這么玩的。
          畫外音:創(chuàng)辦于1996年的互聯(lián)網(wǎng)老站碧海銀沙,曾經(jīng)中國最火爆的聊天室,已于2017.9.27停止運(yùn)營。

          缺點(diǎn)也很明顯:
          (1)實(shí)時(shí)性差:最壞的情況下,1條消息進(jìn)入隊(duì)列后,10s之后才會(huì)收到;
          (2)效率低下:發(fā)消息是一個(gè)低頻動(dòng)作,如果10次輪詢才收到1條消息,請(qǐng)求有效性只有10%,浪費(fèi)了大量服務(wù)器資源;

          更要命的是,在這種方案下,實(shí)時(shí)性與效率是一對(duì)不可調(diào)和的矛盾:如果將輪詢周期設(shè)為1/10,將時(shí)延縮短到1秒,意味著100次輪詢才會(huì)收到1條消息,請(qǐng)求有效性則降為了1%。

          方案二:建立長連接
          如果要兼顧實(shí)時(shí)性和效率,長連接是最佳之選,PC端聊天軟件基本都是使用長連接。網(wǎng)頁端常見的實(shí)現(xiàn)長連接的方式有兩種:
          (1)WebSocket;
          (2)FlashSocket;
          這兩種方案的細(xì)節(jié)不再展開,ta們均有一定的局限性。

          更為通用的方式,是“長輪詢”
          長輪詢,是通過拼裝HTTP短連接來達(dá)到長連接的效果,即保證了消息100%實(shí)時(shí),又最大化的系統(tǒng)效率。

          方案三:HTTP長輪詢
          HTTP長輪詢的核心在于,瀏覽器與服務(wù)端之間建立了一條“通知連接”,它的特點(diǎn)是:
          (1)這是一條browser發(fā)往web-server的HTTP連接;
          (2)這條連接只用來收取推送通知;
          (3)不像普通的“請(qǐng)求-響應(yīng)”式HTTP請(qǐng)求,這個(gè)HTTP會(huì)被服務(wù)端夯住,直到有推送通知到達(dá),或者超過約定的時(shí)間;
          畫外音:對(duì)于HTTP請(qǐng)求,為了提高效率,一般來說browser和web-server都會(huì)有一些設(shè)置,如果一條HTTP請(qǐng)求長時(shí)間沒有數(shù)據(jù)(例如,150秒),會(huì)被斷開。“通知連接”為了不被browser和web-server粗暴斷開,一般會(huì)設(shè)置一個(gè)約定閾值(例如,小于150秒),由系統(tǒng)返回一個(gè)空消息,以便“優(yōu)雅返回”。

          更具體的,對(duì)于這條“夯住”與“只收推送通知”的“通知連接”,是怎么玩的呢?

          場(chǎng)景1,發(fā)起通知連接時(shí),隊(duì)列里正好消息,則:
          (1)發(fā)起通知連接,正好隊(duì)列里有消息;
          (2)實(shí)時(shí)把隊(duì)列里的消息帶回;
          (3)立馬再發(fā)起通知連接;

          場(chǎng)景二,發(fā)起通知連接時(shí),隊(duì)列里消息,則:
          (1)發(fā)起通知連接時(shí),隊(duì)列里無消息;
          (2)一直等待,直到觸發(fā)“時(shí)間閾值”,返回?zé)o消息;
          (3)立馬再發(fā)起通知連接;

          場(chǎng)景三,新消息來時(shí),正好通知連接在,則:
          (1)新消息來時(shí),正好有通知連接在;
          (2)通知連接實(shí)時(shí)將消息帶回;
          (3)立馬再發(fā)起通知連接;

          上面三個(gè)場(chǎng)景的最終狀態(tài),都是“一定,永遠(yuǎn),會(huì)有一條通知連接,連接在瀏覽器與服務(wù)器之間”,這樣就能夠保證消息的實(shí)時(shí)性。當(dāng)然,有人會(huì)說,HTTP的返回與再次發(fā)起會(huì)有一個(gè)時(shí)間差,如果這個(gè)時(shí)間差,恰巧有新消息過來呢?

          場(chǎng)景四,新消息來時(shí),沒有通知連接,則:
          (1)新消息來時(shí),沒有通知連接;
          (2)把新消息放入隊(duì)列;

          最后這個(gè)場(chǎng)景,發(fā)生的概率非常小,但也確保了在“HTTP的返回與再次發(fā)起會(huì)有一個(gè)時(shí)間差”內(nèi),消息不會(huì)丟失,在通知連接發(fā)起后,消息能夠?qū)崟r(shí)返回。

          總結(jié)
          網(wǎng)頁端收消息,究竟是推還是拉?
          (1)最容易想到的是,但實(shí)時(shí)性和效率是一對(duì)無法調(diào)和的矛盾;
          (2)最佳的方式是,但WebSocket和FlashSocket各有局限性;
          (3)最通用的方式是長輪詢,通過HTTP短連接拼裝長連接,具體是通過“夯住”“只收推送通知”的“通知連接”來實(shí)現(xiàn)的,能夠做到消息的實(shí)時(shí)性到達(dá);

          架構(gòu)師之路-分享技術(shù)思路


          若有收獲,隨手轉(zhuǎn)發(fā)。
          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆精品在线影院 | 中文字幕不卡+婷婷五月 | 成人伊人观看视频 | 丁香五月色情二区 | 操逼视频一区二区三区 |