? ? ? ?AlrDetector(應用受限區域檢測器)是WebRTC中用于檢測發送端是否處于應用層限速狀態的核心組件。它通過維護一個基于時間間隔的預算系統,監控實際發送數據量與網絡容量之間的關系。當發送速率持續低于網絡容量的設定比例(如65%)時,判定進入ALR狀態;當發送速率恢復時退出該狀態。該檢測為擁塞控制算法提供關鍵狀態信號,幫助區分網絡擁塞和應用層限速,從而優化帶寬估計和速率調整策略。
一、核心功能
AlrDetector
(Application Limited Region Detector)用于檢測是否處于應用受限區域(Application Limited Region, ALR)。當應用程序發送數據的速度低于網絡容量時,就處于 ALR 狀態。該檢測器通過監控發送字節數和時間間隔,結合當前估計的帶寬,判斷是否進入或退出 ALR 狀態。
二、核心算法原理
基于預算的比例判斷:
使用?
IntervalBudget
?來模擬一個“發送預算”。預算隨時間的推移而增加(按目標帶寬比例),隨數據發送而減少。
當預算比例超過?
start_budget_level_ratio
?時,判定進入 ALR;當預算比例低于?
stop_budget_level_ratio
?時,判定退出 ALR。
帶寬使用率控制:
使用?
bandwidth_usage_ratio
(默認 0.65)來設定目標發送速率(即估計帶寬的 65%),避免過于激進地判斷 ALR。
三、關鍵數據結構
1.?AlrDetectorConfig
struct AlrDetectorConfig {double bandwidth_usage_ratio = 0.65; // 帶寬使用比例double start_budget_level_ratio = 0.80; // 開始ALR的預算比例閾值double stop_budget_level_ratio = 0.50; // 結束ALR的預算比例閾值std::unique_ptr<StructParametersParser> Parser(); };
2.?AlrDetector
?類成員
class AlrDetector {private:const AlrDetectorConfig conf_; // 配置參數absl::optional<int64_t> last_send_time_ms_; // 上次發送時間IntervalBudget alr_budget_; // 間隔預算器absl::optional<int64_t> alr_started_time_ms_; // ALR開始時間(若存在則表示處于ALR)RtcEventLog* event_log_; // 事件日志(可選) };
四、核心方法詳解
1. 構造函數
AlrDetector::AlrDetector(AlrDetectorConfig config, RtcEventLog* event_log): conf_(config), alr_budget_(0, true), event_log_(event_log) {}
初始化配置和?
IntervalBudget
,初始預算為0,啟用“可變目標模式”。
2.?OnBytesSent
void AlrDetector::OnBytesSent(size_t bytes_sent, int64_t send_time_ms) {if (!last_send_time_ms_.has_value()) {last_send_time_ms_ = send_time_ms;return;}int64_t delta_time_ms = send_time_ms - *last_send_time_ms_;last_send_time_ms_ = send_time_ms;alr_budget_.UseBudget(bytes_sent); // 使用預算(發送數據)alr_budget_.IncreaseBudget(delta_time_ms); // 增加預算(隨時間)bool state_changed = false;if (alr_budget_.budget_ratio() > conf_.start_budget_level_ratio &&!alr_started_time_ms_) {alr_started_time_ms_.emplace(rtc::TimeMillis()); // 進入ALRstate_changed = true;} else if (alr_budget_.budget_ratio() < conf_.stop_budget_level_ratio &&alr_started_time_ms_) {state_changed = true;alr_started_time_ms_.reset(); // 退出ALR}if (event_log_ && state_changed) {event_log_->Log(std::make_unique<RtcEventAlrState>(alr_started_time_ms_.has_value()));} }
每次發送數據時調用,更新預算并判斷ALR狀態變化。
記錄狀態變化事件(如啟用了事件日志)。
3.?SetEstimatedBitrate
void AlrDetector::SetEstimatedBitrate(int bitrate_bps) {RTC_DCHECK(bitrate_bps);int target_rate_kbps = static_cast<double>(bitrate_bps) * conf_.bandwidth_usage_ratio / 1000;alr_budget_.set_target_rate_kbps(target_rate_kbps); }
根據當前估計帶寬設置?
IntervalBudget
?的目標速率(按比例縮放)。
4.?GetApplicationLimitedRegionStartTime
absl::optional<int64_t> AlrDetector::GetApplicationLimitedRegionStartTime() const {return alr_started_time_ms_; }
返回當前ALR狀態的開始時間(若存在則表示正處于ALR)。
五、設計亮點
靈活配置:支持通過字段試驗(Field Trials)動態調整參數,適應不同網絡環境和應用場景。
事件日志:可記錄ALR狀態變化事件,便于后續分析和調試。
預算比例判斷:使用相對比例而非絕對值,更具適應性和魯棒性。
輕量級設計:僅依賴時間戳和字節數,無需復雜計算,適合實時系統。
六、典型工作流程
初始化:構造?
AlrDetector
,設置初始帶寬(通常為0,后續通過?SetEstimatedBitrate
?設置)。發送數據:每次發送數據包后調用?
OnBytesSent
,更新預算并判斷ALR狀態。帶寬更新:當網絡帶寬估計更新時,調用?
SetEstimatedBitrate
?調整目標速率。狀態查詢:通過?
GetApplicationLimitedRegionStartTime
?獲取當前是否處于ALR及其開始時間。事件記錄:若狀態變化且啟用了事件日志,則記錄?
RtcEventAlrState
?事件。
七、整體流程圖
處理發送數據 (OnBytesSent) 流程
檢查預算比例并更新ALR狀態流程