雲上視頻業務基於邊緣容器的技術實踐


視頻網關是視頻雲系統下的一個邊緣容器設備,它起着將視頻數據承上啟下的功能。

視頻雲

說到邊緣視頻網關就不得不提到雲計算中的視頻雲,它是各領域的視頻系統比如安防監控等向着智能化、物聯網、上雲發展的產物。

在雲平台上通過雲服務器和邊緣視頻設備將采集的視頻輸出編碼后經過網絡實時傳輸給終端,終端進行實時解碼后顯示輸出。終端同時可以進行操作,經過網絡將操作控制信息實時傳送給雲端應用后台對邊緣視頻設備進行控制。

視頻雲一般框架

一個物聯網場景下雲邊協同的智能視頻雲系統,具有實時流、歷史錄像功能,並支持對視頻數據算法分析與結果聯動控制,可以兼容市面上大多數廠商的視頻設備比如攝像頭和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等安全信息是通過視頻網關與雲視頻之間的數據通道下發的,視頻鏈路保證該加密信息的單次使用時效性,也就是說單次推流的信令中所包含的加密信息如果在一個時間閾值內不使用或者握手成功后就不可再次復用了。

視頻雲系統中邊緣容器設備接入與數據通道的安全認證機制如下圖所示。

img

雲邊協同

靈活的雲邊協同和邊緣計算能力,集中管理能力雲端收攏,部分邏輯下沉邊緣,保證快速響應,即便在雲環境網絡異常下也能提供基礎的本地視頻服務實現高可用。

在傳統的視頻監控領域,攝像頭、算法和監控軟件會部署在同一個局域網內,對於用戶而言,往往有在公網短時播放的需求。如果將視頻放到公網上進行播放,又會帶來帶寬成本以及安全問題。視頻雲系統為解決以上問題,提供雲邊協同和邊緣計算能力,在雲端控制邊緣節點,可以將已訓練好的算法或者事件聯動能力下沉到邊緣容器設備進行運行,大大降低雲端壓力。同時擁有靈活邊緣路由能力,根據雲端拉流需求,將部分視頻推到雲端進行播放,極大降低帶寬成本,提高系統的穩定性。

雲邊系統高可用

雲邊系統高可用

技術方案

跨平台編程

視頻網關作為一種嵌入式媒體網關設備,主要有兩種設備形態,一種是以通用服務器搭載網關服務的形式,這樣的系統比較重,成本比較高但是性能強勁,另一種是嵌入式盒子設備比如樹莓派,成本低同時性能較低,按照項目應用場景合理搭配解決方案。

視頻網關作為一個可以跨平台,跨系統並深度融合雲計算視頻雲領域的服務,軟件我們采用了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)隨着系統一並發布,它的功能大致有如下幾個:

  1. 提供基礎庫函數調用,比如:strncpy;

  2. 封裝syscall(操作系統提供的API口,當用戶層進行系統調用時,代碼會trap(陷入)到內核層面執行),並提供同語言的庫函數調用,比如:malloc、fread等;

  3. 提供程序啟動入口函數,比如:linux下的__libc_start_main。

早期的系統的磁盤/內存資源十分緊張,采用動態鏈接庫的方式可以使得編譯的程序/進程磁盤/內存占用小。不過時代變了,現在的服務器配置已經足夠,由於libc等c runtime lib是基於線程模型的並且歷史版本復雜,對於開發人員來說這里的負擔很重,一些從事c/c++開發多年的同學可能有過這樣的經歷,鏈接runtime庫時需要選擇鏈接支持多線程的庫還是只支持單線程的庫。

img

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過期機制。

Token 過期策略

雲邊協同

事件處理

視頻網關具有邊緣節點監控、數據統計與告警、事件處理能力。

視頻網關接入雲視頻系統內核后,由雲視頻系統內核下發消息控制視頻網關執行相關功能,定義視頻網關與內核之間消息命令字。視頻網關與內核之間的消息通道可以采用mqtt/http等協議。消息通道中使用管道實現隊列的能力,內核下發消息通過管道分發到不同的接收消息任務中並發處理,網關上報消息通過管道由發送任務上報內核。

事件處理流程

狀態上報

網關與雲視頻系統內核之間通信的加密key通過網關的心跳上報定時檢測更新。

消息上報流程

視頻網關位於設備側局域網內,可以通過其與雲視頻系統內核之間的消息通道上報統計與告警消息。實現對設備狀態全程監控、有效實時獲取狀態變更通知。

視頻網關通過消息通道上報統計和告警消息到雲視頻系統內核,結合雲計算視頻雲的后台服務以及綁定接入的應用實現告警上報。

消息通道上報統計與告警

雙機熱備

為避免視頻網關單點異常宕機對視頻服務造成影響,視頻網關采用主備方式提高服務可用性,結構簡單容易維護。

