iOS 네트워크 속도 감지 솔루션

배경

네트워크 상황에 따른 보다 세부적인 사업 전략을 수립하기 위해서는 가능한 한 적은 비용으로 현재의 네트워크 상황을 평가할 수 있는 일련의 네트워크 속도 탐지 솔루션이 필요하므로 탐지 데이터가 과거 네트워크 요청에서 나왔으면 합니다. , 정확하게 평가하기 위해 네트워크 요청에 리소스를 소비하는 대신.

지수 계산

일반적으로 RTT는 네트워크 속도의 주요 평가 지표로 사용됩니다.이력 요청 RTT 값을 일괄적으로 얻은 후 보다 정확한 목표 RTT 값을 계산하는 방법은 무엇입니까?

RTT 값에 영향을 미치는 변수는 주로 다음과 같습니다.

  1. 네트워크 상태는 시간이 지남에 따라 변경됩니다.
  2. 요청은 서로 다른 서버에서 오고 성능이 다르며 롱테일 데이터의 영향을 쉽게 받습니다.

먼저 Chrome의 nqe 소스 코드를 참조하세요: chromium.googlesource.com/chromium/sr…

무게 설계

관련 소스 코드를 참조한 후 기록 요청의 RTT 값이 최종 계산을 위한 가중치와 연결되고 RTT 가중치를 계산하기 위한 핵심 논리가 발견됩니다.

void ObservationBuffer::ComputeWeightedObservations(
    const base::TimeTicks& begin_timestamp,
    int32_t current_signal_strength,
    std::vector<WeightedObservation>* weighted_observations,
    double* total_weight) const {
    base::TimeDelta time_since_sample_taken = now - observation.timestamp();
    double time_weight =
        pow(weight_multiplier_per_second_, time_since_sample_taken.InSeconds());

    double signal_strength_weight = 1.0;
    if (current_signal_strength >= 0 && observation.signal_strength() >= 0) {
      int32_t signal_strength_weight_diff =
          std::abs(current_signal_strength - observation.signal_strength());
      signal_strength_weight =
          pow(weight_multiplier_per_signal_level_, signal_strength_weight_diff);
    }

    double weight = time_weight * signal_strength_weight;
复制代码

무게는 주로 두 가지 측면에서 비롯된다는 것을 알 수 있습니다.

  1. 신호 가중치: 현재 신호 강도와의 차이가 클수록 RTT 값의 기준 값이 낮아집니다.
  2. 시간 가중치: 현재 시간에서 RTT 값이 길수록 기준 값이 낮습니다.

이 프로세스는 시간 경과에 따라 변경되는 네트워크 상태의 영향을 줄일 수 있습니다.

반감기 디자인

두 가중치를 계산할 때 계산 pow(衰减因子, diff)이 사용되므로 이 "감쇠 계수"를 얻는 방법은 시간 감쇠 계수를 예로 들 수 있습니다.

double GetWeightMultiplierPerSecond(
    const std::map<std::string, std::string>& params) {
  // Default value of the half life (in seconds) for computing time weighted
  // percentiles. Every half life, the weight of all observations reduces by
  // half. Lowering the half life would reduce the weight of older values
  // faster.
  int half_life_seconds = 60;
  int32_t variations_value = 0;
  auto it = params.find("HalfLifeSeconds");
  if (it != params.end() && base::StringToInt(it->second, &variations_value) &&
      variations_value >= 1) {
    half_life_seconds = variations_value;
  }
  DCHECK_GT(half_life_seconds, 0);
  return pow(0.5, 1.0 / half_life_seconds);
}
复制代码

사실 반감기를 설계하고 "초당 감쇠 계수"를 계산하는 것인데, 예를 들어 RTT 값과 현재 시간의 차이가 60초라면 가중치는 초기 값의 절반으로 감소합니다. 좀 더 생각해보면 다음과 같은 두 가지 결론을 내릴 수 있습니다.

  1. 동일한 과거 RTT 값 수준에서 반감기가 짧을수록 현재 네트워크 상태에 더 가깝기 때문에 신뢰도가 높아집니다.
  2. 동일한 반감기에서 과거 RTT 값의 크기가 클수록 더 많은 서버 성능 차이가 완화되기 때문에 신뢰도가 높아집니다.

따라서 한 단계 더 나아가 과거 RTT 값의 크기에 따라 반감기를 조정하여 둘 사이의 균형을 찾을 수 있습니다.

가중 알고리즘 설계

가중치를 구한 후 가중치를 계산하는 방법은 가중 평균 알고리즘을 생각할 가능성이 높지만 롱테일 데이터의 영향도 받게 됩니다.

예를 들어 어떤 RTT 값이 정상 값보다 수십 배 크고 가중치가 조금 더 높다면 가중 평균값도 커지게 되는데 더 좋은 방법은 가중 중앙값을 구하는 것인데, 이 역시 가중 평균값을 구하는 것이 더 좋은 방법이다. nqe 의사 코드는 다음과 같습니다.

//按 RTT 值从小到大排序
samples.sort()
//目标权重是总权重的一半
desiredWeight = 0.5 * totalWeight
//找到目标权重对应的 RTT 值
cumulativeWeight = 0
for sample in samples
  cumulativeWeight += sample.weight
  If (cumulativeWeight >= desiredWeight) 
    return sample.RTT
复制代码

추가 최적화

과거 네트워크 요청 샘플 데이터를 통해 가중 중앙값을 계산하고, 계산된 RTT 값 범위에 따라 Bad / Good 등 업무용 네트워크 속도 상태를 판단합니다. 최적화할 수 있습니다.

네트워크 액세스가 없는 시나리오

사용자가 일정 기간 동안 네트워크에 액세스하지 않고 샘플 데이터가 부족한 경우 RTT 값을 실시간으로 계산하라는 요청을 시작하는 능동적 감지 전략이 도입됩니다.

네트워크 상태의 급격한 악화

특정 순간에 네트워크가 갑자기 나빠지고 대기열에 많은 수의 요청이 누적되면 우리의 RTT 값은 네트워크 요청의 랜딩에 따라 달라지므로 이때 계산된 목표 RTT 값에는 지연이 있습니다.

이 문제를 해결하기 위해 "착륙하지 않은 요청"의 대기열을 기록할 수 있습니다. 매번 RTT 값을 계산하기 전에 "특정 임계값을 초과"하는 미착륙 요청이 "일정 비율을 초과"하는 것으로 미리 판단합니다. 취약한 네트워크 상태를 고려하여 네트워크 열화를 빠르게 감지하는 효과를 얻을 수 있습니다.

Guess you like

Origin juejin.im/post/7171020344117952542