無服務(wù)器 WebSocket:開啟實(shí)時(shí)數(shù)據(jù)傳遞新時(shí)代(無服務(wù)器技術(shù))
作者 | Matthew O’Riordan
譯者 | 明知山
策劃 | 丁曉昀
實(shí)時(shí)數(shù)據(jù)傳遞的興起
我們的日常數(shù)字體驗(yàn)正在經(jīng)歷一場(chǎng)變革:實(shí)時(shí)數(shù)據(jù)。
現(xiàn)在,用戶希望應(yīng)用程序或?yàn)g覽器中的頁面無需刷新就能更新狀態(tài)——例如,顯示實(shí)時(shí)體育比分的應(yīng)用程序或在地圖上跟蹤快遞進(jìn)度的網(wǎng)頁。
我們都已經(jīng)習(xí)慣了即時(shí)的數(shù)字體驗(yàn),我們理所當(dāng)然地認(rèn)為應(yīng)用程序和網(wǎng)頁可以提供流暢的交互式服務(wù),沒有延遲。提供無縫實(shí)時(shí)更新體驗(yàn)來吸引用戶的組織可以獲得更高的用戶參與度和更多的頁面停留時(shí)間,還有潛在的再次訪問和業(yè)務(wù)上的好處。如果沒有無縫的實(shí)時(shí)更新,用戶體驗(yàn)就會(huì)顯得過時(shí),并有失去市場(chǎng)份額的風(fēng)險(xiǎn)。
本文通過示例對(duì)一些最常見的實(shí)時(shí)用戶體驗(yàn)進(jìn)行了比較,討論了支持實(shí)時(shí)更新的事件驅(qū)動(dòng)架構(gòu),并介紹了常見的技術(shù)選項(xiàng)。
據(jù)估計(jì),到 2025 年,全球30%的消費(fèi)數(shù)據(jù)將來自實(shí)時(shí)信息交換,因?yàn)轭A(yù)計(jì)將有 1500 億臺(tái)設(shè)備連接并創(chuàng)建實(shí)時(shí)數(shù)據(jù)。隨著企業(yè)尋求相對(duì)于競(jìng)爭(zhēng)對(duì)手的運(yùn)營(yíng)優(yōu)勢(shì),它們開始關(guān)注實(shí)時(shí)體驗(yàn)。在最近的一項(xiàng)調(diào)查中,一些 IT 行業(yè)的領(lǐng)先者告訴 IDC,在有助于實(shí)現(xiàn)實(shí)時(shí)決策的技術(shù)上投入是當(dāng)務(wù)之急。
實(shí)時(shí)的定義
人類平均眨眼時(shí)間為 100 毫秒,平均反應(yīng)時(shí)間約為 250 毫秒。因此,在 250 毫秒以內(nèi)發(fā)生的任何事情都被認(rèn)為是“實(shí)時(shí)”的。
操作系統(tǒng)對(duì)硬件有不同的要求,“硬實(shí)時(shí)”的內(nèi)核承諾延遲小于 5 毫秒。另一個(gè)要求低延遲的領(lǐng)域是多人游戲,它要求延遲低于 50 毫秒。在本文中,我們要討論的實(shí)時(shí)是一種符合人類對(duì)“瞬時(shí)”理解的實(shí)時(shí)。
常見的實(shí)時(shí)用戶體驗(yàn)
實(shí)時(shí)體驗(yàn)
許多人都熟悉這種實(shí)時(shí)體驗(yàn)——根據(jù)內(nèi)容或數(shù)據(jù)的變化,實(shí)時(shí)數(shù)據(jù)從源向用戶單向傳遞。
這類例子包括:
- 在線購物網(wǎng)站,顯示商品庫存數(shù)量或商品存放在其他用戶購物籃中的數(shù)量;
- 作為對(duì)銀行帳戶活動(dòng)的反映,即時(shí)更新銀行應(yīng)用程序;
- 將體育和新聞更新發(fā)送到應(yīng)用程序或網(wǎng)頁上。
實(shí)時(shí)體驗(yàn)的例子:Reddit
Reddit 是全球訪問量最大的 20 個(gè)網(wǎng)站之一,它最近推出的實(shí)時(shí)更新功能表明,在與 Facebook 等其他在線社區(qū)的競(jìng)爭(zhēng)中,實(shí)時(shí)體驗(yàn)具有重要的戰(zhàn)略意義。Reddit App 用戶現(xiàn)在可以看到其他 Reddit 用戶的活動(dòng),比如當(dāng)其他 Reddit 用戶在閱讀同一篇文章或輸入回復(fù)時(shí)會(huì)顯示動(dòng)畫和提示。除此之外,還有其他的一些實(shí)時(shí)功能。
共享的實(shí)時(shí)體驗(yàn)
當(dāng)實(shí)時(shí)數(shù)據(jù)雙向流動(dòng)時(shí),就形成了共享的實(shí)時(shí)體驗(yàn)。打字聊天消息的傳遞就是一個(gè)典型的例子。其他的例子還包括民意調(diào)查、測(cè)驗(yàn)和問答,例如在 Twitch 流媒體直播中,參與者可以與主持人互動(dòng)。
共享的實(shí)時(shí)體驗(yàn)示例:Mentimeter
Mentimeter可以作為直播的一個(gè)補(bǔ)充環(huán)節(jié),可用于進(jìn)行民意調(diào)查或測(cè)驗(yàn)。例如,主持人可以問觀眾:“你們最喜歡的曼達(dá)洛人角色是哪一個(gè)?”參與者可以打開一個(gè)短 URL,并進(jìn)行在線投票,他們的回答會(huì)被實(shí)時(shí)可視化,并在直播中顯示。
協(xié)作體驗(yàn)
協(xié)作體驗(yàn)類似于共享的實(shí)時(shí)體驗(yàn),但通常使用點(diǎn)對(duì)點(diǎn)通信,用戶可以實(shí)時(shí)編輯共享的狀態(tài)和數(shù)據(jù)。一個(gè)典型的例子是我們?cè)谶h(yuǎn)程工作中使用的協(xié)作生產(chǎn)力工具,如 Figma、Google Docs 或 Miro。
協(xié)作體驗(yàn)示例:Figma
Figma是一個(gè)協(xié)作設(shè)計(jì)工具,允許多個(gè)用戶同時(shí)處理一個(gè)文件。它被稱為“設(shè)計(jì)協(xié)作的分水嶺”和設(shè)計(jì)軟件的變革者。
用戶可以直接共享 Figma 文件的鏈接,不需要下載或發(fā)送文件,也不需要離線編輯和合并修改。對(duì)于文檔、電子表格和演示文稿的協(xié)作來說,這些已經(jīng)相對(duì)標(biāo)準(zhǔn)化了,但對(duì)于復(fù)雜的設(shè)計(jì)軟件來說,這是一種新的工作方式。
對(duì)于許多組織(無論是現(xiàn)有的頭部公司還是挑戰(zhàn)者)來說,被Adobe以破紀(jì)錄的200億美元收購的 Figma 是一個(gè)有趣的案例。共享的實(shí)時(shí)和協(xié)作體驗(yàn)是未來趨勢(shì),沒有實(shí)時(shí)功能的產(chǎn)品需要找到一種方法來引入這些功能。
通常,當(dāng)我們講到實(shí)時(shí)體驗(yàn)時(shí),我們想到的是速度和延遲,但實(shí)時(shí)交互的根本在于架構(gòu)。
基于事件驅(qū)動(dòng)的實(shí)時(shí)架構(gòu)
對(duì)于一個(gè)成功的實(shí)時(shí)解決方案,你需要考慮采用事件驅(qū)動(dòng)模型。在事件驅(qū)動(dòng)模型中,事件表示可能觸發(fā)客戶端(或事件消費(fèi)者)執(zhí)行某些操作的變更,例如更新 UI。事件將作為消息通過事件通道傳遞給消費(fèi)者。事件生成器負(fù)責(zé)傳遞反映數(shù)據(jù)或狀態(tài)實(shí)時(shí)變化的事件。
事件驅(qū)動(dòng)系統(tǒng)的典型模式是“發(fā)布和訂閱”。當(dāng)狀態(tài)發(fā)生變化時(shí),事件生產(chǎn)者(發(fā)布者)發(fā)送事件消息,事件訂閱者可以消費(fèi)這些消息,并做出響應(yīng)時(shí)執(zhí)行業(yè)務(wù)邏輯。
用于實(shí)時(shí)解決方案的協(xié)議
在事件驅(qū)動(dòng)架構(gòu)中,事件消費(fèi)者需要能夠異步地接收更新??晒┻x擇的協(xié)議包括:
- HTTP長(zhǎng)輪詢——服務(wù)器保持客戶端連接處于打開狀態(tài),在新數(shù)據(jù)可用或連接超時(shí)時(shí)發(fā)送響應(yīng)。
- WebSocket——通過持久 TCP 連接提供雙向、全雙工通信通道,開銷要比半雙工替代方案(如 HTTP 長(zhǎng)輪詢)低得多。
- MQTT——用于在 CPU 功率或電池壽命有限的設(shè)備(如物聯(lián)網(wǎng)設(shè)備)之間傳輸數(shù)據(jù)的首選協(xié)議。
- SSE——用于事件驅(qū)動(dòng)數(shù)據(jù)流的輕量級(jí)開放協(xié)議(僅訂閱)。
WebSocket 可以說是使用最為廣泛的支持實(shí)時(shí)用戶體驗(yàn)的協(xié)議。WebSocket 于 2011 年實(shí)現(xiàn)標(biāo)準(zhǔn)化(RFC 6455),它是建立在TCP/IP協(xié)議棧之上的一個(gè)薄傳輸層。
WebSocket 的出現(xiàn)標(biāo)志著 Web 開發(fā)的一個(gè)轉(zhuǎn)折點(diǎn)。WebSocket 連接是為事件驅(qū)動(dòng)架構(gòu)而設(shè)計(jì)的,并針對(duì)最小化開銷和延遲進(jìn)行了優(yōu)化,它通過持久的單套接字連接實(shí)現(xiàn)了客戶端和服務(wù)器之間的雙向全雙工通信,并盡可能接近原始的 TCP 通信層。
與HTTP相比,WebSocket 連接提高了效率,可伸縮性更好。WebSocket 協(xié)議是基于推送的,因此一旦有事件發(fā)生,連接的客戶端就會(huì)收到更新。
用于事件驅(qū)動(dòng)系統(tǒng)的 WebSocket
我們有幾種方法可以將 WebSocket 集成到我們的技術(shù)棧中。
第一種方法是從頭開始構(gòu)建一個(gè)基于 WebSocket 的消息傳遞解決方案,并根據(jù)需要對(duì)其進(jìn)行定制。例如,DAZN 使用 WebSocket 協(xié)議設(shè)計(jì)了一個(gè)自定義解決方案,用于向數(shù)百萬用戶廣播消息。
另一種方法是使用 WebSocket 開源項(xiàng)目作為消息傳遞層的主干。Socket.IO是一個(gè)基于原始 WebSocket 構(gòu)建的框架,提供了額外的功能,比如支持回退、自動(dòng)重連和發(fā)布/訂閱消息(房間)。一種常見的方法是結(jié)合使用 Socket.IO 和Redis Pub/Sub,在不同的進(jìn)程或服務(wù)器上運(yùn)行多個(gè) Socket.IO 實(shí)例,并在節(jié)點(diǎn)之間傳遞事件。
然而,這種方法仍然存在一些限制,例如缺乏消息排序、有限的原生安全性和單區(qū)域可用性設(shè)計(jì)。因此,要在生產(chǎn)環(huán)境中大規(guī)模使用Socket.IO仍然存在很大的挑戰(zhàn)。
為實(shí)時(shí)數(shù)據(jù)構(gòu)建 WebSocket 解決方案所面臨的挑戰(zhàn)
上面描述的兩種 WebSockets 集成方式都存在工程方面的挑戰(zhàn),可能會(huì)影響項(xiàng)目成本和交付期限。從表面上看,構(gòu)建 WebSocket 解決方案就是從添加接收實(shí)時(shí)更新的功能開始。然而,隨著功能的演進(jìn),基本的實(shí)時(shí)體驗(yàn)會(huì)延伸出共享實(shí)時(shí)體驗(yàn)和協(xié)作功能等額外需求。
為這些實(shí)時(shí)體驗(yàn)構(gòu)建和維護(hù)一個(gè)專有的 WebSocket 解決方案可能極具挑戰(zhàn)性。支撐解決方案的基礎(chǔ)設(shè)施必須穩(wěn)定可靠,需要有經(jīng)驗(yàn)的工程師來構(gòu)建和維護(hù)。開發(fā)團(tuán)隊(duì)可能會(huì)更關(guān)注實(shí)時(shí)需求方面的東西,而不是增強(qiáng)核心產(chǎn)品的特性,并面臨可伸縮性和彈性、延遲、容錯(cuò)以及數(shù)據(jù)完整性和連接管理等工程挑戰(zhàn)。
可伸縮性和彈性
為了能夠可靠地處理數(shù)百萬個(gè)并發(fā) WebSocket 連接,解決方案需要具備可伸縮性,這是一項(xiàng)復(fù)雜且耗時(shí)的工作,需要專門的工程資源、大量的基礎(chǔ)設(shè)施成本和時(shí)間。
水平伸縮帶來了更復(fù)雜的架構(gòu)、負(fù)載均衡、路由以及基礎(chǔ)設(shè)施和維護(hù)成本的增加,這些還只是其中的一部分挑戰(zhàn)。
為了能夠成功地處理規(guī)模不可預(yù)測(cè)的 WebSocket 連接,解決方案還需要具備彈性,讓系統(tǒng)能夠自動(dòng)添加更多的服務(wù)器,有足夠的容量來處理潛在的流量高峰。
延遲
網(wǎng)絡(luò)延遲是大規(guī)模分布式系統(tǒng)中的一個(gè)關(guān)鍵因素。延遲隨著距離的增加而增加,因此為了保持較低的網(wǎng)絡(luò)延遲,建議借助托管數(shù)據(jù)中心和邊緣加速點(diǎn)讓數(shù)據(jù)盡可能地靠近用戶。良好的用戶體驗(yàn)還需要盡量減少延遲抖動(dòng)。
容錯(cuò)
要讓系統(tǒng)具備容錯(cuò)能力,必須要有服務(wù)實(shí)例甚至數(shù)據(jù)中心冗余。這意味著至少要將基礎(chǔ)設(shè)施分布到同一地區(qū)的多個(gè)可用性區(qū)域,甚至分布到多個(gè)地區(qū)。這涉及大量的工程和 DevOps 工作以及與基礎(chǔ)設(shè)施相關(guān)的成本。
數(shù)據(jù)完整性和連接管理
事件驅(qū)動(dòng)架構(gòu)依賴了事件消息序列,要求沒有消息丟失或沒有的無序消息。
如果用戶設(shè)備斷電或網(wǎng)絡(luò)出了問題,則可能導(dǎo)致連接中斷。當(dāng)用戶重新連接時(shí),需要從斷開連接的點(diǎn)繼續(xù)處理事件。系統(tǒng)需要在不重復(fù)已處理消息的情況下傳遞遺漏的消息。整個(gè)過程必須是完全無縫的。
所以還需要解決一些復(fù)雜的工程問題,以保證消息排序和精確一次語義所需的數(shù)據(jù)完整性。
DIY 的困境
一些組織試圖盡早發(fā)布產(chǎn)品,將這些困難的問題留到以后解決。但是,如果產(chǎn)品無法滿足它創(chuàng)造出來的需求,那么迅速進(jìn)入市場(chǎng)并獲得早期成功可能會(huì)弄巧成拙。
另一種選擇是盡早進(jìn)行伸縮性設(shè)計(jì),并為未來的增長(zhǎng)建立可持續(xù)的架構(gòu)。但這種方法可能會(huì)導(dǎo)致延遲進(jìn)入市場(chǎng),成為競(jìng)爭(zhēng)對(duì)手的可乘之機(jī)。另一個(gè)常見的問題是,最初的設(shè)計(jì)會(huì)在產(chǎn)品獲得足夠的市場(chǎng)反饋以了解其發(fā)展方向之前就已經(jīng)在產(chǎn)品中加入了重大的限制。
無服務(wù)器 WebSocket 的優(yōu)勢(shì)
一個(gè)可行的解決方案是將構(gòu)建業(yè)務(wù)關(guān)鍵型實(shí)時(shí)平臺(tái)的復(fù)雜性轉(zhuǎn)移到專門的云服務(wù)上。全托管的無服務(wù)器 WebSocket 解決方案為基于事件驅(qū)動(dòng)的消息傳遞提供了基礎(chǔ)設(shè)施,它將底層基礎(chǔ)設(shè)施變成了商品。用戶使用提供者服務(wù)發(fā)送/接收低延遲消息,并專注于構(gòu)建業(yè)務(wù)邏輯來處理實(shí)時(shí)更新。
將 WebSocket 技術(shù)與無服務(wù)器模型結(jié)合起來有幾個(gè)好處:
- 無需維護(hù)基礎(chǔ)設(shè)施——構(gòu)建專有的 WebSocket 基礎(chǔ)設(shè)施既耗時(shí)又耗費(fèi)資源。無服務(wù)器 WebSocket 提供商減輕了管理實(shí)時(shí)基礎(chǔ)設(shè)施的負(fù)擔(dān)。
- 降低運(yùn)營(yíng)成本——大多數(shù)無服務(wù)器 WebSocket 提供商都提供按使用付費(fèi)的定價(jià)模型。這比預(yù)先租用或購買固定數(shù)量的服務(wù)器容量更具成本效益,后者通常會(huì)存在大量未充分使用或空閑的時(shí)間。
- 可伸縮性和可用性——無服務(wù)器 WebSocket 架構(gòu)在設(shè)計(jì)上是可伸縮的。使用無服務(wù)器基礎(chǔ)設(shè)施構(gòu)建的應(yīng)用程序可能會(huì)遇到很大其波動(dòng)的流量,需要基礎(chǔ)設(shè)施能夠自動(dòng)伸縮以處理不可預(yù)測(cè)且快速變化的并發(fā) WebSocket 連接。
- 降低延遲——在無服務(wù)器模型中,應(yīng)用程序并不是托管在原始的服務(wù)器上。這意味著,根據(jù)無服務(wù)器 WebSocket 基礎(chǔ)設(shè)施提供商的設(shè)置,無服務(wù)器應(yīng)用程序可能會(huì)在全球多個(gè)地區(qū)和邊緣位置的用戶附近運(yùn)行,從而提高了性能并降低了延遲。
無服務(wù)器 WebSocket 解決方案
一些云供應(yīng)商提供了無服務(wù)器 WebSocket 解決方案,如AWS AppSync和AWS API Gateway、Cloudflare Workers、Google Cloud Run和Azure Web PubSub。然而,這些解決方案并沒有提供一個(gè)完整的端到端解決方案來處理最常見的場(chǎng)景,具體例子見DAZN對(duì)AWS AppSync和AWS API Gateway的評(píng)測(cè)。
一些平臺(tái),如Ably和Pusher,致力于幫助組織應(yīng)對(duì)在采用無服務(wù)器 WebSocket 事件驅(qū)動(dòng)架構(gòu)時(shí)面臨的挑戰(zhàn),并添加了額外的功能來解決常見的痛點(diǎn)。
例如,它們很少只使用一個(gè)通用的協(xié)議,因?yàn)椴煌膮f(xié)議可以更好地實(shí)現(xiàn)某些目的。Ably 提供了多種協(xié)議,如 WebSocket、MQTT、SSE 和 HTTP,并且還擴(kuò)展了原始協(xié)議之外的功能,如設(shè)備狀態(tài)、流歷史、通道回流和處理連接突然斷開。
采用供應(yīng)商提供的端到端無服務(wù)器 WebSocket 平臺(tái)有很多好處,因?yàn)樗鼈兛梢詰?yīng)對(duì)處理大規(guī)模實(shí)時(shí)數(shù)據(jù)時(shí)所面臨的挑戰(zhàn),讓工程團(tuán)隊(duì)可以專注于核心產(chǎn)品創(chuàng)新,不需要操心與實(shí)時(shí)基礎(chǔ)設(shè)施相關(guān)的問題。
總結(jié)
實(shí)時(shí)體驗(yàn)由實(shí)時(shí)、事件驅(qū)動(dòng)的 API 提供支撐,可以滿足現(xiàn)代終端用戶的需求。
穩(wěn)定的低延遲、數(shù)據(jù)完整性(順序和傳遞保證)、容錯(cuò)、可用性和可伸縮性是實(shí)時(shí)系統(tǒng)的基礎(chǔ),并不是每個(gè)組織都有能力處理好構(gòu)建可靠和不間斷體驗(yàn)的復(fù)雜性。
新一代提供無服務(wù)器 WebSocket 的 PaaS 可以促進(jìn)架構(gòu)、構(gòu)建、交付和維護(hù)解決方案的過程,讓用戶更加滿意,并使產(chǎn)品更具競(jìng)爭(zhēng)力,無需花費(fèi)高成本自行開發(fā)解決方案。
作者簡(jiǎn)介:
Matthew O'Riordan 是 Ably(無服務(wù)器 WebSocket 提供商)的首席執(zhí)行官和聯(lián)合創(chuàng)始人。他已經(jīng)做了 20 多年的軟件工程師,其中有很多時(shí)間在擔(dān)任 CTO。他從在 20 世紀(jì) 90 年代中期開始從事商業(yè)互聯(lián)網(wǎng)方面的工作,當(dāng)時(shí) IE 3 和網(wǎng)景還在你爭(zhēng)我搶。他喜歡寫代碼,同時(shí),作為初創(chuàng)企業(yè)家,擴(kuò)大業(yè)務(wù)所面臨的挑戰(zhàn)是他前進(jìn)的動(dòng)力。Matthew 之前曾創(chuàng)辦過兩家科技公司,并成功退出。
原文鏈接:
https://www.infoq.com/articles/serverless-websockets-realtime-messaging/
相關(guān)閱讀:
WebSocket 原理淺析與實(shí)現(xiàn)簡(jiǎn)單聊天
構(gòu)建通用WebSocket推送網(wǎng)關(guān)的設(shè)計(jì)與實(shí)踐
Serverless實(shí)戰(zhàn):利用云函數(shù) API網(wǎng)關(guān)實(shí)現(xiàn)Websocket聊天工具
本文轉(zhuǎn)載來源:
https://www.infoq.cn/article/9C7u99NSGaKvx9jeA4lw