視頻網關是視頻雲系統下的一個邊緣容器設備,它起着將視頻數據承上啓下的功能。node
說到邊緣視頻網關就不得不提到雲計算中的視頻雲,它是各領域的視頻系統好比安防監控等向着智能化、物聯網、上雲發展的產物。linux
在雲平臺上經過雲服務器和邊緣視頻設備將採集的視頻輸出編碼後通過網絡實時傳輸給終端,終端進行實時解碼後顯示輸出。終端同時能夠進行操做,通過網絡將操做控制信息實時傳送給雲端應用後臺對邊緣視頻設備進行控制。android
一個物聯網場景下雲邊協同的智能視頻雲系統,具備實時流、歷史錄像功能,並支持對視頻數據算法分析與結果聯動控制,能夠兼容市面上大多數廠商的視頻設備好比攝像頭和NVR。不只能夠在公有云/私有云部署,甚至提供支持有損服務的本地局域網視頻最小系統。c++
視頻網關是雲計算在視頻垂直領域中的邊緣容器設備,能夠將其理解鏈接視頻數據在視頻傳感器與雲上服務之間的橋樑,是視頻雲系統中的關鍵一環,實現視頻設備普遍的兼容性以及雲邊協同都離不開它的身影。設計一個功能完備,可擴展,高可用的視頻網關是很是值得投入的。golang
視頻網關須要實現的基本功能包括視頻流採集與推送、視頻設備接入與管理等,做爲一個與底層硬件打交道的設備,又涉及到雲計算中的接入、安全以及雲邊協同等方面,可謂麻雀雖小五臟俱全。算法
視頻雲系統中視頻數據的採集由位於邊緣側的視頻網關完成,視頻網關鏈接視頻採集設備好比IPC/NVR, 經過廠家SDK或者ONVIF協議對視頻採集設備進行管理,網關拉取視頻採集設備的數據流並推送雲端或者邊緣側的視頻服務,由視頻服務對視頻數據進行轉碼、數據流協議轉換等操做以適配不一樣的播放客戶端。編程
攝像頭、NVR等視頻設備位於用戶局域網內,經過邊緣視頻網關接入到視頻雲系統中。邊緣視頻網關和視頻設備須要在管理平臺上經過導入的方式作登記以便明確視頻網關與視頻設備以及視頻網關與業務的綁定關係。視頻網關管理視頻設備並將設備狀態實時同步到雲視頻系統中,管理平臺實現"設備影子"並提供對視頻網關以及視頻設備狀態信息的增刪改查接口。windows
視頻上雲鬚要安全認證,視頻雲系統中邊緣容器設備接入雲端服務、邊緣容器設備之間以及邊緣容器設備與雲端服務之間的數據流採用標準國密算法保證其運行的安全性,其中邊緣容器設備接入雲視頻流程中採用國密sm2非對稱祕鑰技術保證接入安全,邊緣容器設備與雲視頻之間的數據通道採用國密sm4對稱祕鑰技術保證信令與視頻數據的安全。api
視頻雲系統中視頻網關等邊緣容器設備一般位於用戶局域網內,視頻網關在局域網內鏈接視頻設備好比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)這樣的主流操做系統、amd6四、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查看文件內容。
在開發過程當中遇到的性能優化問題挑了兩個比較典型的案例進行分析。
視頻網關與雲視頻系統內核(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這樣的工具,排查起來仍是挺麻煩了,採用了正確的姿式,再分析能夠看到已經沒有訂閱接口的時間佔用了。
既然視頻網關的主要功能是推流那麼網絡傳輸接口這塊必定是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重構版本。
如今的設備正逐漸朝着物聯網,智能化方面發展,探索發現一條適合將來智能設備發展要求的技術棧是雲相關產品開發工程師必須面對的;
不要重複造輪子,優秀的官方庫,活躍的開源社區可讓開發工做穩定可控而且豐富多彩;
追求產品質量和開發效率是每位開發同窗都須要要考慮的問題,有了它們才能保證產品在市場競爭中立於不敗之地,用合適的工具作合適的事。