nginx

простою мовою, без припущень про ваш досвід

nginx – це програма, яка відповідає, коли хтось просить у вашого сайту сторінку. Вона захопила веб тим, що надзвичайно добре вміє чекати: тримати десятки тисяч відкритих з’єднань на одній звичайній машині там, де старіший спосіб уже задихався. А сьогодні здебільшого робить другу роботу – стоїть біля вхідних дверей вашого сайту й розбирає гостей, перш ніж вони дістануться до того, що виконує справжню роботу.

Коли ви набираєте адресу і з’являється сторінка, хтось на тому кінці вас почув і сторінку подав. Не будівля і не компанія – програма, що працює на якомусь комп’ютері, і вся її робота полягає в тому, щоб почути «надішли мені, будь ласка, оту сторінку» і надіслати. Приблизно на третині сайтів світу ця програма зветься nginx.

Цікаве тут не те, що вона робить, – це робить будь-який вебсервер. Цікаве те, чому саме ця опинилася скрізь. І відповідь виявляється напрочуд гарною думкою про різницю між тим, щоб бути зайнятим, і тим, щоб бути корисним.

Програма, а не машина

Слово «сервер» уживають у двох різних значеннях, і якщо їх розплутати, половина туману розвіюється.

Одне значення – це машина: звичайний комп’ютер, який стоїть десь у будівлі завжди ввімкненим і чекає. Друге – це програма, що на тій машині працює, і саме вона читає ваш запит і відповідає на нього. Машина – це крамниця; програма – це крамар.

Розмова між вами і крамарем простіша, ніж можна подумати. Ваш браузер відкриває з’єднання і надсилає кілька рядків звичайного тексту, приблизно таких: «надішли мені сторінку /about – і, до речі, я Firefox, і я вмію читати стиснені сторінки». Програма на тому кінці це читає, знаходить сторінку й відсилає її назад разом із кількома власними рядками. В одному з тих рядків крамар чемно називає своє ім’я.

Це ім’я ви можете побачити на власні очі просто зараз. Команда нижче просить у сайту самі лише заголовки – наліпку на посилці, а не саму посилку, – і друкує їх. Нічого не завантажується, нічого не змінюється:

curl -sI https://wordpress.org

Серед рядків, які повернуться, буде один: server: nginx. Це крамар представляється. Підставте замість адреси https://www.gnu.org – і він скаже Apache. (curl уже вбудований і в macOS, і в Windows, і в Linux, тож це майже напевно спрацює. А деякі сайти своє ім’я лишають при собі – так теж можна, і це розважлива обачність.)

Ці два імені, nginx і Apache, і є більша частина історії вебу за останні тридцять років.

Епоха Apache: по офіціанту на кожен столик

Apache з’явився 1995 року, і вже з квітня 1996-го був найпоширенішим вебсервером інтернету – позицію цю він утримував понад двадцять років. Він був надійний, безкоштовний, запускався будь-де, і довгий час «викласти сайт у мережу» означало просто «поставити Apache».

Спосіб, у який він давав раду відвідувачам, був очевидний і чесний: на кожне з’єднання – окремий робітник. Хтось під’єднався – Apache виділяє цілого окремого робітника, з власним процесом і власним шматком пам’яті, і той належить цьому відвідувачеві, доки той не піде. Просто зрозуміти, просто полагодити. Якщо чийсь запит щось ламав, він ламав лише того одного робітника.

Так працював би ресторан, якби ви найняли по офіціанту на кожен столик. Цілком розважливо – доки в ресторані не стане людно.

Бо ось у чому річ зі столиком: більшість часу нікому за ним нічого не треба. Люди читають меню. Жують. Одягають пальто. А приставлений офіціант увесь цей час стоїть поруч, отримує платню, займає місце в залі й не робить нічого.

Зі з’єднаннями те саме, тільки гостріше. Читач на повільному мобільному зв’язку отримує сторінку кілька секунд – ту саму, яку сервер приготував за мілісекунду, – і робітник вистоює кожну з тих секунд. Гірше: браузери навмисне тримають з’єднання відкритим після того, як сторінку вже отримали, на випадок, якщо ви за мить клацнете ще раз, – це заощаджує побудову нового з’єднання з нуля. Порожній столик, на спинках якого досі висять пальта. За моделлю Apache він однаково коштує цілого робітника.

