Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 AI-free content. This post is 100% written by a human, as is everything on my blog. Enjoy!

27.11.2024

Keep-Alive та як воно працює

В мене тут намалювалася помилка, здається, через Keep-Alive. А саме, клієнт внутрішнього HTTP API в Go час від часу віддає помилку io.EOF. Не найкраща помилка, якщо чесно, бо ніяк не пояснює, що відбулося. А відбулося ніби те, що сервер час від часу закриває підключення.

Keep-Alive (“залиш живим”) можна побачити у двох контекстах: TCP-сокетах та HTTP. Давайте спочатку про HTTP. Тут є заголовок Keep-Alive. Такий заголовок з боку клієнта каже “я б хотів використати це підключення більш ніж для одного запиту”. А з боку сервера, “так, я на це згодний”. На цьому участь HTTP в Keep-Alive закінчується. Ба більше, в HTTP/2 та далі цей заголовок взагалі заборонений! Бо в HTTP/2 сталість підключення є нормою. А в HTTP/3 втрачає сенс, оскільки він побудований на UDP, де передача даних відбувається взагалі без підключень.

Але що треба запамʼятати, то Keep-Alive на шарі HTTP тільки інформує, а справжня реалізація Keep-Alive відбувається на шарі TCP. Та для клієнтів API, гадаю, це все ще актуально, бо HTTP/3 з UDP не має сенсу. (А ви як думаєте?)

З TCP теж не все очевидно. Бо в підключення в принципі немає “терміну придатності”, воно буде існувати поки не закриєш. Але зайві підключення споживають ресурси сервера, тому сервер майже певно їх закриватиме. А щоб цього не відбулося, клієнт може час від часу надсилати так звані “посилки keepalive” (а насправді просто порожні посилки), щоб нагадати серверу, що підключення ще живе. (Сервер все одно може закрити таке підключення, але шанси на це менше.)

Для того в налаштуваннях підключення (в Go це в net.Dialer) є параметри Keepalive, які й вказують, чи надсилати такі пакети, та як часто. Я знав, що базовий клієнт Go вже підтримує стале підключення, а тепер я ще дізнався, що він також надсилає Keepalive, але надто рідко для цього серверу API. Отак.