雲上影片業務基於邊緣容器的技術實踐
影片網關是影片雲系統下的一個邊緣容器設備,它起著將影片數據承上啟下的功能。
影片雲
說到邊緣影片網關就不得不提到雲計算中的影片雲,它是各領域的影片系統比如安防監控等向著智慧化、物聯網、上雲發展的產物。
在雲平台上通過雲伺服器和邊緣影片設備將採集的影片輸出編碼後經過網路實時傳輸給終端,終端進行實時解碼後顯示輸出。終端同時可以進行操作,經過網路將操作控制資訊實時傳送給雲端應用後台對邊緣影片設備進行控制。
一個物聯網場景下雲邊協同的智慧影片雲系統,具有實時流、歷史錄像功能,並支援對影片數據演算法分析與結果聯動控制,可以兼容市面上大多數廠商的影片設備比如攝影機和NVR。不僅可以在公有雲/私有雲部署,甚至提供支援有損服務的本地區域網影片最小系統。
影片網關
影片網關是雲計算在影片垂直領域中的邊緣容器設備,可以將其理解連接影片數據在影片感測器與雲上服務之間的橋樑,是影片雲系統中的關鍵一環,實現影片設備廣泛的兼容性以及雲邊協同都離不開它的身影。設計一個功能完備,可擴展,高可用的影片網關是非常值得投入的。
如何實現
影片網關需要實現的基本功能包括影片流採集與推送、影片設備接入與管理等,作為一個與底層硬體打交道的設備,又涉及到雲計算中的接入、安全以及雲邊協同等方面,可謂麻雀雖小五臟俱全。
影片數據採集
影片雲系統中影片數據的採集由位於邊緣側的影片網關完成,影片網關連接影片採集設備比如IPC/NVR, 通過廠家SDK或者ONVIF協議對影片採集設備進行管理,網關拉取影片採集設備的數據流並推送雲端或者邊緣側的影片服務,由影片服務對影片數據進行轉碼、數據流協議轉換等操作以適配不同的播放客戶端。
影片設備管理
攝影機、NVR等影片設備位於用戶區域網內,通過邊緣影片網關接入到影片雲系統中。邊緣影片網關和影片設備需要在管理平台上通過導入的方式做登記以便明確影片網關與影片設備以及影片網關與業務的綁定關係。影片網關管理影片設備並將設備狀態實時同步到雲影片系統中,管理平台實現”設備影子”並提供對影片網關以及影片設備狀態資訊的增刪改查介面。
數據安全
影片上雲需要安全認證,影片雲系統中邊緣容器設備接入雲端服務、邊緣容器設備之間以及邊緣容器設備與雲端服務之間的數據流採用標準國密演算法保證其運行的安全性,其中邊緣容器設備接入雲影片流程中採用國密sm2非對稱秘鑰技術保證接入安全,邊緣容器設備與雲影片之間的數據通道採用國密sm4對稱秘鑰技術保證信令與影片數據的安全。
設備接入
影片雲系統中影片網關等邊緣容器設備通常位於用戶區域網內,影片網關在區域網內連接影片設備比如IPC或者NVR,並作為一個邊緣容器設備接入到雲影片。影片網關通過註冊、登錄方式接入雲影片保證安全性,整個設備接入流程中影片網關與雲影片之間通訊採用國密sm2非對稱加密技術進行消息加密與簽名校驗,接入雲影片後影片網關與雲影片之間的信令通道採用國密sm4對稱秘鑰方式進行數據加解密。
1)在影片雲開放平台為影片網關設備申請sn序列號後即可以得到影片網關的私鑰以及接入雲影片所需的公鑰;
2)影片網關接入雲影片的註冊階段,首先網關使用網關私鑰對自身資訊進行簽名,然後使用雲影片公鑰將簽名資訊以及設備sn等資訊進行加密並發送雲影片,這一過程可以保證網關的註冊請求只能被雲影片解析,並且雲影片可以通過簽名驗簽識別消息是由影片網關發出。
3)註冊雲影片成功後,雲影片會將其與影片網關之間的信令通道等相關資訊經過雲影片私鑰加密後返回給影片網關,影片網關通過雲影片公鑰可以解析。
4)影片網關接入雲影片的登錄階段會與雲影片協商信令通道對稱秘鑰,首先網關使用網關私鑰對自身資訊進行簽名,然後使用雲影片公鑰將簽名資訊以及設備唯一標識、對稱秘鑰向量等資訊進行加密後發送雲影片,這一過程可以保證網關的登錄請求只能被雲影片解析,並且雲影片可以通過簽名驗簽識別消息是由影片網關發出。
5)登錄雲影片成功後,雲影片會將其與影片網關之間信令通道中使用的對稱秘鑰key、token以及有效時間等資訊經過雲影片私鑰加密後返回給影片網關,影片網關通過雲影片公鑰可以解析。
數據通道
邊緣容器設備與雲影片之間的業務數據,比如影片網關與雲影片之間的影片流推送、攝影機列表維護等消息通過數據通道傳達,採用國密sm2對稱秘鑰技術加密,如果數據通道的token、對稱秘鑰過期需要影片網關重新登錄雲影片獲取。
以邊緣影片網關向雲影片推送影片流這一過程為例說明,影片網關採集到攝影機設備的影片流後對影片幀加密後傳輸到雲端影片後台服務,其中影片網關與雲端影片後台服務之間推影片流建立握手的token以及推流數據加密使用的國密sm4 key等安全資訊是通過影片網關與雲影片之間的數據通道下發的,影片鏈路保證該加密資訊的單次使用時效性,也就是說單次推流的信令中所包含的加密資訊如果在一個時間閾值內不使用或者握手成功後就不可再次復用了。
影片雲系統中邊緣容器設備接入與數據通道的安全認證機制如下圖所示。
雲邊協同
靈活的雲邊協同和邊緣計算能力,集中管理能力雲端收攏,部分邏輯下沉邊緣,保證快速響應,即便在雲環境網路異常下也能提供基礎的本地影片服務實現高可用。
在傳統的影片監控領域,攝影機、演算法和監控軟體會部署在同一個區域網內,對於用戶而言,往往有在公網短時播放的需求。如果將影片放到公網上進行播放,又會帶來頻寬成本以及安全問題。影片雲系統為解決以上問題,提供雲邊協同和邊緣計算能力,在雲端控制邊緣節點,可以將已訓練好的演算法或者事件聯動能力下沉到邊緣容器設備進行運行,大大降低雲端壓力。同時擁有靈活邊緣路由能力,根據云端拉流需求,將部分影片推到雲端進行播放,極大降低頻寬成本,提高系統的穩定性。
雲邊系統高可用
技術方案
跨平台編程
影片網關作為一種嵌入式媒體網關設備,主要有兩種設備形態,一種是以通用伺服器搭載網關服務的形式,這樣的系統比較重,成本比較高但是性能強勁,另一種是嵌入式盒子設備比如樹莓派,成本低同時性能較低,按照項目應用場景合理搭配解決方案。
影片網關作為一個可以跨平台,跨系統並深度融合雲計算影片雲領域的服務,軟體我們採用了golang語言,藉助於其天然的跨平台特性,可以支援網關服務運行在各種晶片平台以及作業系統之上。go tool dist list 可以看到go語言支援的平台和系統如下。
作業系統 | 主控晶片平台 |
---|---|
linux | 386/amd64/arm/arm64/mips/mips64/mips64le/mipsle/ppc64/ppc64le/riscv64/s390x |
android | 386/amd64/arm/arm64 |
darwin | 386/amd64/arm/arm64 |
freebsd | 386/amd64/arm/arm64 |
solaris | amd64 |
plan9 | 386/amd64/arm |
openbsd | 386/amd64/arm/arm64 |
netbsd | 386/amd64/arm/arm64 |
aix | ppc64 |
windows | 386/amd64/arm |
從上述列表可以看出,從linux/arm64的嵌入式系統到linux/s390x的大型機系統,再到Windows、linux和darwin(mac)這樣的主流作業系統、amd64、386這樣的主串流處理器體系,Go對各種平台和作業系統的支援不可謂不廣泛。
go語言被稱作互聯網時代的c語言其優點很多,語法簡單、原生支援並發、平台可移植性好、運行速度快、有功能豐富並且統一的標準庫等等,其中關於跨平台有一種說法go是為了解決c/c++那些複雜的依賴而來的,這一定程度上得益於Go獨立實現了runtime,作為技術棧上的選型這裡關於runtime多說一些。
runtime是支撐程式運行的基礎。libc(C運行時)是目前主流作業系統上應用最普遍的運行時,通常以動態鏈接庫的形式(比如:/lib/x86_64-linux-gnu/libc.so.6)隨著系統一併發布,它的功能大致有如下幾個:
-
提供基礎庫函數調用,比如:strncpy;
-
封裝syscall(作業系統提供的API口,當用戶層進行系統調用時,程式碼會trap(陷入)到內核層面執行),並提供同語言的庫函數調用,比如:malloc、fread等;
-
提供程式啟動入口函數,比如:linux下的__libc_start_main。
早期的系統的磁碟/記憶體資源十分緊張,採用動態鏈接庫的方式可以使得編譯的程式/進程磁碟/記憶體佔用小。不過時代變了,現在的伺服器配置已經足夠,由於libc等c runtime lib是基於執行緒模型的並且歷史版本複雜,對於開發人員來說這裡的負擔很重,一些從事c/c++開發多年的同學可能有過這樣的經歷,鏈接runtime庫時需要選擇鏈接支援多執行緒的庫還是只支援單執行緒的庫。
go獨立實現runtime層,封裝了syscall將Go user-level code與OS syscall解耦,把go 移植到一個新平台時,將runtime與新平台的syscall對接即可,基本擺脫對libc的依賴,這樣靜態編譯的go程式具有很好的平台適應性。而且交叉編譯很簡單,只涉及兩個重要的環境變數:GOOS和GOARCH,分別代表Target Host OS和Target Host ARCH,這裡需要注意CGO_ENABLED=0的情況下,即不涉及cgo的前提下go採用純靜態編譯。
業務功能
影片網關位於影片系統的邊緣側,主要業務功能是負責拉取影片流並推送到影片後台服務。在系統管理層面,影片網關需要連接設備側的IPC/NVR等,並接入到影片系統的控制內核,作為邊緣容器設備接收雲影片系統內核的信令對影片設備進行管理,執行相應的操作,並將影片設備的回饋結果以及狀態上報到雲影片系統內核。
網路接入
影片網關不僅可通過固網接入影片雲系統,也可通過蜂窩網,wifi等無線方式接入。影片網關通過驅動搭載WIFI/4G/5G等通訊模組實現無線接入能力,其中區域網內可以使用WIFI等協議,連接互聯網可以使用4G/5G通訊。影片網關可根據影片系統組網的實際情況以及現場影片設備的實際能力,將整個影片系統的有線/無線網路結合。
設備初始化
影片網關在接入層採用插件化的框架,向下可以兼容ONVIF協議、SDK等多種方式接入影片設備,向上可以兼容mqtt/http等物聯網傳輸協議接入雲計算影片平台。
初始化能力集
影片網關通過影片設備的設備影子中廠商、流來源等屬性判斷使用ONVIF協議還是廠商SDK對影片設備進行初始化,獲取影片設備的能力列表比如RTSP連接等。
初始化消息通道
影片網關和雲影片系統內核之間的消息通道支援http/mqtt等物聯網通訊協議,影片網關具體使用某種通訊協議由用戶選擇相應的配置在系統啟動階段完成初始化。
安全策略
影片網關在接入雲影片系統內核過程支援雙向鑒權,信令通道以及影片流傳輸支援數據加密等多種安全策略。
影片網關接入雲影片系統內核分為註冊、挑戰、登錄三步,網關與內核之間採用tcp私有協議方式通訊,接入過程中使用sm2/4國密進行數據加密和簽名。其中影片網關的設備私鑰、設備公鑰以及雲影片系統內核的公鑰由影片網關在申請雲影片系統內核放號的過程中獲取。
影片流加密
內核下發推流消息命令字通知影片網關推影片數據流,網關根據消息中的流來源欄位區分收流設備是IPC還是NVR,網關推送影片流的目的端資訊以及影片流加密秘鑰由內核下發消息指定。
信令加密
網關接入雲影片系統內核成功後即可通過消息通道實現網關與內核間的雲邊協同,為了增強消息安全性在影片網關與內核之間的消息通道設置了token過期時間,當token過期,網關在接收與上報消息將出現異常,此時需要網關主動重新登錄內核換取新token,網關在定時心跳過程中維護檢測token過期機制。
雲邊協同
事件處理
影片網關具有邊緣節點監控、數據統計與告警、事件處理能力。
影片網關接入雲影片系統內核後,由雲影片系統內核下發消息控制影片網關執行相關功能,定義影片網關與內核之間消息命令字。影片網關與內核之間的消息通道可以採用mqtt/http等協議。消息通道中使用管道實現隊列的能力,內核下發消息通過管道分發到不同的接收消息任務中並發處理,網關上報消息通過管道由發送任務上報內核。
狀態上報
網關與雲影片系統內核之間通訊的加密key通過網關的心跳上報定時檢測更新。
影片網關位於設備側區域網內,可以通過其與雲影片系統內核之間的消息通道上報統計與告警消息。實現對設備狀態全程監控、有效實時獲取狀態變更通知。
影片網關通過消息通道上報統計和告警消息到雲影片系統內核,結合雲計算影片雲的後台服務以及綁定接入的應用實現告警上報。
雙機熱備
為避免影片網關單點異常宕機對影片服務造成影響,影片網關採用主備方式提高服務可用性,結構簡單容易維護。
主備模式下設備側區域網內多個影片網關涉及調度和配置管理,這裡使用了項目中zookeeper組件提供分散式搶佔鎖和配置中心的能力,zookeeper使用znode目錄節點作為鎖和共享存儲。
網關接入
影片網關作為接入影片雲系統的邊緣容器設備具有唯一性,主備模式下區域網內同一時間只有一個影片網關作為主網關提供服務,其餘網關作為主網關的從網關監視主網關狀態,當主網關出現異常從網關嘗試切換成為主網關。其中多個影片網關對影片雲系統等效為一個接入設備。具體部署可以是一主一從或者一主多從。
使用zookeeper的臨時目錄編號節點(EPHEMERAL_SEQUENTIAL)實現分散式搶佔鎖可以為多個網關的運行提供調度,保證同一時刻只有一個網關接入到影片雲內核(IOT)。
網關切換
主網關由於宕機與zk斷開連接或者業務異常主動釋放與zk之間的鎖時,zk將對應的編號節點刪除,並通知其他監聽臨時節點的網關可以搶佔,新搶佔到鎖的網關成為主網關。
邊緣部署
隨著Docker為代表的容器技術和Kubernates為代表的容器編排工具逐漸成熟,越來越多的應用通過容器封裝、分發和運行,這種部署方式非常合適邊緣計算場景。
按照端設備—邊緣—雲」三層模型, 影片網關作為一種邊緣設備與攝影機、nvr等影片終端設備直接相連,然而邊緣節點的硬體資源往往比較緊張, 影片雲系統需要十分靈活的對邊緣節點的計算能力與資源調度策略進行調整。
使用容器技術對邊緣節點進行資源隔離,不僅CPU、記憶體和存儲的開銷非常小,而且容器可以實現在毫秒級開啟和關閉,生命周期管理非常快捷。
影片雲系統中邊緣影片網關往往分散在建築、園區等各個局部區域中,遠離雲中心。隨著用戶對影片播放需求的變化,邊緣影片網關的資源分配與部署也需要隨時調整,並且需要支援監控、日誌等等運維手段。採用了tke edge邊緣容器架構支撐影片雲系統的邊緣計算場景,tke edge支援邊緣計算、多雲管理和混合雲,具有完備的k8s功能與標準api,可以方便的從中心雲運維邊緣容器,具有邊緣自治能力,支援邊緣節點健康檢查,服務可以下沉到邊緣機房,而且和tke擁有一致的控制台頁面,運維管理可視化十分便捷。
性能調優
影片網關的業務場景決定了其主要功能模組是設備接入與消息通道、任務調度、採集與推送影片流,性能優化的關鍵點往往就在這裡。
go tool可以很方便的使用pprof對進程詳細的性能分析,使用 -memprofile 和 -cpuprofile 選項生成cpu和記憶體取樣文件,再用工具go tool pprof查看文件內容。
在開發過程中遇到的性能優化問題挑了兩個比較典型的案例進行分析。
Mqtt 訂閱
影片網關與雲影片系統內核(IOT)之間的mqtt消息通道使用了開源的paho.mqtt.golang,影片網關作為客戶端需要訂閱IOT分配的topic,開發調試過程中發現網關進程在啟動後既沒有接收來自於IOT的消息也沒有推流的情況下,cpu佔用都有2~3個點,於是通過火焰圖對調用介面進行性能分析,發現mqtt客戶端的Subscribe介面cpu時間佔用異常。
檢查程式碼原來是由於介面誤使用,訂閱介面本來在mqtt客戶端初始化的時候訂閱一次就可以了,但是寫程式碼時把它當成了非同步阻塞接收介面,在一個輪詢的循環中不停的調用,結果就是不停的在訂閱同一個topic。
token := client.Subscribe(m.subOption.topic, m.subOption.qos, msgSubscribeHandler)
token.Wait()
if token.Error() != nil {
log.Errorf("Subscribe msg to mqtt broker error:%s", token.Error().Error())
}
使用開源庫中介面不熟悉誤用造成的問題比較低級也很典型,如果沒有pprof這樣的工具,排查起來還是挺麻煩了,採用了正確的姿勢,再分析可以看到已經沒有訂閱介面的時間佔用了。
優化推流 buffer
既然影片網關的主要功能是推流那麼網路傳輸介面這塊一定是cpu和記憶體性能的消耗大戶,通過火焰圖發現封裝的推流介面cpu佔用時間幾乎都集中在底層的Write和recv,這一塊優化空間不大,但是發現runtime.gcBgMarkWorker(垃圾回收器)這塊消耗比較高,排查程式碼原來是推流任務中的buffer申請時機不合理導致。
func (v *videoPush) PushToWeLink(pushData *pb.PushReq) error {
//申請記憶體空間
packet := make([]byte, mvsTCPHeadLen)
//組裝數據
......
//發送數據
middleware.SendTCPMsg(v.Conn, v.packet)
return err
}
在每次收到影片幀並推流的時候都新申請一塊buffer,造成go的gc壓力過大,其實對於影片網關每次從影片採集設備收到的數據幀大小是可以預估的,在每次建立推流任務初始化的時候可以針對任務將固定空間的buffer預留好。
//videoPush
type videoPush struct {
//攝影機推流屬性等
//token與秘鑰等
//與影片伺服器連接等
//狀態等
……
PushCtx context.Context
PushCancel context.CancelFunc
frameHead []byte //加密幀頭
packet []byte //sharp包體
head *com_tencent_weling_proto.MvsHead //sharp包頭
}
func (v *videoPush) PushToWeLink(pushData *pb.PushReq) error {
//取記憶體空間
v.packet = v.packet[0:mvsTCPHeadLen]
//組裝數據
......
//發送數據
if err = middleware.SendTCPMsg(v.Conn, v.packet); err == nil {
//更新推流狀態, 在線、推流時間戳
v.camerasInfo.setPushingByIntDinSubDin(v.SDin, int(v.StreamID), v.StreamType, v.getVideo.StreamHandler)
} else {
log.Errorf("push send msg error:%s, packet len:%d", err.Error(), len(v.packet))
}
return err
}
經過簡單適配,可以看到gc的性能消耗已經有了明顯改善。
項目總結
基於go的技術棧實現了一個跨晶片平台的影片網關,用戶可以選擇邊緣伺服器或者邊緣嵌入式硬體等環境部署影片網關,融合雲計算敏捷靈活、可靠穩定的特點,將網路連接、管理運維及調度的能力應用於影片場景,提供實時、可靠的影片端到端服務。
通過插件化的網路接入層,影片網關可以選擇多種物聯網協議接入雲計算服務,並且兼容多種廠商的影片設備;
通過雲邊協同,實現雲端下發邊緣處理,提供有損服務能力,系統可用性強;
通過邊緣側狀態監控、統計與告警,掌握影片設備實時狀態上報,構建全鏈條的打點數據採集,設備級的精細化狀態追蹤,支援設備行為軌跡等數據分析;
通過從端到雲全方位的安全策略。影片網關設備接入雲端過程中雙向身份認證,保證設備唯一性不受篡改,全面杜絕偽造設備/雲伺服器發送請求。影片流數據加密傳輸防止敏感資訊泄露。
使用效果
以公司普通計算型伺服器的配置(8核16G記憶體千兆網卡)為例,設置動態碼率2m以內的攝影機實時流推流實測可以支援到400路。樹莓派3B+搭載影片網關在同樣場景下可以支援不低於100路攝影機實時流推流。
目前go重構的影片網關已經在多個項目環境中使用,整體表現良好,並計劃在後續的新項目以及老項目的影片網關升級改造中逐步替換成go重構版本。
設計感悟
現在的設備正逐漸朝著物聯網,智慧化方面發展,探索發現一條適合未來智慧設備發展要求的技術棧是雲相關產品開發工程師必須面對的;
不要重複造輪子,優秀的官方庫,活躍的開源社區可以讓開發工作穩定可控並且豐富多彩;
追求產品品質和開發效率是每位開發同學都需要要考慮的問題,有了它們才能保證產品在市場競爭中立於不敗之地,用合適的工具做合適的事。
【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多乾貨!!