Після того, як ви освоїли net/rpc
з попередньої статті (From net/rpc to gRPC in Go Applications), варто почати вивчення HTTP/2, який є основою протоколу gRPC.
Як працює HTTP/2 та як працювати з ним в Golang
Ця стаття більше зосереджена на теоретичній частині, тому попереджаю - тут багато тексту. Ми зосередимось на розумінні HTTP/2, а потім коротко розглянемо його налаштування в Go. Тож беріть каву, влаштовуйтесь зручніше, і давайте розбиратися.
HTTP/2 - це значне оновлення порівняно з HTTP/1.1, і сьогодні він став фактично стандартом всюди. Якщо ви коли-небудь відкривали Chrome DevTools
для перегляду мережевих запитів, ви, ймовірно, вже бачили з'єднання HTTP/2 в дії.
Перевірка з’єднань HTTP/2 за допомогою Chrome
Але чому HTTP/2 такий важливий? Що не так з HTTP/1.1?
HTTP/1.1 впровадив конвеєризацію, яка на папері виглядала як суттєве покращення. Ідея була простою: декілька запитів могли використовувати одне з'єднання і відправлятися, не чекаючи завершення попереднього.
HTTP/1.1 Pipelining: послідовна обробка запитів
Проблема полягала в тому, що запити мали надсилатися по порядку, і відповіді мали повертатися в тому ж порядку. Якщо одна відповідь затримувалася — можливо, серверу потрібен був додатковий час для обробки — все інше в черзі мало чекати.
Це також стається, якщо виникає мережева "заминка", яка затримує лише один запит. Весь конвеєр відповідей призупиняється, доки цей затриманий запит не пройде.
Блокування головного рядка в HTTP/1.1
Ця проблема називається блокуванням Head-of-Line (HoL).
Щоб обійти це обмеження, HTTP/1.1 клієнти (як ваш браузер) почали відкривати кілька TCP-з'єднань з одним і тим же сервером, дозволяючи запитам проходити більш вільно та паралельно.
І хоча це працювало, це не було особливо ефективним:
"То HTTP/2 вирішує цю проблему?"
Так... ну, здебільшого.
HTTP/2 бере одне з'єднання і розділяє його на кілька незалежних потоків. Кожен потік має свій унікальний ідентифікатор, який називається ID потоку, і ці потоки можуть працювати паралельно. Така структура вирішує проблему блокування Head-of-Line (HoL) на рівні додатку (де працює HTTP). Якщо один потік затримується, це не зупиняє рух інших.