51 lines
1.8 KiB
C++
51 lines
1.8 KiB
C++
// rtt_estimator.h
|
||
// 平滑 RTT 估算器(参考 RFC 6298),与 Windows 端 KernelManager 算法一致。
|
||
// Linux/macOS 客户端共享:每次心跳 ACK 用 update_from_sample(rtt_ms) 喂一次样本。
|
||
//
|
||
// 设计要点:
|
||
// - srtt / rttvar / rto 单位为秒;输入是毫秒
|
||
// - 异常值(≤0 或 >30s)丢弃,防止统计被一个瞬时坏样本污染
|
||
// - alpha=1/8, beta=1/4 与 RFC 6298 默认值一致
|
||
//
|
||
// C++17 inline 全局变量:g_rttEstimator / g_heartbeatInterval 由本头文件直接定义,
|
||
// 多翻译单元 include 不会触发 ODR 冲突。
|
||
#pragma once
|
||
|
||
#include <cmath>
|
||
|
||
struct RttEstimator {
|
||
double srtt = 0.0; // 平滑 RTT (秒)
|
||
double rttvar = 0.0; // RTT 波动 (秒)
|
||
double rto = 0.0; // 超时时间 (秒)
|
||
bool initialized = false;
|
||
|
||
void update_from_sample(double rtt_ms)
|
||
{
|
||
// 过滤异常值:RTT应在合理范围内 (0, 30000] 毫秒
|
||
if (rtt_ms <= 0 || rtt_ms > 30000)
|
||
return;
|
||
|
||
const double alpha = 1.0 / 8;
|
||
const double beta = 1.0 / 4;
|
||
double rtt = rtt_ms / 1000.0;
|
||
|
||
if (!initialized) {
|
||
srtt = rtt;
|
||
rttvar = rtt / 2.0;
|
||
rto = srtt + 4.0 * rttvar;
|
||
initialized = true;
|
||
} else {
|
||
rttvar = (1.0 - beta) * rttvar + beta * std::fabs(srtt - rtt);
|
||
srtt = (1.0 - alpha) * srtt + alpha * rtt;
|
||
rto = srtt + 4.0 * rttvar;
|
||
}
|
||
|
||
// 限制最小 RTO(RFC 6298 推荐 1 秒)
|
||
if (rto < 1.0) rto = 1.0;
|
||
}
|
||
};
|
||
|
||
// 进程级全局:所有翻译单元共享同一份估算器与心跳间隔
|
||
inline RttEstimator g_rttEstimator;
|
||
inline int g_heartbeatInterval = 5; // 默认心跳间隔(秒),可被服务端 CMD_MASTERSETTING 更新
|