Отже, десять тисяч людей, під’єднаних водночас, – це десять тисяч робітників, кожен зі своїми мегабайтами пам’яті. Це гігабайти машини, витрачені майже цілком на утримання людей, які просто зараз нічого не просять, – плюс усі зусилля, які комп’ютер спалює, перемикаючи увагу між десятьма тисячами.

Цей біль дістав назву 1999 року: проблема C10k. C – від concurrent, «одночасні», а 10k – це десять тисяч.

Чому головне слово тут – «одночасні»

Десять тисяч відвідувачів за годину – то взагалі ніщо: приблизно троє на секунду, з цим упорається й ноутбук. А от десять тисяч з’єднань, відкритих тієї самої миті, – геть інший звір, і саме він усе ламає.

Інженер, який дав цьому назву, Dan Kegel, нічого не вигадував. Він показав на реальну машину, яка це робила ще 1999 року: файловий сервер, що обслуговував десять тисяч клієнтів водночас. Залізо явно тягнуло. А те, як програмне забезпечення навчилося поводитися зі з’єднаннями, – ні.

Саме ця прірва – залізо може, програми не можуть – і була справжнім змістом наступного десятиліття в житті вебсерверів.

Відповідь nginx: чекати – не означає працювати

2002 року системний адміністратор на ім’я Igor Sysoev спостерігав усе це наживо. Він працював у Rambler, одному з великих російських вебпорталів, чиї сервери на Apache просто не могли втримати стільки людей, скільки хотіло бути під’єднаними одночасно. Спершу він пробував латати Apache, писав до нього доповнення, – і зрештою дійшов висновку, що біда не в бракованій можливості. Біда у формі самої речі.

Тож він написав нову. Думка, що лежить у її основі, вміщається в одне речення: перестати наймати по офіціанту на столик.

Натомість – тримати невелику, сталу кількість робітників, зазвичай по одному на ядро процесора, тобто чотири або вісім на звичайній машині. Дати кожному список усіх з’єднань, які він доглядає, – тисяч з’єднань водночас. І хай він раз за разом ставить операційній системі одне-єдине запитання: «з усіх оцих – у яких є щось для мене просто зараз?» Що готове, тим він і займається, швидко, одне за одним. А тоді питає знову.

Оце й усе. У цьому весь фокус: жменька офіціантів, які ніколи не стоять на місці, ходять поміж тисячами столиків і зупиняються лише там, де справді підняли руку.

Виграш тут аж ніяк не тонкий. Власна документація nginx наводить число: десять тисяч відкритих, але бездіяльних з’єднань коштують йому близько 2,5 мегабайта. Не гігабайтів – мегабайтів. Усі ті люди, які чекають, жують і читають меню, стали майже безкоштовними, бо чекати – не означає працювати, і nginx нарешті перестав платити за це так, ніби це робота.

Чому саме 2002-й був моментом, коли це стало можливим

Усе тримається на тому одному повторюваному запитанні – «у кого з них є щось готове?» – а більшу частину життя інтернету саме це запитання й було вузьким місцем.

Старий спосіб (дві інструкції з назвами select і poll) означав щоразу передавати операційній системі цілий свій список з’єднань і щоразу отримувати цілий список назад, щоб самому його перебрати. З десятьма з’єднаннями – дурниця. З десятьма тисячами ви щоразу перечитуєте телефонний довідник із початку, щоб знайти одну людину, яка подзвонила.

А тоді операційні системи навчилися краще. FreeBSD дістала kqueue 2000 року, Linux – epoll 2002-го. З ними програма реєструє свої з’єднання один раз, а далі просто питає «є щось?» і отримує назад лише ту жменьку, що справді готова. Вартість запитання перестає рости разом із кількістю з’єднань, які ви тримаєте.

nginx збудували просто поверх них, щойно вони з’явилися. Ось справжня причина, чому його можна було написати 2002 року, а не 1996-го: ґрунт під ним щойно з’явився.

nginx 0.1.0 вийшов публічно 4 жовтня 2004 року. Спершу він поширився серед великих російських порталів, а потім пішов далі – до всіх, хто вперся в ту саму стіну.

