受訪嘉賓 | 周子傑
作者 | Yonie
小程序雲開發 - 實時數據推送是小程序雲開發即將發布的一個雲服務, 可以監聽雲資料庫的數據變更,實時推送到小程序端。省去了開發者搭建 WebSocket 的成本,是小程序中實時推送的高效實踐方案。本次採訪的嘉賓是騰訊高級工程師——周子傑,他將為我們詳細講解實時數據推送服務的開發背景、技術解決方案及未來相關的產品計劃。感謝「雲加社區」對此次採訪的支持。
InfoQ:請您簡單的介紹一下自己以及目前所負責的工作。
周子傑:我剛畢業時來到了騰訊文檔團隊,負責騰訊文檔實時編輯系統開發,並設計衝突處理算法。今年轉到騰訊云云開發團隊,負責搭建低時延、高並發、高可用的資料庫實時推送服務。畢業後的這三年一直在做實時推送系統方面的工作,有時候也會做一些 Node.js 接入層的工作,目前是騰訊的高級研發工程師。
InfoQ:您之前負責騰訊文檔實時編輯系統開發,現在負責雲開發 - 實時數據推送系統,這兩者都對數據的實時性有一定的要求,您認為兩者有什麼相同點和不同點?
周子傑:它們從設計上講是相似的,但是在側重點上又有所不同:
對於騰訊文檔來說,它的側重點在於數據的可靠性,因為文檔編輯的時候,內容稍微出現一點錯誤,後續所有的編輯就沒有意義了。但是對時延和並發的要求不高。
小程序雲開發中的數據實時推送是一個雲服務 ,需要提供給更多的產品使用,而每個產品都有著自己的應用場景,對數據可靠性、延時、並發量也有著不同的需求,所以我們的實時推送服務在需要在數據穩定性、低延時和高並發量上做到極致,並且微信前端 sdk 加上數據的確認和重傳機制,為數據穩定性保駕護航。
InfoQ:請您介紹下前端如何確定數據的丟失呢?
周子傑:我們目前是這樣設計的:後臺去做監聽,當監聽到新的事件時就會往前端推送。在推送數據消息事件時會帶上有序序號,比如現在給前端推一號事件、二號事件,但是突然發現接下來的是五號事件,這就可以判斷出中間已經丟失了一些數據。之後客戶端會重新請求後臺發送丟失的數據。
InfoQ:之前做騰訊文檔的開發經驗,有哪些是可以用在實時數據推送系統裡的呢?
周子傑:騰訊文檔和雲開發 - 數據實時推送系統在技術上是共通的,很多都是通用的技術,尤其在數據可靠性上參考了很多文檔的成熟技術方案。而它們主要的區別在於:兩者所需要支持的並發用戶數是不同的。文檔支持的並發用戶數沒有那麼多,假設我們這個產品日活是一百萬的話,那它最高的同時連接後臺的用戶數可能就在十萬左右。而數據實時推送系統是一個雲服務,其主要目的是給客戶開發的產品提供數據推送服務,而雲開發同時向非常多的應用提供服務,需要很高的並發支持。所以在高並發上我們作了更多的優化。
InfoQ:小程序雲開發項目中的實時推送系統主要基於什麼需求背景?
周子傑:需求背景主要有兩方面:
一方面是小程序雲開發本身有提供雲資料庫的功能,在此基礎上我們考慮對它做更好的封裝,從而給用戶提供更好的體驗,滿足更多的場景。
另一方面是很多用戶給我們提出了這樣的需求(比如直播的彈幕功能,他們希望有實時消息推送的功能)。他們希望雲開發能提供 WebSocket 的功能,就是希望有能通過後臺直接往前臺推送消息的功能。因為如果沒有這個功能,用戶就要自己去搭 WebSocket 服務,他們自己搭建的服務可能無法保證良好的可靠性和並發性。如果要提供良好的性能,需要的開發成本會很高。於是,為了滿足用戶的需求,我們就立項做資料庫的實時推送系統,我們的願景是:希望實時推送能成為一項服務,不局限於推送資料庫的實時消息,只要你需要,它可以推送任何的消息。目前只是基於資料庫的消息推送,就是資料庫的數據被修改後就將最新數據推送到前端。未來實時推送做成一項服務後,只要有數據消息(可以是自己自定義的一個消息),就可以往前端推送。
InfoQ:現在 Serverless 的概念比較火,小程序雲開發又是一款 Serverless 服務,他為開發者提供了雲函數、雲資料庫和雲文件存儲等功能,請你解釋下採用的雲資料庫與普通的關係型資料庫在數據存儲上有什麼區別?為什麼選取雲資料庫?
周子傑:Serverless 是一個模糊了前端跟後臺關係的概念。雲開發是對 Serverless 的一個落地實踐,但比一般的 Serverless 服務相比,又增加了資料庫、文件存儲等基礎能力,構成一個完整的、可支持小程序、Web、安卓等開發的應用服務中臺。對於一個前端開發人員來說,可以通過雲開發去做一些後臺功能,很大程度上減少了前後端的溝通成本。
雲開發的資料庫與普通的資料庫區別是這樣的:傳統的後臺服務需要先部署 MySQL 或 MongoDB 等資料庫,然後通過後臺服務去操作資料庫,再往前端提供接口,前端同學如果想操作資料庫的話必須通過接口,這中間的溝通成本非常大。
雲開發的資料庫其實是一項服務。從開發的整個鏈路來看,與傳統的開發沒什麼區別的, 它也需要建立自己的後臺服務,只是雲資料庫相當於一個橋梁,處在連接後臺服務和前端的位置,主要是面向前端開發人員使用的一項資料庫服務。雲開發的資料庫不需要後臺提供接口 API 了,前端同學只需要寫幾行調用代碼,就可以實現資料庫的增刪查改,他們也不用再關心後臺用了什麼資料庫、如何搭建等問題,溝通成本和使用成本都降低了很多。用戶可以更聚焦於自己的業務,不用操心其他配置的事情了。
InfoQ:在開發實時推送系統時有沒有遇到一些技術痛點?如何解決的?
周子傑:現在面對最大的技術痛點是如何支持更多的實時連接數。資料庫實時推送是一個新的模塊,實現高可用不是一個簡單的事情,在第一次壓測時,我們 8 核的機器最高支持的連接數大概只有幾千,經過幾次優化現在已經有非常高的並發和可用性。後續還會持續進行優化迭代,以更好的應對高並發需求。
InfoQ:在搭建資料庫的實時推送系統的過程中,需要考慮哪些因素?怎樣保證低延時、高並發、高可用性的性能呢?具體採用了哪些做法?
周子傑:實時推送項目是騰訊雲與微信小程序合作的功能。從整體架構上分成了三個模塊:小程序的前端 SDK、中間接入層和後臺。他們分別承擔的業務為:
小程序的前端 SDK:這個業務需要在前端做些邏輯去保證服務的可靠性。然後在提供一個簡單的接口給前端同學用。這部分由微信小程序的同學負責的。接入層和後臺的工作由我們團隊來負責的。
中間接入層:其任務是與前端保持 WebSocket 長連接,接入層會去後臺輪詢,取到最新的消息事件後就發送給前端。
後臺:就是一個比較傳統的服務,在這一層監聽到最新消息就返回。
為了保證數據的可靠性和完整性,在做模塊設計時,我們採用互不信任的原則,即上述三個模塊之間是互不信任的。為此,我們做了很多的冗餘設計。如果系統中的某一模塊沒有調用成功,我們會採取一些措施來彌補這個缺失。比如說小程序的 SDK,它會定期的去接入層查詢最新消息事件的版本號,如果查到與本地的版本號對不上,它就會重新拉取一下這個消息事件。這樣即使出現數據丟失或者網絡連接斷掉的異常情況時,依然能保證數據的可靠性。
為了保證低延時,除了在接入層提供 WebSocket 接口以外,後臺所有的業務都使用了基於 TARS 框架的 RPC 通信,TARS 是一個成熟的開源框架,其性能很好。
為了處理高並發,我們持續優化接入層,讓其儘可能的維持更多的實時連接。
InfoQ:實時推送系統在未來有什麼計劃?
周子傑:目前推送系統的核心功能已經開發完成,在多款騰訊內部小程序 / 小遊戲進行內測,計劃將於 8 月下旬正式對外開放。此外,在產品層面,我們將對接入層做進一步優化。前端要跟後臺、接入層打交道,需要接入層提供 WebSocket 來保證長連接服務。只有長連接服務的存在,才可以給客戶端推送消息,所以為了保證同一臺機器能支持更多的長連接服務,我們要對接入層機器上部署的業務做裁減,目的是為了把接入層的服務做地更輕量,然後把更多的服務交給後臺來做。就等於說接入層是一個非常輕量的服務,只需要保持長連接的功能,接入層其他的一些功能移到到後臺去做了。