直播是一個(gè)龐大而復(fù)雜的業(yè)務(wù)形態(tài),一個(gè)優(yōu)秀的直播系統(tǒng)涉及眾多團(tuán)隊(duì)的共同協(xié)作,有非常完整的直播鏈路。
那么,直播鏈路中都有哪些角色?這些角色要解決的是哪些問題?要優(yōu)化某個(gè)環(huán)節(jié)時(shí)需要哪些角色的配合?這些角色優(yōu)化鏈路的手段有哪些?……
想要厘清這些問題,對(duì)直播全鏈路接觸比較少的同學(xué)無疑要花費(fèi)大量的時(shí)間才能完成。本文將從直播拉流切入,力求幫助有興趣的同學(xué)簡單明了而全面地理解整個(gè)直播鏈路。
為什么直播拉流是“最后一公里”
從整個(gè)直播鏈路來看,直播拉流作為直播內(nèi)容觸達(dá)觀眾的最后一個(gè)環(huán)節(jié),從客觀現(xiàn)實(shí)上來說,就是直播鏈路的“最后一公里”。
直播拉流作為整個(gè)直播鏈路的“最后一公里”,鏈路上任何一個(gè)前置環(huán)節(jié)出現(xiàn)問題,都會(huì)在拉流過程中體現(xiàn)出來。通過分析、理解拉流過程中產(chǎn)生的各類問題,會(huì)是理解直播鏈路最有效的方式之一。
作為直播內(nèi)容消費(fèi)的關(guān)鍵環(huán)節(jié),如何優(yōu)化這“最后一公里”上的各類體驗(yàn),是每個(gè)直播從業(yè)人員不斷探索的問題,從直播拉流理解怎么做好直播無疑是一個(gè)好的選擇。
從直播業(yè)務(wù)理解直播鏈路
上圖所示是從業(yè)務(wù)層面看到的一次直播觀播過程,也是對(duì)直播拉流的一個(gè)高度簡化。麻雀雖小,但五臟俱全,圖中顯式或隱式地涵蓋了整個(gè)直播鏈路幾乎所有關(guān)鍵角色和流程。
直播鏈路上的關(guān)鍵角色
客戶端
客戶端中囊括了直播鏈路中多個(gè) SDK,包括直播中臺(tái) SDK、直播推流 SDK,以及直播拉流 SDK。
直播中臺(tái) SDK
直播中臺(tái) SDK 封裝直播間內(nèi)的所有業(yè)務(wù)邏輯,能夠串聯(lián)流調(diào)度與推拉流 SDK,給推拉流 SDK 提供日志上報(bào)、配置下發(fā)能力。
直播推流 SDK
直播推流 SDK 作為提供給中臺(tái) SDK 的封裝層,提供采集、編碼、推流、連麥等能力,響應(yīng)流調(diào)度下發(fā)的各種配置,例如推流分辨率、碼率、編碼方式等端上能力,完成推流過程中各類日志信息的采集并上報(bào)至中臺(tái) SDK。
直播拉流 SDK
直播拉流 SDK 作為提供給中臺(tái) SDK 的封裝層,提供直播拉流相關(guān)能力,同時(shí)封裝了超分、音量均衡等功能,響應(yīng)流調(diào)度、settings 下發(fā)的配置,例如是否開啟硬解等端上能力,并完成拉流過程中各類日志信息的采集并上報(bào)至中臺(tái) SDK。
CDN
CDN 全稱是 Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò)。CDN 的核心任務(wù)是使內(nèi)容傳輸?shù)母、更穩(wěn)定。
整個(gè)直播系統(tǒng)中,源站提供了鑒權(quán)、轉(zhuǎn)碼、回調(diào)、禁播等能力。CDN 通過邊緣節(jié)點(diǎn),在客戶端和源站之間增加一層緩存,請(qǐng)求過的數(shù)據(jù)會(huì)在邊緣節(jié)點(diǎn)緩存一段時(shí)間。
動(dòng)態(tài)請(qǐng)求內(nèi)容會(huì)直接回源拉取,CDN 優(yōu)化整個(gè)傳輸鏈路,解決跨網(wǎng)訪問、傳輸擁塞等問題。
流調(diào)度
流調(diào)度主要處理與直播流管理相關(guān)的任務(wù),內(nèi)部封裝了多家 CDN 供應(yīng)商,屏蔽了不同 CDN 的細(xì)節(jié)區(qū)別。滿足大規(guī)模的直播內(nèi)容分發(fā)需求,同時(shí)保證了服務(wù)的高可用性。提供完整的解決方案,方便業(yè)務(wù)方快速接入直播業(yè)務(wù)。
關(guān)鍵流程
直播數(shù)據(jù)流
直播內(nèi)容從生產(chǎn)到消費(fèi)主要涉及到推流端、CDN%20(源站、邊緣節(jié)點(diǎn))%20以及拉流端,如圖中實(shí)箭頭所示即為直播數(shù)據(jù)流方向,其中:
在推流端,推流%20SDK%20完成了主播的音視頻采集,添加美顏、濾鏡后,需要經(jīng)過編碼、封裝,最終按照指定地址,向%20CDN%20邊緣節(jié)點(diǎn)推流;
收流邊緣節(jié)點(diǎn)在被動(dòng)收到用戶的推流請(qǐng)求后,這個(gè)節(jié)點(diǎn)會(huì)主動(dòng)地將這個(gè)流轉(zhuǎn)推(中繼)到上層節(jié)點(diǎn),上層節(jié)點(diǎn)經(jīng)過同樣的過程,最終將源流轉(zhuǎn)推到源站;
源站內(nèi)部會(huì)進(jìn)一步地將源流轉(zhuǎn)推至其他集群完成轉(zhuǎn)碼、錄制等任務(wù);
在拉流端,拉流%20SDK%20會(huì)根據(jù)流地址向%20CDN%20邊緣節(jié)點(diǎn)拉流,此時(shí)根據(jù)這路流在該節(jié)點(diǎn)上的緩存命中情況,出現(xiàn)兩種結(jié)果:
如果命中緩存,則邊緣節(jié)點(diǎn)將直接返回緩存數(shù)據(jù);
如果未命中緩存,邊緣節(jié)點(diǎn)將逐級(jí)進(jìn)行回源,最終將流數(shù)據(jù)返回邊緣節(jié)點(diǎn),最終返回播放器。
詞語釋義:
源流:推流端推出的那路流。
轉(zhuǎn)碼:當(dāng)需要對(duì)源流的分辨率、碼率、編碼等參數(shù)進(jìn)行修改時(shí),就需要進(jìn)行轉(zhuǎn)碼,例如媒體直播往往由專業(yè)設(shè)備或者三方推流器推出,碼率會(huì)非常高,直接拉源流會(huì)造成帶寬壓力過大,這時(shí)就需要轉(zhuǎn)碼。但轉(zhuǎn)碼任務(wù)本身也需要消耗資源,因此衍生出推流轉(zhuǎn)碼、拉流轉(zhuǎn)碼等不同轉(zhuǎn)碼策略。
回源:往往發(fā)生在拉流側(cè),邊緣節(jié)點(diǎn)上未命中緩存時(shí),就需要到源站找到所需要的流,該過程即為回源。在上圖中表示為虛箭頭。完成回源后,邊緣節(jié)點(diǎn)上會(huì)留下這路流的緩存。
流調(diào)度
在開播側(cè),參與到整個(gè)流程的角色包括%20App、直播%20SDK、開播服務(wù)、房間服務(wù)以及流調(diào)度。各角色在開播中的工作如下:
主播在%20App%20發(fā)起開播請(qǐng)求;
開播服務(wù)收到開播請(qǐng)求后根據(jù)不同的場景,使用不同的發(fā)布點(diǎn)%20ID%20向流調(diào)度發(fā)起請(qǐng)求創(chuàng)建直播流;
流調(diào)度根據(jù)具體要使用的發(fā)布點(diǎn)生成對(duì)應(yīng)的推流地址,在這個(gè)過程中完成調(diào)度,決定使用哪家%20CDN%20以及使用何種協(xié)議等;
開播服務(wù)將推流地址返回至%20App%20后,App%20開始推流、房間服務(wù)在推流成功后更新流狀態(tài);
在看播側(cè),參與到整個(gè)流程的角色包%20App、直播%20SDK、房間服務(wù)以及流調(diào)度,其中:
觀眾在%20App%20發(fā)起進(jìn)房請(qǐng)求;
房間服務(wù)收到進(jìn)房請(qǐng)求后,透傳請(qǐng)求中攜帶的用戶信息、向流調(diào)度請(qǐng)求拉流地址;
流調(diào)度收到請(qǐng)求后,根據(jù)用戶信息進(jìn)行調(diào)度,決定下發(fā)的檔位信息、功能信息等,并返回至房間服務(wù);
房間服務(wù)獲取到流信息后,完成檔位映射等邏輯,最終返回%20App;
App%20獲得流信息后透傳至直播%20SDK,并觸發(fā)播放。
流調(diào)度負(fù)責(zé)了與流管理相關(guān)的所有工作,包括流創(chuàng)建、流參數(shù)下發(fā)、流狀態(tài)管理、生成推拉流地址等,同時(shí)流調(diào)度在重;顒(dòng)中也起著舉足輕重的作用。
了解流調(diào)度是如何進(jìn)行調(diào)度的,最好的方式是從流調(diào)度返回的數(shù)據(jù)來理解。例如在拉流端,所有調(diào)度信息是封裝在%20stream_data%20中,隨房間服務(wù)接口返回,由中臺(tái)客戶端透傳給拉流%20SDK,主要包含了以下重要信息:
分辨率,除源流外,目前支持的檔位有UHD、HD、SD、LD、MD、AO、AUTO,其中
AO、MD%20僅在特殊情況下使用,例如后臺(tái)播放等不需要高碼率的情況
并以不同的標(biāo)識(shí)符分別代表該檔位為%20H.265%20或%20H.264%20轉(zhuǎn)碼
主備,為滿足大型活動(dòng)中的災(zāi)備需求,下發(fā)流數(shù)據(jù)中會(huì)包含兩條線路–即主(Main)備(Backup)雙線,實(shí)際上進(jìn)行了%20CDN%20調(diào)度
格式,在每個(gè)檔位的每條線路下,一般存在多種格式(format)供拉流使用,例如常規(guī)%20FLV、用于超低時(shí)延的%20RTM、以及時(shí)移直播%20TSL%20等
流調(diào)度參數(shù),為直播拉流提供所需的各類參數(shù),例如控制實(shí)際使用協(xié)議、格式等,在實(shí)現(xiàn)調(diào)度的同時(shí),避免上層業(yè)務(wù)感知不必要的細(xì)節(jié);此外可以根據(jù)具體的場景控制參數(shù)的生效范圍,實(shí)現(xiàn)從%20CDN%20維度到單路流維度的精準(zhǔn)控制
流調(diào)度在直播日常業(yè)務(wù)中,除了要對(duì)線上的默認(rèn)分辨率、碼率等進(jìn)行控制之外,在重;顒(dòng)中也起著舉足輕重的作用。
當(dāng)預(yù)估帶寬很大時(shí),往往需要多家%20CDN%20來共同分擔(dān)壓力,同時(shí)需要根據(jù)各家質(zhì)量來調(diào)節(jié)占比;
為避免推流端故障往往需要一主一備兩路流的熱備方案(甚至還需要冷備),拉流端需要在其中一路發(fā)生故障時(shí)自行切換到另一路;
在帶寬壓力過大時(shí),需要及時(shí)降低下發(fā)的默認(rèn)清晰度以緩解帶寬壓力,同時(shí)在帶寬充足時(shí)提高默認(rèn)清晰度以優(yōu)化體驗(yàn)。
詞語釋義
ABR:即自適應(yīng)碼率,在直播間中作為%20AUTO%20分辨率檔位,但是%20stream_data%20中實(shí)際不會(huì)包含這樣一個(gè)檔位,原因在于%20ABR%20實(shí)際是將要使用的若干檔位拼裝成了一個(gè)%20MPD(Media%20Presentation%20Description)傳遞給播放器,播放器內(nèi)部切檔時(shí)實(shí)際使用的是對(duì)應(yīng)檔位的流地址。
日志與監(jiān)控
端監(jiān)控作為日志上報(bào)的起點(diǎn),將客戶端產(chǎn)生的各類日志按照一定的規(guī)則(例如采樣率等),進(jìn)行上報(bào);根據(jù)不同的 log_type,上報(bào)的日志會(huì)被分流并寫入到 Kafka 的不同 topic 中;根據(jù)數(shù)據(jù)不同的消費(fèi)場景及用途,日志會(huì)經(jīng)歷一系列處理(例如在 Flink 任務(wù)中進(jìn)行清洗等),并最終呈現(xiàn)到各類數(shù)據(jù)工具當(dāng)中。
了解日志數(shù)據(jù)流對(duì)于定位日志相關(guān)的各類問題是非常有幫助的。例如在 Kibana 中找不到日志時(shí),可以從日志是否上報(bào)(通過 Charles 抓取端監(jiān)控 monitor 接口上報(bào)數(shù)據(jù)確認(rèn))、分流是否正確(通過檢查 log_type 確認(rèn),一般不會(huì)在該環(huán)節(jié)出現(xiàn)問題)、是否由于日志中存在非法字段而被清洗(通過檢查端監(jiān)控中的原始日志確認(rèn))等。
從直播鏈路理解優(yōu)化與問題
為什么拉不到流?
直播是一條完整的鏈路,鏈路上任何一個(gè)環(huán)節(jié)中斷都會(huì)導(dǎo)致拉流端出現(xiàn)拉流失敗的情況:
推流端-收流節(jié)點(diǎn)中斷:單路流所有檔位、所有觀眾將出現(xiàn)進(jìn)房時(shí)拉不到流或直播間內(nèi)卡頓;
收流節(jié)點(diǎn)-源站中斷:一般不會(huì)出現(xiàn),故障源站上的所有流將出現(xiàn)異常;
轉(zhuǎn)碼異常:某一個(gè)或幾個(gè)轉(zhuǎn)碼檔位出現(xiàn)異常,源流正常,觀看轉(zhuǎn)碼檔位的觀眾報(bào)障;
源站-拉流節(jié)點(diǎn)中斷:從故障邊緣節(jié)點(diǎn)上拉流的全部觀眾將會(huì)異常;
拉流節(jié)點(diǎn)-拉流端中斷:單用戶拉流出現(xiàn)故障。
前述情況主要描述的鏈路上某個(gè)環(huán)節(jié)中斷導(dǎo)致的拉流失敗,有時(shí)拉流失敗其實(shí)是首幀耗時(shí)過長造成的,這種情況在拉流成功率指標(biāo)波動(dòng)分析時(shí)較為常見:首幀耗時(shí)增長導(dǎo)致了拉流成功率下降。
為什么首幀慢?
首幀分階段分析
以 HTTP-FLV 為例,從觸發(fā)播放器的 play 接口到最終完成首幀渲染,需要經(jīng)歷以下這些過程:
DNS 解析: 決定了要從 CDN 的哪個(gè)邊緣節(jié)點(diǎn)拉流。這一過程在拉流 SDK 以及播放器內(nèi)核中都會(huì)發(fā)生,后者往往是因?yàn)?SDK 層沒有解析到 IP 地址。DNS 解析耗時(shí)通常在 100ms 左右(localDNS,使用 HTTP-DNS 會(huì)進(jìn)一步增加),因此 HTTP 場景下,我們可以采用 IP 直連的方式規(guī)避 DNS 耗時(shí)。
實(shí)現(xiàn) IP 直連需要在拉流前獲取到 IP 地址,其關(guān)鍵在于 DNS 緩存(緩存之前的 DNS 解析結(jié)果,拉流 SDK 層的 DNS 策略)和 DNS 預(yù)解析(在 App 啟動(dòng)之后一段時(shí)間,對(duì)可能用到的所有域名進(jìn)行 DNS 解析并緩存結(jié)果,節(jié)點(diǎn)優(yōu)選 SDK 的核心邏輯);
緩存的 DNS 結(jié)果會(huì)過期,尤其是 CDN 進(jìn)行節(jié)點(diǎn)覆蓋調(diào)整時(shí),緩存的 DNS 可能會(huì)導(dǎo)致調(diào)整不能及時(shí)生效,因此需要定期更新 DNS 結(jié)果;
用戶發(fā)生跨網(wǎng)時(shí),由于運(yùn)營商變化,也會(huì)導(dǎo)致此前緩存的 DNS 不可用,因此需要在網(wǎng)絡(luò)狀態(tài)發(fā)生變化時(shí)更新 DNS 結(jié)果。
TCP 建聯(lián): 與邊緣節(jié)點(diǎn)建立 TCP 連接,這一過程的耗時(shí)主要是三次握手,耗時(shí)1-RTT。要優(yōu)化建聯(lián)耗時(shí),可以通過 TFO(TCP Fast Open,Wiki),或使用 UDP 協(xié)議(QUIC、KCP)。
TCP 首包: HTTP 響應(yīng)完成,此時(shí)開始返回音視頻數(shù)據(jù)。如果此時(shí)邊緣節(jié)點(diǎn)上有這路流的緩存,那么將直接返回緩存數(shù)據(jù);如果沒有命中緩存,TCP 首包返回之前將發(fā)生回源。要優(yōu)化首包耗時(shí),核心思路在于降低回源率,常見手段有增加邊緣節(jié)點(diǎn)緩存保持時(shí)間,對(duì)于大型活動(dòng)提前進(jìn)行預(yù)熱、以保證更多邊緣節(jié)點(diǎn)上有緩存。
視頻首包: 耗時(shí)主要發(fā)生在 avformat_find_stream_info 函數(shù)調(diào)用,播放器在播放前需要探測一定量的流數(shù)據(jù),以確定流格式、編碼等流信息。由于目前在各個(gè)宿主中播放的格式相對(duì)固定,因此不需要探測過多的數(shù)據(jù)即可確定流信息。所以可以通過調(diào)節(jié)探測的數(shù)據(jù)量以優(yōu)化視頻首包耗時(shí)。通過減小探測數(shù)據(jù)量,首包耗時(shí)下降 300ms 左右。
降低流數(shù)據(jù)探測的數(shù)據(jù)量也可能會(huì)帶來不良后果。當(dāng)探測的數(shù)據(jù)量過少時(shí),可能會(huì)導(dǎo)致讀取到的流信息不全,例如只探測到音頻數(shù)據(jù)、沒有探測到視頻數(shù)據(jù)(尤其是在音視頻數(shù)據(jù)交織不均勻的情況),最終出現(xiàn)有聲無畫或聲音正常、畫面卡住的問題。
視頻首幀解碼和視頻首幀渲染: 分別完成視頻首幀解碼和視頻首幀渲染,優(yōu)化的主要方向是 decoder 及 render 實(shí)例的預(yù)初始化等。
快啟buffer
為了實(shí)現(xiàn)秒開,各家 CDN 都在邊緣節(jié)點(diǎn)上開啟了快啟 buffer 策略?靻 buffer 的核心邏輯是基于邊緣節(jié)點(diǎn)上的緩存(GopCache),調(diào)節(jié)緩存數(shù)據(jù)下發(fā)的具體數(shù)據(jù)范圍,同時(shí)保證視頻數(shù)據(jù)從關(guān)鍵幀開始下發(fā)?靻 buffer 也存在不同的策略,例如上限優(yōu)先或下限優(yōu)先,后者會(huì)要求對(duì)接的 CDN 廠商按照下限優(yōu)先的原則下發(fā)緩存數(shù)據(jù),比如下限 6s ,會(huì)先在緩存數(shù)據(jù)中定位最新 6s 的數(shù)據(jù),然后向 6s 前的舊數(shù)據(jù)查找第一個(gè)關(guān)鍵幀下發(fā)(解碼器要從關(guān)鍵幀開始解碼,因此一定需要從關(guān)鍵幀開始下發(fā))。
詞語釋義:
IP 直連: 即將 HTTP 地址中的 host 部分直接替換為對(duì)應(yīng)的IP地址,并在 HTTP 請(qǐng)求的header中添加“Host”行,其值為原始的host,例如http://``x``.``x``.``x``.``x``/``app``/``stream`` .flv "Host: ``pull-host``.com\r\n"。前述方法最為規(guī)范,有的 CDN 也會(huì)支持在 host 前直接插入 IP 的方式實(shí)現(xiàn) IP 直連,但該方法并不通用,因此并不建議使用前插 IP 的方法。
為什么會(huì)卡頓?
拉流發(fā)生卡頓的直接原因是播放器中的緩存耗盡,此時(shí)播放器卡住其實(shí)是在進(jìn)行 Rebuffering 。
導(dǎo)致 buffer 耗盡的直接原因是播放器中 buffer 消費(fèi)的速度高于 buffer 接收的速度:最為常見的例子就是當(dāng)前拉流端的帶寬顯著低于視頻的碼率。同時(shí),在帶寬充足的情況下,鏈路上前置環(huán)節(jié)的中斷也有可能導(dǎo)致拉流端卡頓。
因此為了對(duì)抗卡頓,一個(gè)最直接的方法就是在播放器中緩存更多數(shù)據(jù),以期在緩存數(shù)據(jù)耗盡之前渡過網(wǎng)絡(luò)波動(dòng)。最直接的做法就是增大播放器的最大緩存,使播放器能夠緩存足夠多的數(shù)據(jù)。
但直播場景的特殊性在于直播內(nèi)容是實(shí)時(shí)產(chǎn)生的,在最大緩存允許的情況下,播放器中的緩存完全取決于當(dāng)前鏈路上有多少緩存(還記得 GopCache 嗎)。
在播放器數(shù)據(jù)消費(fèi)速度不變、帶寬充足的情況下,播放器在獲得了鏈路上所有的緩存后,buffer長度將不再變化,也就意味著播放器只能依賴這些緩存來對(duì)抗卡頓。在能獲得的緩存總量有限的情況下,進(jìn)一步增強(qiáng)現(xiàn)有的緩存對(duì)抗卡頓能力的手段就是調(diào)整播放器消費(fèi)數(shù)據(jù)的速度,例如在首幀之后判斷當(dāng)前水位( buffer 長度)以決定是否起播(對(duì)應(yīng)起播 buffer 策略),或在水位較低時(shí)降低播放速度(對(duì)應(yīng)網(wǎng)絡(luò)自適應(yīng)策略)。
在有限的帶寬條件下,如果能夠更有效的利用帶寬、采用更加高效的傳輸協(xié)議,也可以有效地對(duì)抗弱網(wǎng)條件下的卡頓問題。因此 KCP、QUIC、QUICU 等相較于 TCP 更加高效的協(xié)議被應(yīng)用到了音視頻傳輸當(dāng)中。除此之外,在特定的帶寬情況下選擇合適的碼率,也是降低卡頓的有效手段之一,因此ABR也在直播中得到了應(yīng)用。
實(shí)際上“卡頓”在用戶反饋中涵蓋的情況很多,例如:App 本身的卡頓,或者 CDN 某些操作(數(shù)據(jù)積壓時(shí)丟棄視頻數(shù)據(jù)造成的視頻卡住、聲音正常,或者在數(shù)據(jù)積壓時(shí)主動(dòng)使播放器報(bào)錯(cuò)發(fā)生重試進(jìn)而導(dǎo)致播放器出現(xiàn)鬼畜),甚至視頻本身幀率較低,都會(huì)導(dǎo)致用戶出現(xiàn)“卡頓”的感覺。為了更加貼近用戶對(duì)于卡頓的感受,我們?cè)黾恿艘曨l渲染卡頓這一指標(biāo)。
為什么有延遲?
為了對(duì)抗卡頓,我們需要在直播鏈路中增加緩存,但是緩存的引入必然導(dǎo)致延遲的增加。
例如在抖音上線低延遲 FLV 之前,端到端延遲在5~8s,而這些延遲的引入主要原因就在于 CDN 邊緣節(jié)點(diǎn)上的 GopCache --只有緩存到足夠的數(shù)據(jù)才會(huì)進(jìn)行下發(fā),在這個(gè)過程中便引入了時(shí)延(當(dāng)然不管是推流端采集、服務(wù)端中間鏈路都會(huì)引入延遲,但是相對(duì)于緩存引入的延遲影響較小)。
在客戶端播放速度不變的情況下,延遲會(huì)一直保持下去,另外在發(fā)生卡頓(且未觸發(fā)重試)時(shí)延遲會(huì)不斷累積。
因此通過調(diào)節(jié)邊緣節(jié)點(diǎn)的 GopCache 大小可以直接影響到鏈路上的端到端延遲。與此同時(shí),Gop 的大小也會(huì)影響到不同用戶之間的延遲差,在具體場景中就體現(xiàn)為兩個(gè)觀眾的延遲存在差異(比如內(nèi)購會(huì)別人看到主持人說了“3、2、1,開搶”,你才看到“3”),兩名觀眾進(jìn)入直播間的時(shí)間差即使很短,但是延遲差可能達(dá)到一個(gè) Gop(以下圖為例,假設(shè)快啟 buffer 下限為 1.3s ,用戶分別在 1.2s 和 1.4s 進(jìn)入直播間,延遲分別是多少?)。
為了更好地保證觀眾端的延遲體驗(yàn),我們?cè)谌媸崂砹司上的延遲產(chǎn)生原因,實(shí)現(xiàn)了低延遲 FLV 方案,使得線上端到端延遲由 7s 左右下降至 3.5s 左右,并在抖音取得了顯著的 QoE 正向收益;與此同時(shí),RTM 低延遲拉流方案也在穩(wěn)步推進(jìn)中。
如何判斷拉流異常問題的發(fā)生環(huán)節(jié)?
問題定位一般流程
如前文所述,直播是一個(gè)全鏈路的業(yè)務(wù)形態(tài),尤其是拉流端處在整個(gè)鏈路的末端,各個(gè)環(huán)節(jié)的問題都會(huì)導(dǎo)致拉流端出現(xiàn)異常。因此如何根據(jù)現(xiàn)有信息及工具來定位問題的根源,便是解決問題的關(guān)鍵。定位問題一般要經(jīng)歷以下過程:
對(duì)于各類問題,首先需要的是明確的case與信息,針對(duì)具體case,需要的信息有:
拉流端device_id或user_id
問題現(xiàn)象描述(至少提供roomID或者流名)
問題發(fā)生時(shí)間
最好提供錄屏
在Trace平臺(tái),根據(jù)前述信息檢索相關(guān)日志,可以根據(jù)問題現(xiàn)象進(jìn)一步查找對(duì)應(yīng)的事件(對(duì)應(yīng)event_key字段)
拉不到流?找到play_stop事件
根據(jù)first_frame_blocked字段判斷首幀卡在哪個(gè)階段
根據(jù)code字段判斷錯(cuò)誤碼是什么(錯(cuò)誤碼是0?還記得拉不到流的部分原因是首幀慢嗎?)
首幀慢?找到first_frame事件
根據(jù)前文中分階段耗時(shí)對(duì)應(yīng)的字段,尋找存在顯著異常的階段
卡頓?找到stall事件
根據(jù)流名查詢對(duì)應(yīng)時(shí)間點(diǎn)推流端的推流情況,是否推流端卡頓
根據(jù)拉流端在問題時(shí)間段前后的日志信息判斷是持續(xù)性卡頓、短時(shí)間波動(dòng)還是流相關(guān)卡頓
如果找不到stall事件,只有render_stall,那么可能的原因就是發(fā)生了丟幀
例如花屏、綠屏之類的問題,在日志上一般沒有特別明顯的錯(cuò)誤,此時(shí)可以通過查看流回放判斷源流是否有異常。如果源流回放沒有異常,且用戶播放轉(zhuǎn)碼流,且流已經(jīng)結(jié)束的情況下,就需要運(yùn)營同學(xué)持續(xù)關(guān)注相關(guān)反饋,盡可能保留現(xiàn)場(因?yàn)檗D(zhuǎn)碼流不會(huì)進(jìn)行錄制)。
問題范圍與定位方向
除了前述定位問題的一般過程,問題發(fā)生的范圍也是快速定位問題的有效依據(jù)。一般有以下判斷方法,根據(jù)問題(同一時(shí)間段)發(fā)生在不同用戶或場景判斷:
所有主播及觀眾 --> 這種情況非常少見,如果出現(xiàn),一般意味著出現(xiàn)了整個(gè)系統(tǒng)級(jí)別的問題
單個(gè)主播的所有觀眾 --> 推流端本身或推流端到邊緣節(jié)點(diǎn)或源站引起,如果到邊緣節(jié)點(diǎn)日志正常,一般為源站問題
同一CDN下的多個(gè)主播的所有觀眾 --> 收流節(jié)點(diǎn)問題(收流節(jié)點(diǎn)相同)或源站問題(收流節(jié)點(diǎn)不同)
單個(gè)主播的部分觀眾(僅轉(zhuǎn)碼流觀眾或僅源流觀眾) --> 源站轉(zhuǎn)碼問題(默認(rèn)分辨率的存在導(dǎo)致判斷易受影響,如果只有轉(zhuǎn)碼流播放,那么發(fā)生問題即使的是源流,最終反饋問題的也只有轉(zhuǎn)碼流觀眾)
單個(gè)主播的部分觀眾(某一地區(qū)) --> 分發(fā)CDN問題,一般是某一節(jié)點(diǎn)問題,層級(jí)因地區(qū)而異
單個(gè)主播的部分觀眾(CDN聚集) --> 分發(fā)CDN問題,這種情況一般出現(xiàn)在活動(dòng),有多家CDN參與分發(fā)
全量用戶(或有版本等特征)某一時(shí)間點(diǎn)后 --> 基本是放量引起的
某些版本一段時(shí)間出現(xiàn)激增并驟降 --> 一般是流相關(guān)的問題,在某些版本觸發(fā)了異常
問題定位的經(jīng)驗(yàn)是需要不斷積累的,不可能一蹴而就;除經(jīng)驗(yàn)外,還需要深入理解各個(gè)角色在整個(gè)鏈路中的作用,根據(jù)問題的表現(xiàn)推測根因,再基于推測進(jìn)行佐證。
止損手段
推拉流 SDK 對(duì)于新功能都會(huì)添加各類開關(guān),以保證功能上線后、出現(xiàn)異常時(shí)可以及時(shí)關(guān)閉進(jìn)行止損。但是對(duì)于一些新問題或者一些歷史問題,如果沒有相應(yīng)開關(guān)進(jìn)行控制時(shí),對(duì)于業(yè)務(wù)線會(huì)造成不同程度的影響。
這類問題一般會(huì)是流相關(guān)的,且在測試階段隱蔽性高(測試階段沒有辦法百分之百覆蓋到這些流問題,尤其是新問題)、突發(fā)性強(qiáng)(往往隨直播開播時(shí)發(fā)生、關(guān)播時(shí)結(jié)束)。這類問題在初步分析問題、確定問題可以通過調(diào)度等手段解決時(shí),可以嘗試與轉(zhuǎn)碼、流調(diào)度配合完成這類問題的及時(shí)止損。隨后在新版本進(jìn)行問題修復(fù)。
總結(jié)
在實(shí)際的直播相關(guān)業(yè)務(wù)開發(fā)過程中,還有許許多多有趣且值得深入挖掘的內(nèi)容,這篇文章僅僅是對(duì)直播鏈路做了一個(gè)簡單的概覽,力求幫助沒有直播開發(fā)相關(guān)經(jīng)驗(yàn)的朋友對(duì)直播全鏈路有一個(gè)全局性的理解,相信各位朋友在理解了直播全鏈路之后,對(duì)于直播體驗(yàn)優(yōu)化或問題排查一定能夠更加得心應(yīng)手。
文章內(nèi)容僅供閱讀,不構(gòu)成投資建議,請(qǐng)謹(jǐn)慎對(duì)待。投資者據(jù)此操作,風(fēng)險(xiǎn)自擔(dān)。
11月11日,據(jù)網(wǎng)經(jīng)社數(shù)字零售臺(tái)(DR.100EC.CN)數(shù)據(jù)顯示,秋冬服飾仍是雙11的C位,女士針織衫、女士外套、女士羽絨服等位居服飾消費(fèi)前列,女士夾克銷量同比增長72%,女士棉衣、女士羊毛衫銷量同比增長50%以上。男士外套銷量同比增長30%以上。
奧維云網(wǎng)(AVC)推總數(shù)據(jù)顯示,2024年1-9月明火炊具線上零售額94.2億元,同比增加3.1%,其中抖音渠道表現(xiàn)優(yōu)異,同比有14%的漲幅,傳統(tǒng)電商略有下滑,同比降低2.3%。
“以前都要去窗口辦,一套流程下來都要半個(gè)月了,現(xiàn)在方便多了!”打開“重慶公積金”微信小程序,按照提示流程提交相關(guān)材料,僅幾秒鐘,重慶市民曾某的賬戶就打進(jìn)了21600元。
華碩ProArt創(chuàng)藝27 Pro PA279CRV顯示器,憑借其優(yōu)秀的性能配置和精準(zhǔn)的色彩呈現(xiàn)能力,為您的創(chuàng)作工作帶來實(shí)質(zhì)性的幫助,雙十一期間低至2799元,性價(jià)比很高,簡直是創(chuàng)作者們的首選。
9月14日,2024全球工業(yè)互聯(lián)網(wǎng)大會(huì)——工業(yè)互聯(lián)網(wǎng)標(biāo)識(shí)解析專題論壇在沈陽成功舉辦。