視頻網關是視頻云系統下的一個邊緣容器設備,它起著將視頻資料承上啟下的功能,
視頻云
說到邊緣視頻網關就不得不提到云計算中的視頻云,它是各領域的視頻系統比如安防監控等向著智能化、物聯網、上云發展的產物,
在云平臺上通過云服務器和邊緣視頻設備將采集的視頻輸出編碼后經過網路實時傳輸給終端,終端進行實時解碼后顯示輸出,終端同時可以進行操作,經過網路將操作控制資訊實時傳送給云端應用后臺對邊緣視頻設備進行控制,

一個物聯網場景下云邊協同的智能視頻云系統,具有實時流、歷史錄像功能,并支持對視頻資料演算法分析與結果聯動控制,可以兼容市面上大多數廠商的視頻設備比如攝像頭和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重構版本,
設計感悟
現在的設備正逐漸朝著物聯網,智能化方面發展,探索發現一條適合未來智能設備發展要求的技術堆疊是云相關產品開發工程師必須面對的;
不要重復造輪子,優秀的官方庫,活躍的開源社區可以讓開發作業穩定可控并且豐富多彩;
追求產品質量和開發效率是每位開發同學都需要要考慮的問題,有了它們才能保證產品在市場競爭中立于不敗之地,用合適的工具做合適的事,
【騰訊云原生】云說新品、云研新術、云游新活、云賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/248005.html
標籤:其他

