TokioMiddleTechnical
Как профилировать и отлаживать проблемы производительности в приложении на Tokio с помощью tokio-console?
tokio-console — TUI-профилировщик: добавьте console-subscriber::init() и запустите tokio-console. Он показывает живые задачи, время idle/busy, ресурсы и помогает находить зависшие или busy-poll задачи.
tokio-console — инструмент профилирования Tokio
tokio-console — интерактивный терминальный профилировщик для Tokio-приложений. Он использует tracing subscriber внутри приложения и отображает живые данные о задачах, ресурсах и состоянии планировщика через gRPC.
Установка и настройка
# Установить консоль
cargo install --locked tokio-console
# Cargo.toml
[dependencies]
tokio = { version = "1", features = ["full", "tracing"] }
console-subscriber = "0.3"
[profile.release]
debug = 1 # минимальные символы для трассировки
// main.rs — вызвать до #[tokio::main] или в начале main
fn main() {
console_subscriber::init(); // инициализирует tracing subscriber
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
rt.block_on(run());
}
async fn run() {
// ваш код
}
Запуск и подключение
# В одном терминале — запустить приложение
TOKIO_CONSOLE_BIND=127.0.0.1:6669 cargo run
# В другом — открыть консоль
tokio-console
# или явно указать адрес
tokio-console http://127.0.0.1:6669
Что показывает консоль
- Tasks: список задач с их состоянием (running / idle / scheduled), временем ожидания, числом опросов.
- Resources: мьютексы, семафоры, каналы — показывает ожидающих и владельца.
- Busy / idle time: соотношение рабочего и ожидающего времени задачи — аномальный idle указывает на зависание.
- Poll count: задача с тысячами коротких опросов — кандидат на busy-polling.
Диагностика проблем
// Именуйте задачи для читаемости в консоли
let handle = tokio::task::Builder::new()
.name("db-fetcher")
.spawn(async move {
// ...
})
.unwrap();
Дополнительные инструменты
TOKIO_WORKER_THREADS=1— уменьшает параллелизм для воспроизведения гонок.tracing-flame— генерирует flamegraph из tracing span'ов.perf+flamegraph(Linux) — CPU профилирование на уровне системных вызовов.heaptrack/cargo-flamegraph— анализ аллокаций.
Переменные окружения
TOKIO_CONSOLE_BIND— адрес gRPC сервера (по умолчанию127.0.0.1:6669).TOKIO_CONSOLE_RETENTION— время хранения завершённых задач (по умолчанию 60s).RUST_LOG=tokio=trace— включает детальный трейсинг событий рантайма.
Подводные камни
- Требуется feature "tracing": без
features = ["tracing"]в зависимости tokio данные задач не собираются. - Overhead в production:
console-subscriberдобавляет заметные накладные расходы; не включайте в production-бинарник без явной необходимости. - Совместимость tracing subscriber: если приложение уже использует
tracing_subscriber::fmt, нужно использоватьconsole_subscriber::ConsoleLayerкак один из слоёв через.with(). - Имена задач только через Builder:
tokio::spawnне принимает имя — толькоtokio::task::Builder::new().name("...").spawn(...). - gRPC порт занят: при запуске нескольких экземпляров приложения укажите разные
TOKIO_CONSOLE_BINDдля каждого. - Нет исторических данных: консоль показывает только текущее состояние и окно retention; для долгосрочного мониторинга используйте Prometheus + Grafana с
tokio-metrics.
Common mistakes
- Отвечать определением без production-сценария.
- Не называть runtime boundary, security boundary или failure mode.
- Игнорировать версию API, observability и тестовую проверку.
What the interviewer is testing
- Объясняет механизм своими словами и без выдуманных API.
- Называет реальные риски, диагностику и критерий корректности.
- Связывает ответ с текущей документацией и миграционными ограничениями.