# Benchmark - Инструменты и методология > Актуально: v0.3+ --- ## Инструменты | Инструмент | Что измеряет | Когда | |---|---|---| | **tcpkali** | TCP conn/sec, throughput | Основной benchmark | | **SoulFire** | Реальные MC боты (Fabric код) | Anti-bot тест | | **BotMark** | Быстрые MC handshake | Handshake throughput | | **hping3** | SYN flood | XDP тест | | **pktgen** | Max pps (kernel module) | XDP верхний предел | | **iperf3** | Bandwidth | Throughput VDS | | **cargo bench** | Rust unit benchmarks | Парсер, HMAC, rate limit | --- ## Методология ### Правила честного бенчмарка ``` 1. Изолированная среда - никаких фоновых процессов 2. Прогрев (warm-up) - первые 10 сек не считаются 3. Несколько прогонов - минимум 3, берём медиану 4. Одна переменная - меняем одно за раз 5. Фиксируем конфигурацию - версия ядра, CPU, RAM, NIC 6. Не на той же машине - источник нагрузки на отдельном VDS ``` ### Конфигурация тестового стенда ``` Тестируемый (edge нода): VDS: Hetzner CX31 (4 vCPU, 8GB, 1Gbps, KVM) OS: Ubuntu 22.04 LTS Kernel: 5.15.x NIC: virtio (XDP generic mode) Источник нагрузки (отдельный VDS в той же сети): VDS: Hetzner CX21 (2 vCPU, 4GB, 1Gbps) Измеряем: CPU edge ноды: htop / top Память: /proc/meminfo Connections: ss -s Latency: tcpkali --latency-percentiles ``` --- ## tcpkali - основной инструмент ```bash # Установка cargo install tcpkali # или apt install tcpkali # Тест 1: новых соединений/сек tcpkali \ --connections 1000 \ --connect-rate 5000 \ # 5000 новых conn/сек --duration 30s \ --message-rate 0 \ # без данных - только коннект TARGET_IP:25565 # Тест 2: активные соединения + трафик tcpkali \ --connections 50000 \ # 50k одновременно --connect-rate 1000 \ --duration 60s \ --message-rate 1 \ # 1 msg/сек от каждого --message "$(cat mc_handshake.bin)" \ TARGET_IP:25565 # Тест 3: latency percentiles tcpkali \ --connections 1000 \ --connect-rate 500 \ --duration 30s \ --latency-connect \ # измеряем latency до connect --latency-percentiles 50,95,99,99.9 \ TARGET_IP:25565 ``` --- ## SoulFire - реальные MC боты ```bash # SoulFire запускает настоящий Fabric MC клиент # Боты ведут себя как реальные игроки на уровне протокола # Скачать: github.com/AlexProgrammerDE/SoulFire java -jar SoulFire.jar \ --target play.server.com:25565 \ --amount 500 \ # 500 ботов --join-delay 100 \ # 100мс между подключениями --protocol-version 765 # MC 1.20.4 ``` --- ## hping3 - SYN flood ```bash # ТОЛЬКО для тестирования своих серверов! # Запускать с отдельного VDS # SYN flood hping3 -S --flood -p 25565 TARGET_IP # С рандомным src IP (проверяем uRPF) hping3 -S --flood -p 25565 --rand-source TARGET_IP # Смотрим на XDP счётчики watch -n 1 'cat /sys/kernel/debug/tracing/trace_pipe' # или через наш /metrics endpoint curl http://TARGET_IP:9090/metrics | grep xdp_drops ``` --- ## Rust unit benchmarks ```toml # Cargo.toml [dev-dependencies] criterion = { version = "0.5", features = ["html_reports"] } [[bench]] name = "core_benchmarks" harness = false ``` ```rust // benches/core_benchmarks.rs use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId}; fn bench_handshake_parse(c: &mut Criterion) { let mut group = c.benchmark_group("handshake_parse"); // Разные варианты hostname let cases = vec![ ("vanilla", build_handshake("play.server.com", 765, 2)), ("forge", build_handshake("play.server.com\0FML2\0", 765, 2)), ("hmac", build_handshake("play.server.com\0shield\0abcdef", 765, 2)), ]; for (name, packet) in &cases { group.bench_with_input(BenchmarkId::new("parse", name), packet, |b, p| { b.iter(|| McHandshake::parse(black_box(p))) }); } group.finish(); } fn bench_hmac(c: &mut Criterion) { let secret = b"test_secret_32_bytes_long_here!!"; let hostname = "play.server.com"; let signed = sign_hostname(hostname, secret); let mut group = c.benchmark_group("hmac"); group.bench_function("sign", |b| { b.iter(|| sign_hostname(black_box(hostname), secret)) }); group.bench_function("verify", |b| { b.iter(|| verify_hostname(black_box(&signed), secret)) }); group.finish(); } fn bench_rate_limiter(c: &mut Criterion) { let rt = tokio::runtime::Runtime::new().unwrap(); let limiter = RateLimiter::new(100, 10.0); let ips: Vec = (0..1000u32) .map(|i| IpAddr::V4(Ipv4Addr::from(i))) .collect(); c.bench_function("rate_limit_check", |b| { b.to_async(&rt).iter(|| async { let ip = ips[fastrand::usize(..ips.len())]; limiter.check(black_box(ip)).await }) }); } criterion_group!(benches, bench_handshake_parse, bench_hmac, bench_rate_limiter); criterion_main!(benches); ``` ```bash # Запуск cargo bench # HTML отчёт в target/criterion/ open target/criterion/report/index.html ``` --- > ⚠️ **Важное уточнение:** Цифры 110k conn/s - для **synthetic echo benchmark** (простое прокси без L7 парсинга). > Реальная производительность Rampart (handshake парсинг + HMAC + DashMap + rate limit) на 4 vCPU: > - **~60-70k conn/s** (реалистично для v0.1-v0.3 на epoll) > - **~85-95k conn/s** (с io_uring) > > Для простого TCP proxy без L7 логики - 110k+. > Для точных цифр - прогони `cargo bench` на своём железе. ## Ожидаемые результаты (Hetzner CX31, 4 vCPU) ``` Unit benchmarks: handshake_parse (vanilla): ~160 ns → 6.2M парсингов/сек handshake_parse (forge): ~180 ns → 5.5M парсингов/сек hmac_sign: ~820 ns → 1.2M подписей/сек hmac_verify: ~840 ns → 1.2M верификаций/сек rate_limit_check: ~220 ns → 4.5M проверок/сек Системные (epoll / tokio): Новых соединений/сек: ~80,000 Активных соединений: ~200,000 CPU при 80k conn/s: ~65% Системные (io_uring): Новых соединений/сек: ~110,000 (+37%) Активных соединений: ~260,000 CPU при 110k conn/s: ~48% XDP (generic mode на virtio): Drop rate: ~3-5M pps CPU при 3M pps: ~25% XDP (native, bare metal): Drop rate: ~15-20M pps CPU при 10M pps: ~15% ``` ### Таблица для README ```markdown ## Performance Tested on Hetzner CX31 (4 vCPU, 8GB, KVM), Ubuntu 22.04, kernel 5.15 | Mode | New conn/s | Active conn | CPU | |---|---|---|---| | 1 core, epoll | 20k | 50k | ~100% | | 4 core, epoll | 80k | 200k | ~65% | | 4 core, io_uring | 110k | 260k | ~48% | | XDP drop (generic) | 3-5M pps | - | ~25% | | XDP drop (native) | 15-20M pps | - | ~15% | ``` --- ## Профилирование под нагрузкой ```bash # 1. Запускаем нагрузку tcpkali --connections 50000 --connect-rate 5000 --duration 300s TARGET:25565 & # 2. Пока идёт нагрузка - снимаем профиль CPU perf record -g -p $(pgrep rampart-edge) -- sleep 30 perf report --stdio | head -100 # 3. Flamegraph cargo flamegraph --pid $(pgrep rampart-edge) --output flamegraph.svg open flamegraph.svg # 4. tokio-console - смотрим какие async tasks тормозят tokio-console http://TARGET:6669 ```