Apache, треба віддати належне, теж засвоїв урок: версія 2.4, що вийшла 2012 року, принесла режим, який працює здебільшого так само. Але звичка вже склалася. У квітні 2019-го, якщо рахувати всі сайти інтернету, nginx обійшов Apache і став найпоширенішим вебсервером світу.

Друге життя: швейцар

Ось поворот у цій історії, і саме він пояснює, чому nginx досі всюди. Більша частина того, що nginx робить сьогодні, – це взагалі не роздавання власних сторінок.

Подумайте, чим зазвичай є справжній сайт. Не текою з готовими сторінками, а програмою. Крамницею, яка перевіряє наявність і ціни. Форумом, який з’ясовує, хто ви такий. Їх пишуть мовами на кшталт PHP, Python, Ruby чи JavaScript, і всі вони мають одну чесну слабкість: вони добре думають і погано дають раду натовпу. Їх зроблено так, щоб братися за кілька справ за раз, зате вдумливо.

Тож ви ставите nginx перед ними.

nginx бере на себе тисячі з’єднань із зовнішнім світом – те, у чому він неперевершений. Прості файли – зображення, стилі, шрифти, над якими не треба думати, – він віддає сам. А коли запит справді потребує програми – «що в мене в кошику?» – він передає всередину лише це одне запитання, коротким миттєвим локальним з’єднанням, і виносить відповідь назовні. Застосунок ніколи не зустрічається з повільним телефоном. Він ніколи не чекає. Він думає, відповідає й переходить до наступного.

Посередника, який стоїть попереду того, хто виконує справжню роботу, і повернутий обличчям до світу замість нього, називають зворотним проксі. Проксі – це будь-хто, хто стоїть замість когось іншого; звичайний різновид стоїть попереду вас і ховає вас від сайтів, які ви відвідуєте. А цей розвернуто навпаки: він стоїть попереду сервера, і світ розмовляє з ним.

А щойно біля дверей стоїть хтось надійний, йому починають доручати справу за справою – бо він же вже там:

  • Розбирати за іменем. Одна машина, багато сайтів. nginx читає, яке ім’я запитав відвідувач, і скеровує його до потрібного.
  • Замочок. Він бере на себе шифрування, щоб нічому позаду не довелося цим перейматися.
  • Стискати. Він стискає сторінки на виході, щоб вони швидше долали шлях.
  • Пам’ятати. Він тримає копії свіжих відповідей, тож те саме запитання доходить до застосунку значно рідше.
  • Ділити порівну. Якщо у вас працює кілька копій застосунку, nginx рівномірно розподіляє між ними відвідувачів. Це називають балансуванням навантаження.
  • Не пускати. Обмеження й блокування, щоб потоп ніколи не докотився до чогось крихкого.

Ось що люди насправді мають на увазі, коли кажуть, що «просиділи вихідні в nginx». Майже ніколи не роздавання файлів. Двері.

Як насправді виглядає той славнозвісний конфіг

Він має славу чогось загадкового. Здебільшого дарма. Це вкладені фігурні дужки, і кожен блок каже: «у такій-от ситуації – роби отаке»:

server {
    server_name  example.com;
    listen       443 ssl;

    location /images/ {
        root /var/www/static;
    }

    location / {
        proxy_pass http://127.0.0.1:3000;
    }
}

Прочитайте вголос – і це майже людська мова. Для сайту на ім’я example.com слухай захищений порт. Усе, що починається з /images/, віддавай файлом з оцієї теки на диску. Усе інше передавай усередину – програмі, яка працює тут-таки, на цій самій машині, у дверях номер 3000.

Останній рядок – це і є вся ідея швейцара, в одній вказівці. Справжній мозок сайту сидить за адресою 127.0.0.1:3000 – а це означає просто «оця сама машина, двері 3000» – і в інтернет не виглядає взагалі. Він розмовляє тільки з nginx.

Сьогодні: двері, які впускають себе самі, і двері, які переїхали

Відтоді змінилися дві речі, і разом вони пояснюють, де веб опинився зараз.

