mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-10 11:19:50 +08:00
tune(tunnel): 调整 tunnel 超时与连接池参数,增加冗余连接下限
- Gateway: 增大 idle timeout 至 2s、ping interval 至 500ms - Proxy: 统一 reconnect/ping/stale 超时为常量,降低 reconnect_max 至 250ms - 自动连接池引入 redundant floor(2),保证低负载时也有冗余连接
This commit is contained in:
@@ -46,8 +46,8 @@ pub(crate) const TUNNEL_NODE_STATUS_PATH: &str = "/api/internal/tunnel/node-stat
|
|||||||
pub(crate) const TUNNEL_RELAY_PATH_PATTERN: &str = "/api/internal/tunnel/relay/{node_id}";
|
pub(crate) const TUNNEL_RELAY_PATH_PATTERN: &str = "/api/internal/tunnel/relay/{node_id}";
|
||||||
pub(crate) const TUNNEL_ROUTE_FAMILY: &str = "tunnel_manage";
|
pub(crate) const TUNNEL_ROUTE_FAMILY: &str = "tunnel_manage";
|
||||||
|
|
||||||
const DEFAULT_PROXY_IDLE_TIMEOUT_MS: u64 = 900;
|
const DEFAULT_PROXY_IDLE_TIMEOUT_MS: u64 = 2_000;
|
||||||
const DEFAULT_PING_INTERVAL_MS: u64 = 250;
|
const DEFAULT_PING_INTERVAL_MS: u64 = 500;
|
||||||
const DEFAULT_MAX_STREAMS: usize = 2048;
|
const DEFAULT_MAX_STREAMS: usize = 2048;
|
||||||
const DEFAULT_OUTBOUND_QUEUE_CAPACITY: usize = 128;
|
const DEFAULT_OUTBOUND_QUEUE_CAPACITY: usize = 128;
|
||||||
const DEFAULT_ATTACHMENT_TTL_SECS: u64 = 90;
|
const DEFAULT_ATTACHMENT_TTL_SECS: u64 = 90;
|
||||||
|
|||||||
@@ -53,13 +53,16 @@ pub const DEFAULT_REDIRECT_REPLAY_BUDGET_BYTES: usize = 5_242_880;
|
|||||||
pub const DEFAULT_REDIRECT_REPLAY_BUDGET_HUMAN: &str = "5M";
|
pub const DEFAULT_REDIRECT_REPLAY_BUDGET_HUMAN: &str = "5M";
|
||||||
pub const DEFAULT_LOG_RETENTION_DAYS: u64 = 7;
|
pub const DEFAULT_LOG_RETENTION_DAYS: u64 = 7;
|
||||||
pub const DEFAULT_LOG_MAX_FILES: usize = 30;
|
pub const DEFAULT_LOG_MAX_FILES: usize = 30;
|
||||||
pub const DEFAULT_TUNNEL_PING_INTERVAL_MS: u64 = 250;
|
pub const DEFAULT_TUNNEL_RECONNECT_BASE_MS: u64 = 50;
|
||||||
pub const DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS: u64 = 800;
|
pub const DEFAULT_TUNNEL_RECONNECT_MAX_MS: u64 = 250;
|
||||||
pub const DEFAULT_TUNNEL_STALE_TIMEOUT_MS: u64 = 10_000;
|
pub const DEFAULT_TUNNEL_PING_INTERVAL_MS: u64 = 1_000;
|
||||||
|
pub const DEFAULT_TUNNEL_CONNECT_TIMEOUT_MS: u64 = 1_500;
|
||||||
|
pub const DEFAULT_TUNNEL_STALE_TIMEOUT_MS: u64 = 5_000;
|
||||||
pub const DEFAULT_TUNNEL_SCALE_CHECK_INTERVAL_MS: u64 = 1_000;
|
pub const DEFAULT_TUNNEL_SCALE_CHECK_INTERVAL_MS: u64 = 1_000;
|
||||||
pub const DEFAULT_TUNNEL_SCALE_UP_THRESHOLD_PERCENT: u32 = 70;
|
pub const DEFAULT_TUNNEL_SCALE_UP_THRESHOLD_PERCENT: u32 = 70;
|
||||||
pub const DEFAULT_TUNNEL_SCALE_DOWN_THRESHOLD_PERCENT: u32 = 35;
|
pub const DEFAULT_TUNNEL_SCALE_DOWN_THRESHOLD_PERCENT: u32 = 35;
|
||||||
pub const DEFAULT_TUNNEL_SCALE_DOWN_GRACE_SECS: u64 = 15;
|
pub const DEFAULT_TUNNEL_SCALE_DOWN_GRACE_SECS: u64 = 15;
|
||||||
|
const AUTO_TUNNEL_CONNECTIONS_REDUNDANT_FLOOR: u64 = 2;
|
||||||
const AUTO_TUNNEL_CONNECTIONS_BASE_CAP: u64 = 4;
|
const AUTO_TUNNEL_CONNECTIONS_BASE_CAP: u64 = 4;
|
||||||
const AUTO_TUNNEL_CONNECTIONS_MAX_CAP: u64 = 8;
|
const AUTO_TUNNEL_CONNECTIONS_MAX_CAP: u64 = 8;
|
||||||
|
|
||||||
@@ -508,7 +511,7 @@ pub struct Config {
|
|||||||
#[arg(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
env = "AETHER_PROXY_TUNNEL_RECONNECT_BASE_MS",
|
env = "AETHER_PROXY_TUNNEL_RECONNECT_BASE_MS",
|
||||||
default_value_t = 50
|
default_value_t = DEFAULT_TUNNEL_RECONNECT_BASE_MS
|
||||||
)]
|
)]
|
||||||
pub tunnel_reconnect_base_ms: u64,
|
pub tunnel_reconnect_base_ms: u64,
|
||||||
|
|
||||||
@@ -516,7 +519,7 @@ pub struct Config {
|
|||||||
#[arg(
|
#[arg(
|
||||||
long,
|
long,
|
||||||
env = "AETHER_PROXY_TUNNEL_RECONNECT_MAX_MS",
|
env = "AETHER_PROXY_TUNNEL_RECONNECT_MAX_MS",
|
||||||
default_value_t = 30000
|
default_value_t = DEFAULT_TUNNEL_RECONNECT_MAX_MS
|
||||||
)]
|
)]
|
||||||
pub tunnel_reconnect_max_ms: u64,
|
pub tunnel_reconnect_max_ms: u64,
|
||||||
|
|
||||||
@@ -557,7 +560,7 @@ pub struct Config {
|
|||||||
pub tunnel_stale_timeout_ms: u64,
|
pub tunnel_stale_timeout_ms: u64,
|
||||||
|
|
||||||
/// Minimum number of parallel WebSocket tunnel connections per server.
|
/// Minimum number of parallel WebSocket tunnel connections per server.
|
||||||
/// If omitted, a device-aware value is auto-detected at startup.
|
/// If omitted, a device-aware redundant value is auto-detected at startup.
|
||||||
#[arg(long, env = "AETHER_PROXY_TUNNEL_CONNECTIONS")]
|
#[arg(long, env = "AETHER_PROXY_TUNNEL_CONNECTIONS")]
|
||||||
pub tunnel_connections: Option<u32>,
|
pub tunnel_connections: Option<u32>,
|
||||||
|
|
||||||
@@ -730,9 +733,10 @@ impl Config {
|
|||||||
let per_tunnel_capacity = u64::from(self.tunnel_max_streams.unwrap_or(128).max(1));
|
let per_tunnel_capacity = u64::from(self.tunnel_max_streams.unwrap_or(128).max(1));
|
||||||
let estimated = hw_info.estimated_max_concurrency.max(per_tunnel_capacity);
|
let estimated = hw_info.estimated_max_concurrency.max(per_tunnel_capacity);
|
||||||
let cpu_cap = u64::from(hw_info.cpu_cores).clamp(1, AUTO_TUNNEL_CONNECTIONS_MAX_CAP);
|
let cpu_cap = u64::from(hw_info.cpu_cores).clamp(1, AUTO_TUNNEL_CONNECTIONS_MAX_CAP);
|
||||||
|
let auto_initial_floor = AUTO_TUNNEL_CONNECTIONS_REDUNDANT_FLOOR.min(cpu_cap);
|
||||||
|
|
||||||
let auto_initial = div_ceil_u64(estimated, per_tunnel_capacity.saturating_mul(8))
|
let auto_initial = div_ceil_u64(estimated, per_tunnel_capacity.saturating_mul(8))
|
||||||
.clamp(1, AUTO_TUNNEL_CONNECTIONS_BASE_CAP)
|
.clamp(auto_initial_floor, AUTO_TUNNEL_CONNECTIONS_BASE_CAP)
|
||||||
.min(cpu_cap);
|
.min(cpu_cap);
|
||||||
let auto_max = div_ceil_u64(estimated, per_tunnel_capacity.saturating_mul(4))
|
let auto_max = div_ceil_u64(estimated, per_tunnel_capacity.saturating_mul(4))
|
||||||
.clamp(auto_initial, AUTO_TUNNEL_CONNECTIONS_MAX_CAP)
|
.clamp(auto_initial, AUTO_TUNNEL_CONNECTIONS_MAX_CAP)
|
||||||
@@ -1287,6 +1291,14 @@ mod tests {
|
|||||||
.expect("stale timeout should resolve"),
|
.expect("stale timeout should resolve"),
|
||||||
Duration::from_millis(DEFAULT_TUNNEL_STALE_TIMEOUT_MS)
|
Duration::from_millis(DEFAULT_TUNNEL_STALE_TIMEOUT_MS)
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.tunnel_reconnect_base_ms,
|
||||||
|
DEFAULT_TUNNEL_RECONNECT_BASE_MS
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
config.tunnel_reconnect_max_ms,
|
||||||
|
DEFAULT_TUNNEL_RECONNECT_MAX_MS
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -1354,6 +1366,34 @@ mod tests {
|
|||||||
assert_eq!(sizing.max_connections, 6);
|
assert_eq!(sizing.max_connections, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn auto_tunnel_pool_sizing_prefers_redundant_floor_when_hardware_allows() {
|
||||||
|
let config = Config::parse_from([
|
||||||
|
"aether-proxy",
|
||||||
|
"--aether-url",
|
||||||
|
"https://example.com",
|
||||||
|
"--management-token",
|
||||||
|
"ae_test",
|
||||||
|
"--node-name",
|
||||||
|
"proxy-test",
|
||||||
|
"--tunnel-max-streams",
|
||||||
|
"1024",
|
||||||
|
]);
|
||||||
|
let hw = HardwareInfo {
|
||||||
|
cpu_cores: 4,
|
||||||
|
total_memory_mb: 4_096,
|
||||||
|
os_info: "test".to_string(),
|
||||||
|
fd_limit: 1_048_576,
|
||||||
|
estimated_max_concurrency: 64,
|
||||||
|
};
|
||||||
|
|
||||||
|
let sizing = config
|
||||||
|
.resolve_tunnel_pool_sizing(&hw)
|
||||||
|
.expect("sizing should resolve");
|
||||||
|
assert_eq!(sizing.initial_connections, 2);
|
||||||
|
assert_eq!(sizing.max_connections, 2);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn explicit_tunnel_connections_keep_fixed_pool_without_max_override() {
|
fn explicit_tunnel_connections_keep_fixed_pool_without_max_override() {
|
||||||
let config = Config::parse_from([
|
let config = Config::parse_from([
|
||||||
|
|||||||
Reference in New Issue
Block a user