天天看點

通過ffplay播放OSS上的mp3檔案會斷開

問題描述

使用者的mp3視訊存在在OSS上,使用ffplay播放的時候,播放途中會出現播放斷開,報錯如下

Error in the pull function. The specified session has been invalidated for some reason.

通過ffplay播放OSS上的mp3檔案會斷開

初步分析

1. 嘗試複現

根據使用者提供的mp3音頻的URL,嘗試在本地複現,發現測試播放一直正常,并沒有出現使用者說的播放中途斷開的問題,而使用者卻幾乎百分百必現該問題,是以懷疑還是用戶端網絡環境問題。

2. 傳輸加速正常

讓使用者嘗試使用OSS的傳輸加速來播放,測試發現使用傳輸加速的位址去播放,就可以完整地播放完。根據以上測試,初步判斷跟客戶的網絡環境有關。不過使用者顯然不認可這個結論,首先使用者回報同樣把這個mp3音頻放到另外一個雲廠家,在同樣的用戶端上去播放就一切正常,這不得不懷疑這個問題可能還是跟OSS有關。其次使用OSS的傳輸加速是需要費用的,客戶并不想為此買單。

3. 對比測試

讓使用者嘗試直接用chrome浏覽器播放或者用VLC播放器去播放,播放效果還可以,可以順利播放完,但是用ffplay播放卻一直有問題。這個測試的結論,似乎又推翻了上一個用傳輸加速測試的結果,因為同樣的環境下用别的播放器卻可以完整播放。同時,如果wget下載下傳也是可以正常下載下傳完,并不會存在斷開的問題,由此分析這個問題還是跟播放器流式請求有關。

抓包分析-OSS

1. TCP ZeroWindow

為了更直覺定位問題,嘗試讓使用者用http去播放複現并提供一份抓包資料。通過過濾對應tcp流從下往上看,可以看到在19:21:48.605622時間點,NO1965包用戶端因為接收視窗滿了,Wireshark打了TCP ZeroWindow的标記,随後OSS發TCP Keep-Alive探測幀探測,直到19:21:59.621757時間點,NO1997包用戶端重新更新接收視窗,Wireshark标記TCP Window Update,OSS才重新發送資料,中間間隔了11s,見下圖3-1。同時看整個資料包,存在比較多的這種情況。

通過ffplay播放OSS上的mp3檔案會斷開

圖3-1 TCP ZeroWindow

2. OSS發送了FIN

從NO2152包開始OSS繼續發送資料給用戶端,直到最後NO2177包OSS突然發送了一個FIN包斷開了連接配接,通過更改Wireshark對于Time的顯示格式發現從開始播放到OSS發了FIN包斷開連接配接,整個過程才持續了100多苗,而整個音頻有10分鐘。這裡從抓包的現象來看的确跟使用者描述的現象一緻,在播放的過程中停止播放了,而且從抓包結果來看還是因為OSS突然發了FIN包導緻播放器斷開連接配接,無法讀取到新的視訊Packet導緻停止播放,見下圖3-2

通過ffplay播放OSS上的mp3檔案會斷開

圖3-2 OSS發送了FIN包

3. OSS單連接配接最低下載下傳速度

以上現象看比較像一個OSS最低下載下傳速度的限制,我們先來說下這個最低下載下傳速度的了解。

一個正常C/S 架構的系統,通常會有很多Buffer,會設定很多逾時時間,針對Tengine(OSS基于Tengine)會有send_timeout,recv_timeout,keepalive_timeout等各種逾時限制。這就會造成系統會有一個最小下載下傳速度的限制。以下是一份基于wget的 --limit-rate 功能進行二分測試得到的OSS最低下載下傳速度的資料

單連接配接持續 5k 以内速度必然出問題(一般持續30s+出問題) 單連接配接持續 5 ~10k 以内速度随機出問題,看系統狀況(比較具有偶然性) 單連接配接持續 10k+ 基本不出問題。    

4. 分析下載下傳速度

看抓封包件的Conversations資訊,發現下載下傳速率很低,132s才請求了1695KB的資料,平均速度也就差不多10KB/s的速度,見下圖3-3

通過ffplay播放OSS上的mp3檔案會斷開

圖3-3 分析下載下傳速度

分析源檔案mp3檔案,大小是6559630Bytes,整個音頻時長648s,見下圖3-4。按照音頻大小和音頻時長可以計算得出平均每秒10123Bytes,略微大于10KB/s。但網絡并不能保證每一秒的資料都一定大于10KB,在這個過程中有多次存在下載下傳速度比較低的情況,低于OSS的最低下載下傳速度,就會被OSS斷掉連接配接,這也可以解釋為什麼OSS會突然發FIN包,同時也可以解釋為何用戶端一直出現TCP ZeroWindow的問題。OSS要高于這個最低下載下傳速度發包,但播放速度以及碼率限制了播放器緩沖區能夠接收的資料,是以就會将下載下傳速度降下來,多次之後就會出現後續OSS不再發送資料 。基于以上分析,要解決這個問題,需要給這個音頻轉碼,提高碼率以此來保證提高下載下傳速度(因為播放時長是不可能縮短的)。檔案不大的情況下也可以考慮一次性全讀出來,放記憶體或者本地再慢慢處理。

通過ffplay播放OSS上的mp3檔案會斷開

圖3-4 ffplay分析音頻Duration時長資訊

為什麼使用傳輸加速正常

傳輸加速sndbuf 稍大,對于這個檔案本身恰好沒問題而已,換個大點的檔案還是會有一樣的問題,傳輸加速并不能從根本上解決這個問題。

為什麼使用chrome播放正常

Chrome播放是通過range的形式去GET請求,需要多少資料就從伺服器端RangeGet讀多少,是以并不會産生這個最低下載下傳速度的問題。

為什麼我測試正常

我們的網絡環境品質較好,是以在請求的過程中始終保持在10KB/s +的速度,并沒有觸發OSS的最低下載下傳速度。而客戶那邊網絡品質不佳,剛好到了這個臨界點。

CDN加速架構

1. CDN加速也有問題

由于客戶的業務就是需要ffplay流式讀取播放,以上說的方案并不能滿足使用者需求。考慮到CDN加速OSS,用戶端可以就近讀取緩存,有更好的加速效果,使用者嘗試使用了CDN加速的方式來播放,但是問題依舊反複出現。

2. 抓包分析-CDN

抓了一份ffplay播放通過CDN加速的URL複現問題的包,發現也是存在CDN在發送資料的時候突然發送了FIN包,見下圖NO2306包。由于CDN也是基于Tengine,看起來也是有跟OSS類似的問題。

通過ffplay播放OSS上的mp3檔案會斷開

3. 增加寫用戶端逾時

由于CDN針對某一個域名是可以調整寫用戶端逾時時間調整的,這個案例中可以加大寫用戶端逾時時間,加大寫用戶端逾時時間可以降低系統的最低下載下傳速度,由此來解決這個問題。這個案例裡,我們将使用者的CDN域名的寫用戶端時間調整到900s(預設30s)以後,使用者回報可以完整的播放完mp3了。

适用于

  • 對象存儲OSS
  • CDN

繼續閱讀