主備模式下設備側局域網內多個視頻網關涉及調度和配置管理,這里使用了項目中zookeeper組件提供分布式搶占鎖和配置中心的能力,zookeeper使用znode目錄節點作為鎖和共享存儲。

img

網關接入

視頻網關作為接入視頻雲系統的邊緣容器設備具有唯一性,主備模式下局域網內同一時間只有一個視頻網關作為主網關提供服務,其余網關作為主網關的從網關監視主網關狀態,當主網關出現異常從網關嘗試切換成為主網關。其中多個視頻網關對視頻雲系統等效為一個接入設備。具體部署可以是一主一從或者一主多從。

使用zookeeper的臨時目錄編號節點(EPHEMERAL_SEQUENTIAL)實現分布式搶占鎖可以為多個網關的運行提供調度,保證同一時刻只有一個網關接入到視頻雲內核(IOT)。

img

網關切換

主網關由於宕機與zk斷開連接或者業務異常主動釋放與zk之間的鎖時,zk將對應的編號節點刪除,並通知其他監聽臨時節點的網關可以搶占,新搶占到鎖的網關成為主網關。

img

邊緣部署

隨着Docker為代表的容器技術和Kubernates為代表的容器編排工具逐漸成熟,越來越多的應用通過容器封裝、分發和運行,這種部署方式非常合適邊緣計算場景。

按照端設備—邊緣—雲”三層模型, 視頻網關作為一種邊緣設備與攝像頭、nvr等視頻終端設備直接相連,然而邊緣節點的硬件資源往往比較緊張, 視頻雲系統需要十分靈活的對邊緣節點的計算能力與資源調度策略進行調整。

使用容器技術對邊緣節點進行資源隔離,不僅CPU、內存和存儲的開銷非常小,而且容器可以實現在毫秒級開啟和關閉,生命周期管理非常快捷。

img

視頻雲系統中邊緣視頻網關往往分散在建築、園區等各個局部區域中,遠離雲中心。隨着用戶對視頻播放需求的變化,邊緣視頻網關的資源分配與部署也需要隨時調整,並且需要支持監控、日志等等運維手段。采用了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時間占用異常。

img

檢查代碼原來是由於接口誤使用,訂閱接口本來在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這樣的工具,排查起來還是挺麻煩了,采用了正確的姿勢,再分析可以看到已經沒有訂閱接口的時間占用了。

img

優化推流 buffer

既然視頻網關的主要功能是推流那么網絡傳輸接口這塊一定是cpu和內存性能的消耗大戶,通過火焰圖發現封裝的推流接口cpu占用時間幾乎都集中在底層的Write和recv,這一塊優化空間不大,但是發現runtime.gcBgMarkWorker(垃圾回收器)這塊消耗比較高,排查代碼原來是推流任務中的buffer申請時機不合理導致。

img

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的性能消耗已經有了明顯改善。

img

項目總結

基於go的技術棧實現了一個跨芯片平台的視頻網關,用戶可以選擇邊緣服務器或者邊緣嵌入式硬件等環境部署視頻網關,融合雲計算敏捷靈活、可靠穩定的特點,將網絡連接、管理運維及調度的能力應用於視頻場景,提供實時、可靠的視頻端到端服務。

通過插件化的網絡接入層,視頻網關可以選擇多種物聯網協議接入雲計算服務,並且兼容多種廠商的視頻設備;

通過雲邊協同,實現雲端下發邊緣處理,提供有損服務能力,系統可用性強;

通過邊緣側狀態監控、統計與告警,掌握視頻設備實時狀態上報,構建全鏈條的打點數據采集,設備級的精細化狀態追蹤,支持設備行為軌跡等數據分析;

通過從端到雲全方位的安全策略。視頻網關設備接入雲端過程中雙向身份認證,保證設備唯一性不受篡改,全面杜絕偽造設備/雲服務器發送請求。視頻流數據加密傳輸防止敏感信息泄露。

使用效果

以公司普通計算型服務器的配置(8核16G內存千兆網卡)為例,設置動態碼率2m以內的攝像頭實時流推流實測可以支持到400路。樹莓派3B+搭載視頻網關在同樣場景下可以支持不低於100路攝像頭實時流推流。

目前go重構的視頻網關已經在多個項目環境中使用,整體表現良好,並計划在后續的新項目以及老項目的視頻網關升級改造中逐步替換成go重構版本。

設計感悟

現在的設備正逐漸朝着物聯網,智能化方面發展,探索發現一條適合未來智能設備發展要求的技術棧是雲相關產品開發工程師必須面對的;

不要重復造輪子,優秀的官方庫,活躍的開源社區可以讓開發工作穩定可控並且豐富多彩;

追求產品質量和開發效率是每位開發同學都需要要考慮的問題,有了它們才能保證產品在市場競爭中立於不敗之地,用合適的工具做合適的事。

【騰訊雲原生】雲說新品、雲研新術、雲游新活、雲賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM