大屏技術演進-推模式

1、問題

  • 在咱們上一篇文章《大屏技術演進-拉模式》最後思考部分,咱們提出條件單一使用拉模式其實也能夠,定時控制一下時間粒度問題,整個架構也簡單,那若是咱們條件增長了呢,用那個模式是否是又回到前端請求同時要根據條件計算的問題呢?
  • 咱們是否能夠理解爲在大屏上面其實在不少時刻可能沒有大量日誌數據打點,那咱們在人類社會通常溝通方式都是:你有事叫我,沒事別叫我(儘可能少這樣作,會沒有朋友的),在服務架構上,我們仍是儘可能作到:有日誌上報通知我,而前端不須要定時去拉取數據,數據拉取也是須要消耗網絡流量的。

2、解決方案

那麼基於上面兩個問題,咱們要思考方向就是推的模式,這裏使用時websocket,中心思想就是:有日誌上報大屏就有網絡請求,沒有上報就老實一點,別發請求了,省省吧前端

那麼對應websocket不太理解的同窗,能夠考慮看下 WebSocket原理及如何使用 ,裏面講解的比較詳細。web


上咱們的時序圖:redis


說明:後端

  1. 大屏在打開的時候,會發起一個websocket的connect請求,這個時候鏈接成功後,會進行一個token的返回。
  2. 將返回的token與前端請求的條件參數進行合併提交請求到服務端,服務端將token與條件進行一個綁定操做,條件進行惟一值計算,咱們使用是md5,在redis裏面進行一個集合的綁定操做。
  3. 後臺任務會定時去拉取這個關聯關係,而且將條件參數提取出來,將條件進行一個單獨的進程去進行對應的計算,多核cpu下面,能夠考慮使用線程或者多進程來實現,固然若是是go語言,直接用內置的協程也是能夠的,畢竟在語言級別實現csp模型仍是很是不錯的。
  4. 由於是多個模塊數據數據生成,而且多模塊下面有一些是實時數據,還有一些是要增量數據,實時數據在每次計算均可以覆蓋之前的,而增量的數據只能判斷當前是否有數據,沒有數據不能覆蓋數據源,只有有數據才能夠進行覆蓋。
  5. 計算髮現數據版本已經變動後,就通知服務端 條件(condition)與模塊列表(modules)須要更新,服務端收到請求後,就將關聯關係裏面 條件對應的token取出,而後一次性對於這些token發起服務端推送操做,內容就是模塊列表(modules)
  6. 前端使用onmessage接收到響應後,在使用token與module請求服務端獲取對應模塊的數據,服務端獲取modules列表後去對應redis裏面取出數據直接返回給前端。
  7. 大致的流程就是上面所講的。


3、過程當中的問題

Q:websocket爲何要用ping/pong來維持?websocket

A:由於在本方案裏面,ping/pong心跳用來肯定一個大屏是否打開的,由於咱們在後端計算大屏數據是跟咱們的條件來走的,若是咱們的大屏掉線了,可以及時通知後臺任務,那麼咱們的計算量會少不少網絡

Q:用ping/pong就能百分百保證個人websocket不會斷連嗎?架構

A:答案是否認的,互聯網上真沒有百分百的事情,網絡的一個抖動,咱們的ping/pong就有可能掛了,這是很正常的狀況,咱們在業務上會對於ping/pong進行一些重試機制,這個重試可能會短期內的,好比1s內發起多少次請求的;若是這個請求不能正確獲取數據,那麼服務端過時後,其實這個token就沒有太多用處了,前端就會有個定時器去探測websocket服務與本地通信是否有問題,沒有問題進行從新的connect操做,而在探測過程當中,咱們有個降級操做,會將咱們websocket操做變成傳統的拉模式,這個要結合咱們上一篇文件技術方案。app

Q:我條件確定會變動,變動證實作?socket

A:這是一個好問題,由於啥,切換大屏參數直接致使咱們不少模塊數據是須要從新渲染的,那麼咱們須要從新的發送push操做,而後後續邏輯是一致的。ide

Q:爲何要用token的介入呢,我已經登入系統了,直接uid就能夠不?

A:開始咱們也是考慮到uid的方案的,爲何不行呢,主要是咱們這裏的token是跟websocket相關的,能夠近似的認爲是socket裏面的fd,好比我一我的開了10個大屏,那麼我推送的那一刻,我須要將10個大屏數據都能推送到,而區別就在於,uid只有一個,token是10個


4、總結

這裏爲何花了兩個篇幅來寫大屏這塊呢,主要是在一些簡單場景下,咱們1.0版本會更適合,畢竟websocket相對於流程複雜一點,那麼中間節點處毛病地方就會多一點,可是複雜場景下面,又必需要這樣作設計,因此咱們就分開兩個文章來進行說明。

但願經過兩篇文章,同窗們可以從中學習到大屏製做技術方案的相關知識點,可以讓咱們應對產品經理 完(刁)美(鑽)需求時候,咱們有一個很是合適的技術方案輸出。

相關文章
相關標籤/搜索