Замочок перестав бути мукою. Більшу частину життя вебу HTTPS – той маленький замочок, обіцянка, що ніхто посередині не прочитає й не підмінить надісланого вам, – означав купити сертифікат, руками його встановити й не забути через рік поновити. Забудете – і сайт ламається публічно й миттєво. А тоді з’явився Let’s Encrypt, безкоштовний і автоматизований, загальнодоступний із квітня 2016 року, – і зробив сертифікати такими, що не коштують нічого й не потребують людини.

Новіший вебсервер на ім’я Caddy – його написав Matt Holt, перший випуск 2015 року – довів цю думку до кінця: ви називаєте йому свій домен, а він сам добуває й поновлює сертифікат, і HTTPS у ньому просто ввімкнений одразу. nginx уміє геть усе те саме; різниця в тому, що в nginx ви це складаєте, а в Caddy це припущення за замовчуванням. Такий нині присмак у безлічі інструментів: та сама спроможність, тільки без складання.

А ще двері виїхали з будівлі. Це більший зсув. Для дедалі більшої частки сайтів жодного власного nginx уже немає ніде, бо вся швейцарська робота – замочок, кешування, стиснення, відсіювання ботів, скерування – тепер відбувається на мережі машин, розкиданих по сотнях міст, задовго до того, як запит наблизиться до вашого сайту. Саме цим і є Cloudflare та подібні служби. Придивіться – і мережа доставки контенту і є зворотний проксі; просто він живе в кількох сотнях місць, а не в одному.

Цю передачу естафети видно в цифрах. 2019 року nginx обійшов Apache. До 2023-го, серед мільйона найзавантаженіших сайтів, Cloudflare обійшла їх обох. А в січні 2026-го одне широко вживане дослідження давало nginx 33,3% сайтів, Cloudflare – 25,8%, Apache – 24,4%, і саме Cloudflare продовжувала зростати. (Різні дослідження рахують по-різному й у деталях не сходяться; щодо напрямку – сходяться.)

Найкрасномовніша деталь: сама Cloudflare роками працювала на nginx. А 2022 року замінила його на власну розробку, бо на понад трильйоні запитів на добу спосіб, у який nginx ділить роботу між своєю жменькою робітників, перестав пасувати задачі. Тобто рівно та сама історія ще на один оберт далі: змінилася форма навантаження – змінилася й форма відповіді.

Спробуйте ту першу команду ще раз, цього разу на сайті, який ви читаєте. Це кінець історії, надрукований одним рядком:

curl -sI https://miron.blog

server: cloudflare. Жодна наша машина не відповідає. Ніякого nginx тут немає взагалі.

Рік усередині того конфігураційного файлу

За цим рядком стоїть історія – та сама, якою цей блог і починається.

Автор витратив близько року на ручне вилизування nginx: налаштування HTTP/2, потім HTTP/3, фільтрація ботів, одержимість кешуванням, – і безліччю дрібних правок довів час завантаження сторінки з чотирьох секунд до двох. А тоді вирішив віддати всю цю роботу Cloudflare – і отримав більшу її частину безкоштовно, першого ж дня.

Легко було б прочитати це як змарнований рік. Це не так, і причина важить більше, ніж саме вилизування. Розуміти, що роблять ті двері – навіщо вони, що саме знімають із ваших рук, скільки коштує їх тримати, – це рівно те, що дає змогу зважити, чим буде передача їх комусь іншому: розумним ходом чи помилкою, якої ви не помітите півроку. Безпечно віддати можна лише ту роботу, яку ви розумієте.

Іноді найкраща оптимізація – це вибрати кращий інструмент. Просто треба знати той інструмент, який ви залишаєте.

Отже, одним подихом

nginx – це програма, яка чує «надішли мені оту сторінку» і надсилає, – і вона захопила веб не тим, що була швидшою в чомусь одному, а тим, що відмовилася витрачати цілого робітника на відвідувача, який просто чекає. Одна ця зміна дала змогу звичайній машині тримати десятки тисяч людей водночас і перетворила nginx на універсального швейцара вебу: того, хто стоїть перед вашим застосунком і вбирає в себе натовп, замочок і трафік, щоб застосункові лишалося тільки думати. Нині цей швейцар дедалі частіше стоїть уже зовсім деінде – у мережі міст або в сервері, який сам собі влаштовує замочок, – але робота, яку він виконує, і досі та, яку визначив nginx.